comparison arogue7/fight.c @ 125:adfa37e67084

Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Fri, 08 May 2015 15:24:40 -0400
parents
children b786053d2f37
comparison
equal deleted inserted replaced
124:d10fc4a065ac 125:adfa37e67084
1 /*
2 * fight.c - All the fighting gets done here
3 *
4 * Advanced Rogue
5 * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
6 * All rights reserved.
7 *
8 * Based on "Rogue: Exploring the Dungeons of Doom"
9 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
10 * All rights reserved.
11 *
12 * See the file LICENSE.TXT for full copyright and licensing information.
13 */
14
15 /*
16 * All the fighting gets done here
17 *
18 */
19
20 #include "curses.h"
21 #include <ctype.h>
22 #include "rogue.h"
23
24 int hit(struct object *weapon, bool see_att, bool see_def, char *er, char *ee, bool back_stab, bool thrown, bool short_msg);
25 #define CONF_DAMAGE -1
26 #define PARAL_DAMAGE -2
27 #define DEST_DAMAGE -3
28 #define DRAIN_DAMAGE -4
29
30 /*
31 * returns true if player has a any chance to hit the monster
32 */
33 player_can_hit(tp, weap)
34 register struct thing *tp;
35 register struct object *weap;
36 {
37 if (off(*tp, CMAGICHIT) && off(*tp, BMAGICHIT) && off(*tp, MAGICHIT))
38 return(TRUE);
39 if (weap && weap->o_type == RELIC)
40 return(TRUE);
41 if (on(*tp, CMAGICHIT) && weap && (weap->o_hplus>2 || weap->o_dplus>2))
42 return(TRUE);
43 if (on(*tp, BMAGICHIT) && weap && (weap->o_hplus>1 || weap->o_dplus>1))
44 return(TRUE);
45 if (on(*tp, MAGICHIT) && weap && (weap->o_hplus>0 || weap->o_dplus>0))
46 return(TRUE);
47 if (player.t_ctype == C_MONK) {
48 if (on(*tp, CMAGICHIT) && pstats.s_lvl > 15)
49 return(TRUE);
50 if (on(*tp, BMAGICHIT) && pstats.s_lvl > 10)
51 return(TRUE);
52 if (on(*tp, MAGICHIT) && pstats.s_lvl > 5)
53 return(TRUE);
54 }
55 return(FALSE);
56 }
57
58 /*
59 * fight:
60 * The player attacks the monster.
61 */
62
63 fight(mp, weap, thrown)
64 register coord *mp;
65 struct object *weap;
66 bool thrown;
67 {
68 register struct thing *tp;
69 register struct linked_list *item;
70 register bool did_hit = TRUE;
71 bool see_def, back_stab = FALSE;
72 register char *mname;
73
74 /*
75 * Find the monster we want to fight
76 */
77 if ((item = find_mons(mp->y, mp->x)) == NULL) {
78 return(FALSE); /* must have killed him already */
79 }
80 tp = THINGPTR(item);
81
82 /*
83 * Since we are fighting, things are not quiet so no healing takes
84 * place. The -1 also tells us that we are in a fight.
85 */
86 player.t_quiet = -1;
87 tp->t_quiet = -1;
88
89 see_def = ((off(*tp, ISINVIS) || on(player, CANSEE)) &&
90 (off(*tp, ISSHADOW) || on(player, CANSEE)) &&
91 (!thrown || cansee(unc(tp->t_pos))));
92
93 mname = see_def ? monster_name(tp) : "something";
94
95 /*
96 * if its in the wall, we can't hit it
97 */
98 if (on(*tp, ISINWALL) && off(player, CANINWALL))
99 return(FALSE);
100
101 if (on(*tp, ISSTONE)) {
102 killed(item, FALSE, FALSE, FALSE);
103 if (see_def)
104 msg("%s shatters into a million pieces!", prname(mname, TRUE));
105 count = 0;
106 return (TRUE);
107 }
108 /*
109 * Let him know it was really a mimic (if it was one).
110 */
111 if (on(*tp, ISDISGUISE) && (tp->t_type != tp->t_disguise) &&
112 off(player, ISBLIND))
113 {
114 if (see_def) {
115 msg("Wait! That's a %s!", mname);
116 turn_off(*tp, ISDISGUISE);
117 }
118 did_hit = thrown;
119 }
120 if (on(*tp, CANSURPRISE) && off(player, ISBLIND) && !ISWEARING(R_ALERT)) {
121 if (see_def) {
122 msg("Wait! There's a %s!", mname);
123 turn_off(*tp, CANSURPRISE);
124 }
125 did_hit = thrown;
126 }
127
128 /*
129 * if he's a thief or assassin and the creature is asleep then he gets
130 * a chance for a backstab
131 */
132 if ((player.t_ctype == C_THIEF || player.t_ctype == C_ASSASIN) &&
133 !thrown &&
134 !on(*tp, NOSTAB) &&
135 !invisible(tp) &&
136 (!on(*tp, ISRUN) || on(*tp, ISHELD) || tp->t_action == A_FREEZE))
137 back_stab = TRUE;
138
139 /*
140 * assassins get an assassination chance, if it fails then its normal
141 * damage
142 */
143 if (back_stab && player.t_ctype == C_ASSASIN) {
144 int chance;
145
146 chance = 50 + (pstats.s_lvl - tp->t_stats.s_lvl) * 5;
147 if (cur_weapon && (cur_weapon->o_flags & ISPOISON))
148 chance += 20;
149 if (roll(1,100) > chance || on(*tp, ISUNIQUE))
150 back_stab = FALSE;
151 }
152
153 runto(tp, &hero);
154
155 /* Let the monster know that the player has missiles! */
156 if (thrown) tp->t_wasshot = TRUE;
157
158 if (did_hit)
159 {
160
161 did_hit = FALSE;
162 if (!can_blink(tp) &&
163 player_can_hit(tp, weap) &&
164 roll_em(&player, tp, weap, thrown, cur_weapon, back_stab))
165 {
166 did_hit = TRUE;
167
168 if (on(*tp, NOMETAL) && weap != NULL &&
169 weap->o_type != RELIC && weap->o_flags & ISMETAL) {
170 msg("Your %s passes right through %s!",
171 weaps[weap->o_which].w_name, prname(mname, FALSE));
172 }
173 else if (weap != NULL && weap->o_type == MISSILE && on(*tp, CARRYBAMULET)) {
174 msg("The magic missile has no affect on %s",
175 prname(mname, FALSE));
176 }
177 else {
178 hit(thrown ? NULL : weap,
179 TRUE, see_def,
180 thrown ? weap_name(weap) : NULL,
181 mname, back_stab, thrown, terse);
182
183 /* See if there are any special effects */
184 if (effect(&player, tp, weap, thrown, TRUE, see_def) != 0)
185 killed(item, FALSE, FALSE, TRUE);
186
187 /*
188 * Merchants just disappear if hit
189 */
190 else if (on(*tp, CANSELL)) {
191 if (see_def)
192 msg("%s disappears with his wares in a flash.",
193 prname(mname, FALSE));
194 killed(item, FALSE, FALSE, FALSE);
195 }
196
197 else if (tp->t_stats.s_hpt <= 0)
198 killed(item, TRUE, TRUE, TRUE);
199
200 else {
201 /* If the victim was charmed, it now gets a saving throw! */
202 if (on(*tp, ISCHARMED) && save(VS_MAGIC, tp, 0)) {
203 msg("The eyes of %s turn clear.", prname(mname, FALSE));
204 turn_off(*tp, ISCHARMED);
205 }
206
207 dsrpt_monster(tp, FALSE, see_def); /* Disrupt a spell? */
208 }
209 }
210 }
211 else {
212 miss(thrown ? NULL : weap,
213 TRUE, see_def,
214 thrown ? weap_name(weap) : NULL,
215 mname, thrown, terse);
216 }
217 }
218 count = 0;
219 return did_hit;
220 }
221
222 /*
223 * attack:
224 * The monster attacks the player
225 */
226
227 attack(mp, weapon, thrown)
228 register struct thing *mp;
229 register struct object *weapon;
230 bool thrown;
231 {
232 register char *mname;
233 register bool see_att, did_hit = FALSE;
234 register struct object *wielded; /* The wielded weapon */
235 struct linked_list *get_wield; /* Linked list header for wielded */
236
237 /*
238 * Since this is an attack, stop running and any healing that was
239 * going on at the time. The -1 also tells us that we're fighting.
240 */
241 running = FALSE;
242 player.t_quiet = -1;
243 mp->t_quiet = -1;
244
245 if (on(*mp, ISDISGUISE) && off(player, ISBLIND))
246 turn_off(*mp, ISDISGUISE);
247
248 see_att = ((off(*mp, ISINVIS) || on(player, CANSEE)) &&
249 (off(*mp, ISSHADOW) || on(player, CANSEE)) &&
250 (!thrown || cansee(unc(mp->t_pos))));
251
252 mname = see_att ? monster_name(mp) : "something";
253
254 /*
255 * Try to find a weapon to wield. Wield_weap will return a
256 * projector if weapon is a projectile (eg. bow for arrow).
257 * If weapon is NULL, it will try to find a suitable weapon.
258 */
259 get_wield = wield_weap(weapon, mp);
260 if (get_wield) wielded = OBJPTR(get_wield);
261 else wielded = NULL;
262
263 /* If we aren't wielding a weapon, wield what we found (could be NULL) */
264 if (weapon == NULL) weapon = wielded;
265
266 if (roll_em(mp, &player, weapon, thrown, wielded, FALSE)) {
267 int death_type; /* From one of the effects of getting hit */
268
269 did_hit = TRUE;
270
271 if (weapon != NULL && weapon->o_type == MISSILE && cur_relic[STONEBONES_AMULET]) {
272 hit(weapon, see_att, TRUE, mname, NULL, FALSE, thrown, terse);
273 msg("Your amulet seems to absorb the magic missile");
274 }
275 else {
276 hit(weapon, see_att, TRUE, mname, NULL, FALSE, thrown, terse);
277 dsrpt_player(); /* see if we disrupted some activity */
278 if (pstats.s_hpt <= 0)
279 death(mp->t_index); /* Bye bye life ... */
280 death_type = effect(mp, &player, weapon, thrown, see_att, TRUE);
281 if (death_type != 0) death(death_type);
282 }
283
284 }
285 else {
286 /* If the thing was trying to surprise, no good */
287 if (on(*mp, CANSURPRISE)) turn_off(*mp, CANSURPRISE);
288
289 /* If it couldn't surprise, let's tell the player. */
290 else miss(weapon, see_att, TRUE, mname, NULL, thrown, terse);
291 }
292 if (fight_flush) md_flushinp();
293 count = 0;
294 status(FALSE);
295 return(did_hit);
296 }
297
298 /*
299 * swing:
300 * returns true if the swing hits
301 */
302
303 swing(class, at_lvl, op_arm, wplus)
304 short class;
305 int at_lvl, op_arm, wplus;
306 {
307 register int res = rnd(20)+1;
308 register int need;
309
310 need = char_class[class].base -
311 char_class[class].factor *
312 ((min(at_lvl, char_class[class].max_lvl) -
313 char_class[class].offset)/char_class[class].range) +
314 (10 - op_arm);
315 if (need > 20 && need <= 25) need = 20;
316
317 return (res+wplus >= need);
318 }
319
320 /*
321 * roll_em:
322 * Roll several attacks
323 */
324
325 roll_em(att_er, def_er, weap, hurl, cur_weapon, back_stab)
326 struct thing *att_er, *def_er;
327 struct object *weap;
328 bool hurl;
329 struct object *cur_weapon;
330 bool back_stab;
331 {
332 register struct stats *att, *def;
333 register char *cp;
334 register int ndice, nsides, nplus, def_arm;
335 bool did_hit = FALSE;
336 int prop_hplus, prop_dplus;
337 int vampiric_damage;
338 char *strchr();
339
340 /* Get statistics */
341 att = &att_er->t_stats;
342 def = &def_er->t_stats;
343
344 prop_hplus = prop_dplus = 0;
345 if (weap == NULL) {
346 static char dmgbuf[20];
347
348 /*
349 * monks damage grows with level
350 */
351 if (att == &pstats && player.t_ctype == C_MONK) {
352 sprintf(dmgbuf, "%dd4", att->s_lvl/3+1);
353 cp = dmgbuf;
354 }
355 else
356 cp = att->s_dmg;
357 }
358 else if (weap->o_type == RELIC) {
359 switch (weap->o_which) {
360 case MUSTY_DAGGER: cp = "1d4+1/1d4+1";
361 when YEENOGHU_FLAIL: cp = "3d6/paralyze/confuse";
362 when HRUGGEK_MSTAR: cp = "3d10";
363 when MING_STAFF: cp = "1d8";
364 when ASMO_ROD: cp = "2d8+1";
365 when ORCUS_WAND: cp = "destroy";
366 when AXE_AKLAD: if (hurl) cp = "1d6/drain";
367 else cp = "3d6/drain";
368 }
369 }
370 else if (hurl) {
371 if ((weap->o_flags&ISMISL) && cur_weapon != NULL &&
372 cur_weapon->o_which == weap->o_launch)
373 {
374 cp = weap->o_hurldmg;
375 prop_hplus = cur_weapon->o_hplus;
376 prop_dplus = cur_weapon->o_dplus;
377 }
378 else
379 cp = (weap->o_flags&ISMISL ? weap->o_damage : weap->o_hurldmg);
380 }
381 else {
382 cp = weap->o_damage;
383 /*
384 * Drain a staff of striking
385 */
386 if(weap->o_type==STICK && weap->o_which==WS_HIT && weap->o_charges==0)
387 {
388 strncpy(weap->o_damage, "1d6", sizeof(weap->o_damage));
389 weap->o_hplus = weap->o_dplus = 0;
390 }
391 }
392 /*
393 * If defender is wearing a cloak of displacement -- no damage
394 * the first time. (unless its a hurled magic missile or the
395 * attacker is very smart and can see thru the illusion)
396 */
397 if ((weap == NULL || weap->o_type != MISSILE) &&
398 def == &pstats &&
399 off(*att_er, MISSEDDISP) &&
400 att->s_intel < 22 &&
401 ((cur_misc[WEAR_CLOAK]!=NULL &&
402 cur_misc[WEAR_CLOAK]->o_which==MM_DISP) ||
403 cur_relic[EMORI_CLOAK])) {
404 turn_on(*att_er, MISSEDDISP);
405 if (cansee(att_er->t_pos.y, att_er->t_pos.x) && !invisible(att_er))
406 msg("%s looks amazed", prname(monster_name(att_er), TRUE));
407 return (FALSE);
408 }
409 if (on(*def_er, CARRYCLOAK) && def != &pstats &&
410 (weap == NULL || weap->o_type != MISSILE) && off(*att_er, MISSEDDISP) &&
411 pstats.s_intel < 22) {
412 turn_on(*att_er, MISSEDDISP);
413 msg("You feel amazed");
414 return(FALSE);
415 }
416 for (;;)
417 {
418 int damage;
419 int hplus = prop_hplus;
420 int dplus = prop_dplus;
421
422 if (weap != NULL && weap->o_type == RELIC) {
423 switch (weap->o_which) {
424 case MUSTY_DAGGER:
425 if (att != &pstats || /* Not player or good stats */
426 (str_compute() > 15 && dex_compute() > 15)) {
427
428 hplus += 6;
429 dplus += 6;
430
431 /* Give an additional strength and dex bonus */
432 if (att == &pstats) {
433 hplus += str_plus(str_compute()) +
434 dext_plus(dex_compute());
435 dplus += dext_plus(dex_compute()) +
436 add_dam(str_compute());
437 }
438 else {
439 hplus += str_plus(att->s_str) +
440 dext_plus(att->s_dext);
441 dplus += dext_plus(att->s_dext) +
442 add_dam(att->s_str);
443 }
444 }
445 else {
446 hplus -= 3;
447 dplus -= 3;
448 }
449 when YEENOGHU_FLAIL:
450 case HRUGGEK_MSTAR:
451 hplus += 3;
452 dplus += 3;
453 when MING_STAFF:
454 hplus += 2;
455 dplus += 2;
456 when AXE_AKLAD:
457 hplus += 5;
458 dplus += 5;
459 }
460 }
461 else if (weap != NULL) {
462 hplus += weap->o_hplus;
463 dplus += weap->o_dplus;
464 }
465
466 /* Is attacker weak? */
467 if (on(*att_er, HASSTINK)) hplus -= 2;
468
469 if (att == &pstats) /* Is the attacker the player? */
470 {
471 hplus += hitweight(); /* adjust for encumberence */
472 dplus += hung_dam(); /* adjust damage for hungry player */
473 dplus += ring_value(R_ADDDAM);
474 }
475 if (back_stab || (weap && att != &pstats && on(*att_er, CANBSTAB)))
476 hplus += 4; /* add in pluses for backstabbing */
477
478 /* Get the damage */
479 while (isspace(*cp)) cp++;
480 if (!isdigit(*cp)) {
481 if (strncmp(cp, "confuse", 7) == 0) ndice = CONF_DAMAGE;
482 else if (strncmp(cp, "paralyze", 8) == 0) ndice = PARAL_DAMAGE;
483 else if (strncmp(cp, "destroy", 7) == 0) ndice = DEST_DAMAGE;
484 else if (strncmp(cp, "drain", 5) == 0) ndice = DRAIN_DAMAGE;
485 else ndice = 0;
486 nsides = 0;
487 nplus = 0;
488 }
489 else {
490 char *oldcp;
491
492 /* Get the number of damage dice */
493 ndice = atoi(cp);
494 if ((cp = strchr(cp, 'd')) == NULL)
495 break;
496
497 /* Skip the 'd' and get the number of sides per die */
498 nsides = atoi(++cp);
499
500 /* Check for an addition -- save old place in case none is found */
501 oldcp = cp;
502 if ((cp = strchr(cp, '+')) != NULL) nplus = atoi(++cp);
503 else {
504 nplus = 0;
505 cp = oldcp;
506 }
507 }
508
509 if (def == &pstats) { /* Monster attacks player */
510 if (on(*att_er, NOMETAL))
511 def_arm = ac_compute(TRUE) - dext_prot(dex_compute());
512 else
513 def_arm = ac_compute(FALSE) - dext_prot(dex_compute());
514 hplus += str_plus(att->s_str)+dext_plus(att->s_dext);
515 }
516 else if (att == &pstats) { /* Player attacks monster */
517 def_arm = def->s_arm - dext_prot(def->s_dext);
518 if (player.t_ctype == C_MONK) /* no strength bonus for monk */
519 if (weap == NULL)
520 hplus += att->s_lvl/5; /* monks hplus varies with level */
521 else
522 hplus += str_plus(str_compute())+dext_plus(dex_compute());
523 }
524 else { /* Monster attacks monster */
525 def_arm = def->s_arm - dext_prot(def->s_dext);
526 hplus += str_plus(att->s_str)+dext_plus(att->s_dext);
527 }
528
529 if (swing(att_er->t_ctype, att->s_lvl, def_arm, hplus)) {
530 register int proll;
531
532 /* Take care of special effects */
533 switch (ndice) {
534 case CONF_DAMAGE:
535 if (def == &pstats) { /* Monster attacks player */
536 if (!save(VS_MAGIC, &player, 0) && off(player, ISCLEAR)) {
537 msg("You feel disoriented.");
538 if (find_slot(unconfuse))
539 lengthen(unconfuse, HUHDURATION);
540 else
541 fuse(unconfuse, 0, HUHDURATION, AFTER);
542 turn_on(player, ISHUH);
543 }
544 else msg("You feel dizzy, but it quickly passes.");
545 }
546 /* Player or monster hits monster */
547 else if (!save(VS_MAGIC, def_er, 0) && off(*def_er, ISCLEAR)) {
548 if (att == &pstats)
549 msg("The artifact warms with pleasure.");
550 turn_on(*def_er, ISHUH);
551 }
552 did_hit = TRUE;
553 when PARAL_DAMAGE:
554 if (def == &pstats) { /* Monster attacks player */
555 if (!save(VS_MAGIC, &player, 0) && off(player, CANINWALL)) {
556 msg("You stiffen up.");
557 player.t_no_move += movement(&player) * FREEZETIME;
558 player.t_action = A_FREEZE;
559 }
560 }
561 else if (!save(VS_MAGIC, def_er, 0)) { /* Player hits monster */
562 if (att == &pstats) msg("The artifact hums happily.");
563 turn_off(*def_er, ISRUN);
564 turn_on(*def_er, ISHELD);
565 }
566 did_hit = TRUE;
567 when DEST_DAMAGE:
568 if (def == &pstats) { /* Monster attacks player */
569 msg("You feel a tug at your life force.");
570 if (!save(VS_MAGIC, &player, -4)) {
571 msg("The wand devours your soul.");
572 def->s_hpt = 0;
573 }
574 }
575 /* Player hits monster */
576 else if (!save(VS_MAGIC, def_er, -4)) {
577 if (att == &pstats)
578 msg("The artifact draws energy.");
579
580 /* Give the attacker half the monster's hits */
581 att->s_hpt += def->s_hpt/2;
582 if (att->s_hpt > att_er->maxstats.s_hpt)
583 att->s_hpt = att_er->maxstats.s_hpt;
584
585 /* Kill the monster */
586 def->s_hpt = 0;
587 }
588 did_hit = TRUE;
589 when DRAIN_DAMAGE:
590 if (def == &pstats) { /* Monster attacks player */
591 if (!save(VS_MAGIC, &player, -4)) {
592 lower_level(att_er->t_index);
593 }
594 }
595 /* Player hits monster */
596 else if (!save(VS_MAGIC, def_er, -4)) {
597 def->s_hpt -= roll(1, 8);
598 def->s_lvl--;
599 if (def->s_lvl <= 0)
600 def->s_hpt = 0; /* he's dead */
601 if (att == &pstats)
602 msg("The artifact cackles with laughter");
603 }
604 did_hit = TRUE;
605 otherwise:
606 /* Heil's ankh always gives maximum damage */
607 if (att == &pstats && cur_relic[HEIL_ANKH])
608 proll = ndice * nsides;
609 else proll = roll(ndice, nsides);
610
611 if (ndice + nsides > 0 && proll < 1)
612 debug("Damage for %dd%d came out %d.",
613 ndice, nsides, proll);
614 damage = dplus + proll + nplus;
615 if (att == &pstats) {
616 /*
617 * Monks do not get strength bonus on damage. Instead,
618 * if they are wielding a weapon, they get at extra
619 * 1/2 point per level of damage.
620 */
621 if(player.t_ctype == C_MONK) {
622 /* Bonus does not apply for hands. */
623 if (weap != NULL) damage += att->s_lvl / 2;
624 }
625 else
626 damage += add_dam(str_compute());
627 }
628 else
629 damage += add_dam(att->s_str);
630
631 /* Check for half damage monsters */
632 if (on(*def_er, HALFDAMAGE)) damage /= 2;
633
634 /* add in multipliers for backstabbing */
635 if (back_stab ||
636 (weap && att != &pstats && on(*att_er, CANBSTAB))) {
637 int mult = 2 + (att->s_lvl-1)/4; /* Normal multiplier */
638
639 if (mult > 5)
640 mult = 5;
641 if (weap->o_type == RELIC && weap->o_which == MUSTY_DAGGER)
642 mult++;
643 damage *= mult;
644 }
645 if (att == &pstats) {
646 if (cur_weapon && (cur_weapon->o_flags & ISPOISON)) {
647 cur_weapon->o_flags &= ~ISPOISON;
648 if (save(VS_POISON, def_er, -2))
649 damage += def->s_hpt/4;
650 else
651 damage += def->s_hpt/2;
652 }
653 if (back_stab && player.t_ctype == C_ASSASIN)
654 damage = def->s_hpt + 1;
655 }
656 /* Check for no-damage and division */
657 if (on(*def_er, BLOWDIVIDE)) {
658 damage = 0;
659 creat_mons(def_er, def_er->t_index, FALSE);
660 if (cansee(unc(def_er->t_pos))) light(&hero);
661 }
662 /* check for immunity to metal -- RELICS are always bad */
663 if (on(*def_er, NOMETAL) && weap != NULL &&
664 weap->o_type != RELIC && weap->o_flags & ISMETAL) {
665 damage = 0;
666 }
667 if (weap != NULL && weap->o_type == MISSILE) {
668 if ((def == &pstats && cur_relic[STONEBONES_AMULET]) ||
669 (att == &pstats && on(*def_er, CARRYBAMULET))) {
670 damage = 0;
671 }
672 }
673
674
675 def->s_hpt -= max(0, damage); /* Do the damage */
676 did_hit = TRUE;
677 vampiric_damage = damage;
678 if (def->s_hpt < 0) /* only want REAL damage inflicted */
679 vampiric_damage += def->s_hpt;
680 if (vampiric_damage < 0)
681 vampiric_damage = 0;
682 if (att == &pstats && ISWEARING(R_VAMPREGEN) && !hurl) {
683 if ((pstats.s_hpt += vampiric_damage/2) > max_stats.s_hpt)
684 pstats.s_hpt = max_stats.s_hpt;
685 }
686 debug ("hplus=%d dmg=%d", hplus, damage);
687 }
688 }
689 if ((cp = strchr(cp, '/')) == NULL)
690 break;
691 cp++;
692 }
693 return did_hit;
694 }
695
696 /*
697 * prname:
698 * The print name of a combatant
699 */
700
701 char *
702 prname(who, upper)
703 register char *who;
704 bool upper;
705 {
706 static char tbuf[LINELEN];
707
708 *tbuf = '\0';
709 if (who == 0)
710 strcpy(tbuf, "you");
711 else if (on(player, ISBLIND) || strcmp(who, "something") == 0)
712 strcpy(tbuf, "something");
713 else
714 {
715 /* If we have a name (starts with a capital), don't use a "the" */
716 if (islower(*who)) strcpy(tbuf, "the ");
717 strcat(tbuf, who);
718 }
719 if (upper)
720 *tbuf = toupper(*tbuf);
721 return tbuf;
722 }
723
724 /*
725 * hit:
726 * Print a message to indicate a succesful hit
727 */
728
729 hit(weapon, see_att, see_def, er, ee, back_stab, thrown, short_msg)
730 register struct object *weapon;
731 bool see_att, see_def;
732 register char *er, *ee;
733 bool back_stab, thrown, short_msg;
734 {
735 register char *s;
736 char att_name[LINELEN], /* Name of attacker */
737 def_name[LINELEN]; /* Name of defender */
738
739 /* If we can't see either the attacker or defender, don't say anything */
740 if (!see_att && !see_def) return;
741
742 /* What do we call the attacker? */
743 strcpy(att_name, see_att ? prname(er, TRUE) : "Something");
744 if (er) { /* A monster is attacking */
745
746 /* If the monster is using a weapon and we can see it, report it */
747 if (weapon != NULL && (see_att || thrown)) {
748 strcat(att_name, "'s ");
749 strcat(att_name, weap_name(weapon));
750 }
751 }
752
753 /* What do we call the defender? */
754 strcpy(def_name, see_def ? prname(ee, FALSE) : "something");
755
756 addmsg(att_name);
757 if (short_msg) {
758 if (back_stab) {
759 if (player.t_ctype == C_ASSASIN)
760 s = (er == 0 ? " assassinate!" : " assassinates!");
761 else
762 s = (er == 0 ? " backstab!" : " backstabs!");
763 }
764 else
765 s = " hit.";
766 }
767 else {
768 if (back_stab) {
769 if (player.t_ctype == C_ASSASIN)
770 s = (er == 0 ? " have assassinated " : " has assassinated ");
771 else
772 s = (er == 0 ? " have backstabbed " : " has backstabbed ");
773 }
774 else {
775 switch (rnd(thrown ? 2 : 3))
776 {
777 case 0: s = " hit ";
778 when 1: s = " injured ";
779 when 2: s = " smacked ";
780 }
781 }
782 }
783 if (short_msg) addmsg(s);
784 else addmsg("%s%s.", s, def_name);
785 endmsg();
786 }
787
788 /*
789 * miss:
790 * Print a message to indicate a poor swing
791 */
792
793 miss(weapon, see_att, see_def, er, ee, thrown, short_msg)
794 register struct object *weapon;
795 bool see_att, see_def;
796 register char *er, *ee;
797 bool thrown, short_msg;
798 {
799 register char *s;
800 char
801 att_name[LINELEN], /* Name of attacker */
802 def_name[LINELEN]; /* Name of defender */
803
804 /* If we can't see either the attacker or defender, don't say anything */
805 if (!see_att && !see_def) return;
806
807 /* What do we call the attacker? */
808 strcpy(att_name, see_att ? prname(er, TRUE) : "Something");
809 if (er) { /* A monster is attacking */
810
811 /* If the monster is using a weapon and we can see it, report it */
812 if (weapon != NULL && (see_att || thrown)) {
813 strcat(att_name, "'s ");
814 strcat(att_name, weap_name(weapon));
815 }
816 }
817
818 /* What do we call the defender? */
819 strcpy(def_name, see_def ? prname(ee, FALSE) : "something");
820
821 addmsg(att_name);
822 switch (short_msg ? 0 : rnd(thrown ? 3 : 2))
823 {
824 case 0: s = (er == 0 ? " miss" : " misses");
825 when 1: s = (er == 0 ? " don't hit" : " doesn't hit");
826 when 2: s = (" whizzes by");
827 }
828 if (short_msg) addmsg("%s.", s);
829 else addmsg("%s %s.", s, def_name);
830 endmsg();
831 }
832
833 /*
834 * dext_plus:
835 * compute to-hit bonus for dexterity
836 */
837
838 dext_plus(dexterity)
839 register int dexterity;
840 {
841 return (dexterity > 10 ? (dexterity-13)/3 : (dexterity-10)/3);
842 }
843
844
845 /*
846 * dext_prot:
847 * compute armor class bonus for dexterity
848 */
849
850 dext_prot(dexterity)
851 register int dexterity;
852 {
853 return ((dexterity-10)/2);
854 }
855 /*
856 * str_plus:
857 * compute bonus/penalties for strength on the "to hit" roll
858 */
859
860 str_plus(str)
861 register short str;
862 {
863 return((str-10)/3);
864 }
865
866 /*
867 * add_dam:
868 * compute additional damage done for exceptionally high or low strength
869 */
870
871 add_dam(str)
872 register short str;
873 {
874 return((str-9)/2);
875 }
876
877 /*
878 * hung_dam:
879 * Calculate damage depending on players hungry state
880 */
881 hung_dam()
882 {
883 reg int howmuch;
884
885 switch(hungry_state) {
886 case F_SATIATED:
887 case F_OKAY:
888 case F_HUNGRY: howmuch = 0;
889 when F_WEAK: howmuch = -1;
890 when F_FAINT: howmuch = -2;
891 }
892 return howmuch;
893 }
894
895 #ifdef THUNK
896 /*
897 * thunk:
898 * A missile hits a monster
899 */
900
901 thunk(weap, tp, mname)
902 register struct object *weap;
903 register struct thing *tp; /* Defender */
904 register char *mname;
905 {
906 char *def_name; /* Name of defender */
907
908 /* What do we call the defender? */
909 if (!cansee(tp->t_pos.y, tp->t_pos.x) || invisible(tp))
910 def_name = "something";
911 else def_name = prname(mname, FALSE);
912
913 if (weap->o_type == WEAPON)
914 msg("The %s hits %s.", weaps[weap->o_which].w_name, def_name);
915 else if (weap->o_type == MISSILE)
916 msg("The %s hits %s.",ws_magic[weap->o_which].mi_name, def_name);
917 else
918 msg("You hit %s.", def_name);
919 }
920
921 /*
922 * mthunk:
923 * A missile from a monster hits the player
924 */
925
926 m_thunk(weap, tp, mname)
927 register struct object *weap;
928 register struct thing *tp;
929 register char *mname;
930 {
931 char *att_name; /* Name of attacker */
932
933 /* What do we call the attacker? */
934 if (!cansee(tp->t_pos.y, tp->t_pos.x) || invisible(tp))
935 att_name = "Something";
936 else att_name = prname(mname, TRUE);
937
938 if (weap->o_type == WEAPON)
939 msg("%s's %s hits you.", att_name, weaps[weap->o_which].w_name);
940 else if (weap->o_type == MISSILE)
941 msg("%s's %s hits you.", att_name, ws_magic[weap->o_which].mi_name);
942 else
943 msg("%s hits you.", att_name);
944 }
945
946 /*
947 * bounce:
948 * A missile misses a monster
949 */
950
951 bounce(weap, tp, mname)
952 register struct object *weap;
953 register struct thing *tp; /* Defender */
954 register char *mname;
955 {
956 char *def_name; /* Name of defender */
957
958 /* What do we call the defender? */
959 if (!cansee(tp->t_pos.y, tp->t_pos.x) || invisible(tp))
960 def_name = "something";
961 else def_name = prname(mname, FALSE);
962
963 if (weap->o_type == WEAPON)
964 msg("The %s misses %s.",weaps[weap->o_which].w_name, def_name);
965 else if (weap->o_type == MISSILE)
966 msg("The %s misses %s.",ws_magic[weap->o_which].mi_name, def_name);
967 else
968 msg("You missed %s.", def_name);
969 }
970
971 /*
972 * m_bounce:
973 * A missle from a monster misses the player
974 */
975
976 m_bounce(weap, tp, mname)
977 register struct object *weap;
978 register struct thing *tp;
979 register char *mname;
980 {
981 char *att_name; /* Name of attacker */
982
983 /* What do we call the attacker? */
984 if (!cansee(tp->t_pos.y, tp->t_pos.x) || invisible(tp))
985 att_name = "Something";
986 else att_name = prname(mname, TRUE);
987
988 if (weap->o_type == WEAPON)
989 msg("%s's %s misses you.", att_name, weaps[weap->o_which].w_name);
990 else if (weap->o_type == MISSILE)
991 msg("%s's %s misses you.", att_name, ws_magic[weap->o_which].mi_name);
992 else
993 msg("%s misses you.", att_name);
994 }
995 #endif
996
997
998 /*
999 * is_magic:
1000 * Returns true if an object radiates magic
1001 */
1002
1003 is_magic(obj)
1004 register struct object *obj;
1005 {
1006 switch (obj->o_type)
1007 {
1008 case ARMOR:
1009 return obj->o_ac != armors[obj->o_which].a_class;
1010 when WEAPON:
1011 return obj->o_hplus != 0 || obj->o_dplus != 0;
1012 when POTION:
1013 case SCROLL:
1014 case STICK:
1015 case RING:
1016 case MM:
1017 case RELIC:
1018 return TRUE;
1019 }
1020 return FALSE;
1021 }
1022
1023 /*
1024 * killed:
1025 * Called to put a monster to death
1026 */
1027
1028 int chance = 0;/* cumulative chance for goodies to loose it */
1029
1030 killed(item, pr, points, treasure)
1031 register struct linked_list *item;
1032 bool pr, points, treasure;
1033 {
1034 register struct thing *tp, *mp;
1035 register struct linked_list *pitem, *nexti, *mitem;
1036 char *monst;
1037
1038 tp = THINGPTR(item);
1039
1040 if (pr)
1041 {
1042 addmsg(terse ? "Defeated " : "You have defeated ");
1043 if (on(player, ISBLIND))
1044 msg("it.");
1045 else
1046 {
1047 if (cansee(tp->t_pos.y, tp->t_pos.x) && !invisible(tp))
1048 monst = monster_name(tp);
1049 else {
1050 if (terse) monst = "something";
1051 else monst = "thing";
1052 }
1053 if (!terse)
1054 addmsg("the ");
1055 msg("%s.", monst);
1056 }
1057 }
1058
1059 /* Take care of any residual effects of the monster */
1060 check_residue(tp);
1061
1062 /* Make sure that no one is still chasing us */
1063 for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
1064 mp = THINGPTR(mitem);
1065 if (mp->t_dest == &tp->t_pos) {
1066 mp->t_dest = &hero;
1067 mp->t_wasshot = FALSE;
1068 turn_off(*mp, ISFLEE); /* Be sure we aren't running away! */
1069 }
1070 }
1071
1072 if (points) {
1073 if ((off(*tp, ISMEAN) || on(*tp, ISFRIENDLY)) &&
1074 (player.t_ctype == C_RANGER || player.t_ctype == C_PALADIN)) {
1075 if (tp->t_stats.s_exp > pstats.s_exp)
1076 pstats.s_exp = 0;
1077 else
1078 pstats.s_exp -= tp->t_stats.s_exp;
1079 if (roll(1,100) < chance++)
1080 changeclass(C_FIGHTER);
1081 else
1082 msg("You feel uneasy for a moment");
1083 }
1084 else {
1085 unsigned long test; /* For overflow check */
1086 /*
1087 * Do an overflow check before increasing experience
1088 */
1089 test = pstats.s_exp + tp->t_stats.s_exp;
1090 if (test > pstats.s_exp)
1091 pstats.s_exp = test;
1092 }
1093
1094 /*
1095 * Do adjustments if he went up a level
1096 */
1097 check_level();
1098 }
1099
1100 /*
1101 * Empty the monsters pack
1102 */
1103 pitem = tp->t_pack;
1104
1105 /*
1106 * Get rid of the monster.
1107 */
1108 mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, ' ');
1109 mvwaddch(cw, tp->t_pos.y, tp->t_pos.x, tp->t_oldch);
1110 detach(mlist, item);
1111 if (on(*tp, AREMANY) && levtype == NORMLEV) /* AREMANYs stick together */
1112 wake_room(roomin(&tp->t_pos));
1113 /*
1114 * empty his pack
1115 */
1116 while (pitem != NULL)
1117 {
1118 nexti = next(tp->t_pack);
1119 (OBJPTR(pitem))->o_pos = tp->t_pos;
1120 detach(tp->t_pack, pitem);
1121 if (treasure)
1122 fall(pitem, FALSE);
1123 else
1124 o_discard(pitem);
1125 pitem = nexti;
1126 }
1127 turn_on(*tp,ISDEAD);
1128 attach(monst_dead,item);
1129 }
1130
1131
1132 /*
1133 * Returns a pointer to the weapon the monster is wielding corresponding to
1134 * the given thrown weapon. If no thrown item is given, try to find any
1135 * decent weapon.
1136 */
1137
1138 struct linked_list *
1139 wield_weap(thrown, mp)
1140 struct object *thrown;
1141 struct thing *mp;
1142 {
1143 int look_for, /* The projectile weapon we are looking for */
1144 new_rate, /* The rating of a prospective weapon */
1145 cand_rate = -1; /* Rating of current candidate -- higher is better */
1146 register struct linked_list *pitem, *candidate = NULL;
1147 register struct object *obj;
1148
1149 if (thrown != NULL) { /* Using a projectile weapon */
1150 switch (thrown->o_which) {
1151 case BOLT: look_for = CROSSBOW; /* Find the crossbow */
1152 when ARROW: look_for = BOW; /* Find the bow */
1153 when ROCK: look_for = SLING; /* find the sling */
1154 otherwise: return(NULL);
1155 }
1156 }
1157 else if (off(*mp, ISUNIQUE) && off(*mp, CARRYWEAPON)) return(NULL);
1158
1159 for (pitem=mp->t_pack; pitem; pitem=next(pitem)) {
1160 obj = OBJPTR(pitem);
1161
1162 /*
1163 * If we have a thrown weapon, just return the first match
1164 * we come to.
1165 */
1166 if (thrown != NULL && obj->o_type == WEAPON && obj->o_which == look_for)
1167 return(pitem);
1168
1169 /* If we have a usable RELIC, return it */
1170 if (thrown == NULL && obj->o_type == RELIC) {
1171 switch (obj->o_which) {
1172 case MUSTY_DAGGER:
1173 case YEENOGHU_FLAIL:
1174 case HRUGGEK_MSTAR:
1175 case AXE_AKLAD:
1176 case MING_STAFF:
1177 case ASMO_ROD:
1178 case ORCUS_WAND:
1179 return(pitem);
1180 }
1181 }
1182
1183 /* Otherwise if it's a usable weapon, it is a good candidate */
1184 else if (thrown == NULL && obj->o_type == WEAPON) {
1185 switch (obj->o_which) {
1186 case DAGGER:
1187 case SPEAR:
1188 new_rate = 0;
1189 when BATTLEAXE:
1190 new_rate = 1;
1191 when MACE:
1192 new_rate = 2;
1193 when SWORD:
1194 new_rate = 3;
1195 when PIKE:
1196 new_rate = 4;
1197 when HALBERD:
1198 case SPETUM:
1199 new_rate = 6;
1200 when BARDICHE:
1201 new_rate = 7;
1202 when TRIDENT:
1203 new_rate = 8;
1204 when BASWORD:
1205 new_rate = 9;
1206 when TWOSWORD:
1207 new_rate = 10;
1208 otherwise:
1209 new_rate = -1;
1210 }
1211
1212 /* Only switch if this is better than the current candidate */
1213 if (new_rate > cand_rate) {
1214 cand_rate = new_rate;
1215 candidate = pitem;
1216 }
1217 }
1218 }
1219
1220 return(candidate);
1221 }
1222 explode(tp)
1223 register struct thing *tp;
1224 {
1225
1226 register int x,y, damage;
1227 struct linked_list *item;
1228 struct thing *th;
1229
1230 /*
1231 * check to see if it got the hero
1232 */
1233 if (off(player, ISINWALL) &&
1234 DISTANCE(hero.x, hero.y, tp->t_pos.x, tp->t_pos.y) <= 25) {
1235 msg("The explosion hits you");
1236 damage = roll(6,6);
1237 if (save(VS_WAND, &player, 0))
1238 damage /= 2;
1239 pstats.s_hpt -= damage;
1240 }
1241
1242 /*
1243 * now check for monsters in vicinity
1244 */
1245 for (x = tp->t_pos.x-5; x<=tp->t_pos.x+5; x++) {
1246 if (x < 0 || x > cols - 1)
1247 continue;
1248 for (y = tp->t_pos.y-5; y<=tp->t_pos.y+5; y++) {
1249 if (y < 1 || y > lines - 3)
1250 continue;
1251 if (isalpha(mvwinch(mw, y, x))) {
1252 if ((item = find_mons(y, x)) != NULL) {
1253 th = THINGPTR(item);
1254 if (th == tp || /* don't count gas spore */
1255 on(*th, ISINWALL)) /* Don't count monsters in wall */
1256 continue;
1257 damage = roll(6, 6);
1258 if (save(VS_WAND, th, 0))
1259 damage /= 2;
1260 runto(th, &hero);
1261 if ((th->t_stats.s_hpt -= damage) <= 0) {
1262 msg("The explosion kills %s",
1263 prname(monster_name(th), FALSE));
1264 killed(item, FALSE, FALSE, TRUE);
1265 }
1266 }
1267 }
1268 }
1269 }
1270 }
1271
1272 /*
1273 * skirmish:
1274 * Called when one monster attacks another monster.
1275 */
1276
1277 skirmish(attacker, mp, weap, thrown)
1278 register struct thing *attacker;
1279 register coord *mp;
1280 struct object *weap;
1281 bool thrown;
1282 {
1283 register struct thing *defender;
1284 register struct linked_list *item;
1285 register bool did_hit = TRUE, see_att, see_def;
1286 char attname[LINELEN+1], defname[LINELEN+1];
1287 struct object *wielded; /* The wielded weapon */
1288 struct linked_list *get_wield; /* Linked list header for wielded */
1289
1290 /*
1291 * Find the monster we want to fight
1292 */
1293 if ((item = find_mons(mp->y, mp->x)) == NULL) {
1294 return(FALSE); /* must have killed him already */
1295 }
1296 defender = THINGPTR(item);
1297
1298 /* Can the player see either of the fighters? */
1299 see_att = (cansee(unc(attacker->t_pos)) &&
1300 (off(*attacker, ISINVIS) || on(player, CANSEE)) &&
1301 (off(*attacker, ISSHADOW) || on(player, CANSEE)));
1302 see_def = (cansee(unc(defender->t_pos)) &&
1303 (off(*defender, ISINVIS) || on(player, CANSEE)) &&
1304 (off(*defender, ISSHADOW) || on(player, CANSEE)));
1305
1306 /*
1307 * Since we are fighting, things are not quiet so no healing takes
1308 * place. The -1 also tells us that we are in a fight.
1309 */
1310 attacker->t_quiet = -1;
1311 defender->t_quiet = -1;
1312
1313 if (see_att) strcpy(attname, monster_name(attacker));
1314 else strcpy(attname, "something");
1315
1316 if (see_def) strcpy(defname, monster_name(defender));
1317 else strcpy(defname, "something");
1318
1319 /*
1320 * if its in the wall, we can't hit it
1321 */
1322 if (on(*defender, ISINWALL) && off(*attacker, CANINWALL))
1323 return(FALSE);
1324
1325 if (on(*defender, ISSTONE)) {
1326 killed(item, FALSE, FALSE, FALSE);
1327 if (see_def)
1328 msg("%s shatters into a million pieces!", prname(defname, TRUE));
1329 return (TRUE);
1330 }
1331
1332 /*
1333 * Let him know it was really a mimic (if it was one).
1334 */
1335 if (see_def && on(*defender, ISDISGUISE) &&
1336 (defender->t_type != defender->t_disguise)) {
1337 msg("Wait! There's a %s!", defname);
1338 turn_off(*defender, ISDISGUISE);
1339 did_hit = thrown;
1340 }
1341
1342 if (see_def && on(*defender, CANSURPRISE) && !ISWEARING(R_ALERT)) {
1343 msg("Wait! There's a %s!", defname);
1344 turn_off(*defender, CANSURPRISE);
1345 did_hit = thrown;
1346 }
1347
1348 if (did_hit) {
1349
1350 did_hit = FALSE;
1351
1352 /*
1353 * Try to find a weapon to wield. Wield_weap will return a
1354 * projector if weapon is a projectile (eg. bow for arrow).
1355 * If weapon is NULL, it will try to find a suitable weapon.
1356 */
1357 get_wield = wield_weap(weap, attacker);
1358 if (get_wield) wielded = OBJPTR(get_wield);
1359 else wielded = NULL;
1360
1361 #ifdef DOBLINK
1362 /*
1363 * For now Blink Dogs will not blink away from monsters. We
1364 * have to fix can_blink so it isn't dependant on the player
1365 * before we can add it.
1366 */
1367 if (!can_blink(defender) &&
1368 #endif
1369 if (((weap && weap->o_type == RELIC) ||
1370 ((off(*defender, MAGICHIT) ||
1371 attacker->t_stats.s_lvl > 4 ||
1372 (weap && (weap->o_hplus > 0 || weap->o_dplus > 0))) &&
1373 (off(*defender, BMAGICHIT) ||
1374 attacker->t_stats.s_lvl > 6 ||
1375 (weap && (weap->o_hplus > 1 || weap->o_dplus > 1))) &&
1376 (off(*defender, CMAGICHIT) ||
1377 attacker->t_stats.s_lvl > 8 ||
1378 (weap && (weap->o_hplus > 2 || weap->o_dplus > 2)))))
1379 && roll_em(attacker, defender, weap, thrown, wielded, FALSE))
1380 {
1381 did_hit = TRUE;
1382
1383 /* Should we start to chase this creature? */
1384 if (attacker->t_index != defender->t_index &&
1385 (off(*defender, ISRUN) || rnd(100) < 50)) {
1386 /*
1387 * If we're intelligent enough to realize that this
1388 * is a friendly monster, we will attack the hero instead.
1389 */
1390 if (on(*attacker, ISFRIENDLY) &&
1391 roll(3,6) < defender->t_stats.s_intel) {
1392 runto(defender, &hero);
1393 debug("%s attacking %s's hero", defname, attname);
1394 }
1395
1396 /* Otherwise, let's chase the monster */
1397 else {
1398 runto(defender, &attacker->t_pos);
1399 debug("%s now attacking %s", defname, attname);
1400 }
1401 }
1402 else if (off(*defender, ISRUN)) runto(defender, &hero);
1403
1404 /* Let the defender know that the attacker has missiles! */
1405 if ((defender->t_dest == &attacker->t_pos) && thrown)
1406 defender->t_wasshot = TRUE;
1407
1408 if (on(*defender, NOMETAL) && weap != NULL &&
1409 weap->o_type != RELIC && weap->o_flags & ISMETAL) {
1410 if (see_def && see_att)
1411 msg("The %s passes right through %s!",
1412 weaps[weap->o_which].w_name, prname(defname, FALSE));
1413 }
1414 else {
1415 hit(weap, see_att, see_def,
1416 attname, defname, FALSE, thrown, FALSE);
1417 }
1418
1419 /* See if there are any special effects */
1420 if (effect(attacker, defender,
1421 weap, thrown, see_att, see_def) != 0) {
1422 killed(item, FALSE, FALSE, TRUE);
1423 if (see_def) msg("%s dies.", prname(defname, TRUE));
1424 else msg("You hear a blood-curdling scream.");
1425 }
1426
1427 /*
1428 * Merchants just disappear if hit
1429 */
1430 else if (on(*defender, CANSELL)) {
1431 if (see_def)
1432 msg("%s disappears with his wares in a flash.",
1433 prname(defname, TRUE));
1434 killed(item, FALSE, FALSE, FALSE);
1435 }
1436
1437 else if (defender->t_stats.s_hpt <= 0) {
1438 killed(item, FALSE, FALSE, TRUE);
1439 if (see_def) msg("%s dies.", prname(defname, TRUE));
1440 else msg("You hear a blood-curdling scream.");
1441 }
1442
1443 else {
1444 /* Did we disrupt a spell? */
1445 /* Don't turn on WASDISRUPTED since player didn't do it */
1446 if (defender->t_action == A_SUMMON ||
1447 defender->t_action == A_MISSILE) {
1448 /* Just make the old fellow start over again */
1449 defender->t_action = A_NIL;
1450 defender->t_no_move = movement(defender);
1451 defender->t_using = NULL;
1452
1453 if (see_def)
1454 msg("%s was disrupted.", prname(defname, TRUE));
1455 }
1456
1457 #ifdef FLEEMONST
1458 /*
1459 * If the monster is fairly intelligent and about to die, it
1460 * may turn tail and run. WE STILL NEED TO FIGURE OUT HOW
1461 * WE WANT THIS TO WORK.
1462 */
1463 if ((tp->t_stats.s_hpt < max(10, tp->maxstats.s_hpt/10)) &&
1464 (rnd(25) < tp->t_stats.s_intel)) {
1465 turn_on(*tp, ISFLEE);
1466
1467 /* If monster was suffocating, stop it */
1468 if (on(*tp, DIDSUFFOCATE)) {
1469 turn_off(*tp, DIDSUFFOCATE);
1470 extinguish(suffocate);
1471 }
1472
1473 /* If monster held us, stop it */
1474 if (on(*tp, DIDHOLD) && (--hold_count == 0))
1475 turn_off(player, ISHELD);
1476 turn_off(*tp, DIDHOLD);
1477
1478 /* It is okay to turn tail */
1479 tp->t_oldpos = tp->t_pos;
1480 }
1481 #endif
1482 }
1483 }
1484 else {
1485 /* If the thing was trying to surprise, no good */
1486 if (on(*attacker, CANSURPRISE)) {
1487 /* If we can't see it, it keeps surprise (from us) */
1488 if (see_att) turn_off(*attacker, CANSURPRISE);
1489 }
1490
1491 miss(weap, see_att, see_def, attname, defname, thrown, FALSE);
1492 }
1493 }
1494 return did_hit;
1495 }