comparison xrogue/fight.c @ 133:e6179860cb76

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