1 | /* SCCS Id: @(#)mhitm.c 3.3 2000/07/29 */
2 | /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 | /* NetHack may be freely redistributed. See license for details. */
4 |
5 | #include "hack.h"
6 | #include "artifact.h"
7 | #include "edog.h"
8 |
9 | extern boolean notonhead;
10 |
11 | #ifdef OVLB
12 |
13 | static NEARDATA boolean vis, far_noise;
14 | static NEARDATA long noisetime;
15 | static NEARDATA struct obj *otmp;
16 |
17 | static const char brief_feeling[] =
18 | "have a %s feeling for a moment, then it passes.";
19 |
20 | STATIC_DCL char *FDECL(mon_nam_too, (char *,struct monst *,struct monst *));
21 | STATIC_DCL void FDECL(mrustm, (struct monst *, struct monst *, struct obj *));
22 | STATIC_DCL int FDECL(hitmm, (struct monst *,struct monst *,struct attack *));
23 | STATIC_DCL int FDECL(gazemm, (struct monst *,struct monst *,struct attack *));
24 | STATIC_DCL int FDECL(gulpmm, (struct monst *,struct monst *,struct attack *));
25 | STATIC_DCL int FDECL(explmm, (struct monst *,struct monst *,struct attack *));
26 | STATIC_DCL int FDECL(mdamagem, (struct monst *,struct monst *,struct attack *));
27 | STATIC_DCL void FDECL(mswingsm, (struct monst *, struct monst *, struct obj *));
28 | STATIC_DCL void FDECL(noises,(struct monst *,struct attack *));
29 | STATIC_DCL void FDECL(missmm,(struct monst *,struct monst *,struct attack *));
30 | STATIC_DCL int FDECL(passivemm, (struct monst *, struct monst *, BOOLEAN_P, int));
31 |
32 | /* Needed for the special case of monsters wielding vorpal blades (rare).
33 | * If we use this a lot it should probably be a parameter to mdamagem()
34 | * instead of a global variable.
35 | */
36 | static int dieroll;
37 |
38 | /* returns mon_nam(mon) relative to other_mon; normal name unless they're
39 | the same, in which case the reference is to {him|her|it} self */
40 | STATIC_OVL char *
41 | mon_nam_too(outbuf, mon, other_mon)
42 | char *outbuf;
43 | struct monst *mon, *other_mon;
44 | {
45 | Strcpy(outbuf, mon_nam(mon));
46 | if (mon == other_mon)
47 | switch (pronoun_gender(mon)) {
48 | case 0: Strcpy(outbuf, "himself"); break;
49 | case 1: Strcpy(outbuf, "herself"); break;
50 | default: Strcpy(outbuf, "itself"); break;
51 | }
52 | return outbuf;
53 | }
54 |
55 | STATIC_OVL void
56 | noises(magr, mattk)
57 | register struct monst *magr;
58 | register struct attack *mattk;
59 | {
60 | boolean farq = (distu(magr->mx, magr->my) > 15);
61 |
62 | if(flags.soundok && (farq != far_noise || moves-noisetime > 10)) {
63 | far_noise = farq;
64 | noisetime = moves;
65 | You_hear("%s%s.",
66 | (mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises",
67 | farq ? " in the distance" : "");
68 | }
69 | }
70 |
71 | STATIC_OVL
72 | void
73 | missmm(magr, mdef, mattk)
74 | register struct monst *magr, *mdef;
75 | struct attack *mattk;
76 | {
77 | const char *fmt;
78 | char buf[BUFSZ], mdef_name[BUFSZ];
79 |
80 | if (vis) {
81 | if (!canspotmon(mdef))
82 | map_invisible(mdef->mx, mdef->my);
83 | if (mdef->m_ap_type) seemimic(mdef);
84 | if (magr->m_ap_type) seemimic(magr);
85 | fmt = (could_seduce(magr,mdef,mattk) && !magr->mcan) ?
86 | "%s pretends to be friendly to" : "%s misses";
87 | Sprintf(buf, fmt, Monnam(magr));
88 | pline("%s %s.", buf, mon_nam_too(mdef_name, mdef, magr));
89 | } else noises(magr, mattk);
90 | }
91 |
92 | /*
93 | * fightm() -- fight some other monster
94 | *
95 | * Returns:
96 | * 0 - Monster did nothing.
97 | * 1 - If the monster made an attack. The monster might have died.
98 | *
99 | * There is an exception to the above. If mtmp has the hero swallowed,
100 | * then we report that the monster did nothing so it will continue to
101 | * digest the hero.
102 | */
103 | int
104 | fightm(mtmp) /* have monsters fight each other */
105 | register struct monst *mtmp;
106 | {
107 | register struct monst *mon, *nmon;
108 | int result, has_u_swallowed;
109 | #ifdef LINT
110 | nmon = 0;
111 | #endif
112 | /* perhaps the monster will resist Conflict */
113 | if(resist(mtmp, RING_CLASS, 0, 0))
114 | return(0);
115 |
116 | if(u.ustuck == mtmp) {
117 | /* perhaps we're holding it... */
118 | if(itsstuck(mtmp))
119 | return(0);
120 | }
121 | has_u_swallowed = (u.uswallow && (mtmp == u.ustuck));
122 |
123 | for(mon = fmon; mon; mon = nmon) {
124 | nmon = mon->nmon;
125 | if(nmon == mtmp) nmon = mtmp->nmon;
126 | /* Be careful to ignore monsters that are already dead, since we
127 | * might be calling this before we've cleaned them up. This can
128 | * happen if the monster attacked a cockatrice bare-handedly, for
129 | * instance.
130 | */
131 | if(mon != mtmp && !DEADMONSTER(mon)) {
132 | if(monnear(mtmp,mon->mx,mon->my)) {
133 | if(!u.uswallow && (mtmp == u.ustuck)) {
134 | if(!rn2(4)) {
135 | pline("%s releases you!", Monnam(mtmp));
136 | u.ustuck = 0;
137 | } else
138 | break;
139 | }
140 |
141 | /* mtmp can be killed */
142 | bhitpos.x = mon->mx;
143 | bhitpos.y = mon->my;
144 | notonhead = 0;
145 | result = mattackm(mtmp,mon);
146 |
147 | if (result & MM_AGR_DIED) return 1; /* mtmp died */
148 | /*
149 | * If mtmp has the hero swallowed, lie and say there
150 | * was no attack (this allows mtmp to digest the hero).
151 | */
152 | if (has_u_swallowed) return 0;
153 |
154 | return ((result & MM_HIT) ? 1 : 0);
155 | }
156 | }
157 | }
158 | return 0;
159 | }
160 |
161 | /*
162 | * mattackm() -- a monster attacks another monster.
163 | *
164 | * This function returns a result bitfield:
165 | *
166 | * --------- aggressor died
167 | * / ------- defender died
168 | * / / ----- defender was hit
169 | * / / /
170 | * x x x
171 | *
172 | * 0x4 MM_AGR_DIED
173 | * 0x2 MM_DEF_DIED
174 | * 0x1 MM_HIT
175 | * 0x0 MM_MISS
176 | *
177 | * Each successive attack has a lower probability of hitting. Some rely on the
178 | * success of previous attacks. ** this doen't seem to be implemented -dl **
179 | *
180 | * In the case of exploding monsters, the monster dies as well.
181 | */
182 | int
183 | mattackm(magr, mdef)
184 | register struct monst *magr,*mdef;
185 | {
186 | int i, /* loop counter */
187 | tmp, /* amour class difference */
188 | strike, /* hit this attack */
189 | attk, /* attack attempted this time */
190 | struck = 0, /* hit at least once */
191 | res[NATTK]; /* results of all attacks */
192 | struct attack *mattk;
193 | struct permonst *pa, *pd;
194 |
195 | if (!magr || !mdef) return(MM_MISS); /* mike@genat */
196 | if (!magr->mcanmove) return(MM_MISS); /* riv05!a3 */
197 | pa = magr->data; pd = mdef->data;
198 |
199 | /* Grid bugs cannot attack at an angle. */
200 | if (pa == &mons[PM_GRID_BUG] && magr->mx != mdef->mx
201 | && magr->my != mdef->my)
202 | return(MM_MISS);
203 |
204 | /* Calculate the armour class differential. */
205 | tmp = find_mac(mdef) + magr->m_lev;
206 | if (mdef->mconf || !mdef->mcanmove || mdef->msleeping) {
207 | tmp += 4;
208 | mdef->msleeping = 0;
209 | }
210 |
211 | /* undetect monsters become un-hidden if they are attacked */
212 | if (mdef->mundetected) {
213 | mdef->mundetected = 0;
214 | newsym(mdef->mx, mdef->my);
215 | if(canseemon(mdef) && !sensemon(mdef))
216 | pline("Suddenly, you notice %s.", a_monnam(mdef));
217 | }
218 |
219 | /* Elves hate orcs. */
220 | if (is_elf(pa) && is_orc(pd)) tmp++;
221 |
222 |
223 | /* Set up the visibility of action */
224 | vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my));
225 |
226 | /* Set flag indicating monster has moved this turn. Necessary since a
227 | * monster might get an attack out of sequence (i.e. before its move) in
228 | * some cases, in which case this still counts as its move for the round
229 | * and it shouldn't move again.
230 | */
231 | magr->mlstmv = monstermoves;
232 |
233 | /* Now perform all attacks for the monster. */
234 | for (i = 0; i < NATTK; i++) {
235 | res[i] = MM_MISS;
236 | mattk = &(pa->mattk[i]);
237 | otmp = (struct obj *)0;
238 | attk = 1;
239 | switch (mattk->aatyp) {
240 | case AT_WEAP: /* "hand to hand" attacks */
241 | if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) {
242 | magr->weapon_check = NEED_HTH_WEAPON;
243 | if (mon_wield_item(magr) != 0) return 0;
244 | }
245 | possibly_unwield(magr);
246 | otmp = MON_WEP(magr);
247 |
248 | if (otmp) {
249 | if (vis) mswingsm(magr, mdef, otmp);
250 | tmp += hitval(otmp, mdef);
251 | }
252 | /* fall through */
253 | case AT_CLAW:
254 | case AT_KICK:
255 | case AT_BITE:
256 | case AT_STNG:
257 | case AT_TUCH:
258 | case AT_BUTT:
259 | case AT_TENT:
260 | /* Nymph that teleported away on first attack? */
261 | if (distmin(magr->mx,magr->my,mdef->mx,mdef->my) > 1)
262 | return MM_MISS;
263 | /* Monsters won't attack cockatrices physically if they
264 | * have a weapon instead. This instinct doesn't work for
265 | * players, or under conflict or confusion.
266 | */
267 | if (!magr->mconf && !Conflict && otmp &&
268 | mattk->aatyp != AT_WEAP && touch_petrifies(mdef->data)) {
269 | strike = 0;
270 | break;
271 | }
272 | dieroll = rnd(20 + i);
273 | strike = (tmp > dieroll);
274 | /* KMH -- don't accumulate to-hit bonuses */
275 | if (otmp)
276 | tmp -= hitval(otmp, mdef);
277 | if (strike)
278 | res[i] = hitmm(magr, mdef, mattk);
279 | else
280 | missmm(magr, mdef, mattk);
281 | break;
282 |
283 | case AT_HUGS: /* automatic if prev two attacks succeed */
284 | strike = (i >= 2 && res[i-1] == MM_HIT && res[i-2] == MM_HIT);
285 | if (strike)
286 | res[i] = hitmm(magr, mdef, mattk);
287 |
288 | break;
289 |
290 | case AT_GAZE:
291 | strike = 0; /* will not wake up a sleeper */
292 | res[i] = gazemm(magr, mdef, mattk);
293 | break;
294 |
295 | case AT_EXPL:
296 | strike = 1; /* automatic hit */
297 | res[i] = explmm(magr, mdef, mattk);
298 | break;
299 |
300 | case AT_ENGL:
301 | #ifdef STEED
302 | if (u.usteed && (mdef == u.usteed)) {
303 | strike = 0;
304 | break;
305 | }
306 | #endif
307 | /* Engulfing attacks are directed at the hero if
308 | * possible. -dlc
309 | */
310 | if (u.uswallow && magr == u.ustuck)
311 | strike = 0;
312 | else {
313 | if ((strike = (tmp > rnd(20+i))))
314 | res[i] = gulpmm(magr, mdef, mattk);
315 | else
316 | missmm(magr, mdef, mattk);
317 | }
318 | break;
319 |
320 | default: /* no attack */
321 | strike = 0;
322 | attk = 0;
323 | break;
324 | }
325 |
326 | if (attk && !(res[i] & MM_AGR_DIED))
327 | res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED);
328 |
329 | if (res[i] & MM_DEF_DIED) return res[i];
330 |
331 | /*
332 | * Wake up the defender. NOTE: this must follow the check
333 | * to see if the defender died. We don't want to modify
334 | * unallocated monsters!
335 | */
336 | if (strike) mdef->msleeping = 0;
337 |
338 | if (res[i] & MM_AGR_DIED) return res[i];
339 | /* return if aggressor can no longer attack */
340 | if (!magr->mcanmove || magr->msleeping) return res[i];
341 | if (res[i] & MM_HIT) struck = 1; /* at least one hit */
342 | }
343 |
344 | return(struck ? MM_HIT : MM_MISS);
345 | }
346 |
347 | /* Returns the result of mdamagem(). */
348 | STATIC_OVL int
349 | hitmm(magr, mdef, mattk)
350 | register struct monst *magr,*mdef;
351 | struct attack *mattk;
352 | {
353 | if(vis){
354 | int compat;
355 | char buf[BUFSZ], mdef_name[BUFSZ];
356 |
357 | if (!canspotmon(mdef))
358 | map_invisible(mdef->mx, mdef->my);
359 | if(mdef->m_ap_type) seemimic(mdef);
360 | if(magr->m_ap_type) seemimic(magr);
361 | if((compat = could_seduce(magr,mdef,mattk)) && !magr->mcan) {
362 | Sprintf(buf, "%s %s", Monnam(magr),
363 | mdef->mcansee ? "smiles at" : "talks to");
364 | pline("%s %s %s.", buf, mon_nam(mdef),
365 | compat == 2 ?
366 | "engagingly" : "seductively");
367 | } else {
368 | char magr_name[BUFSZ];
369 |
370 | Strcpy(magr_name, Monnam(magr));
371 | switch (mattk->aatyp) {
372 | case AT_BITE:
373 | Sprintf(buf,"%s bites", magr_name);
374 | break;
375 | case AT_STNG:
376 | Sprintf(buf,"%s stings", magr_name);
377 | break;
378 | case AT_BUTT:
379 | Sprintf(buf,"%s butts", magr_name);
380 | break;
381 | case AT_TUCH:
382 | Sprintf(buf,"%s touches", magr_name);
383 | break;
384 | case AT_TENT:
385 | Sprintf(buf, "%s tentacles suck",
386 | s_suffix(magr_name));
387 | break;
388 | case AT_HUGS:
389 | if (magr != u.ustuck) {
390 | Sprintf(buf,"%s squeezes", magr_name);
391 | break;
392 | }
393 | default:
394 | Sprintf(buf,"%s hits", magr_name);
395 | }
396 | }
397 | pline("%s %s.", buf, mon_nam_too(mdef_name, mdef, magr));
398 | } else noises(magr, mattk);
399 | return(mdamagem(magr, mdef, mattk));
400 | }
401 |
402 | /* Returns the same values as mdamagem(). */
403 | STATIC_OVL int
404 | gazemm(magr, mdef, mattk)
405 | register struct monst *magr, *mdef;
406 | struct attack *mattk;
407 | {
408 | char buf[BUFSZ];
409 |
410 | if(vis) {
411 | Sprintf(buf,"%s gazes at", Monnam(magr));
412 | pline("%s %s...", buf, mon_nam(mdef));
413 | }
414 |
415 | if (!mdef->mcansee || mdef->msleeping) {
416 | if(vis) pline("but nothing happens.");
417 | return(MM_MISS);
418 | }
419 |
420 | return(mdamagem(magr, mdef, mattk));
421 | }
422 |
423 | /* Returns the same values as mattackm(). */
424 | STATIC_OVL int
425 | gulpmm(magr, mdef, mattk)
426 | register struct monst *magr, *mdef;
427 | register struct attack *mattk;
428 | {
429 | xchar ax, ay, dx, dy;
430 | int status;
431 | char buf[BUFSZ];
432 | struct obj *obj;
433 |
434 | if (mdef->data->msize >= MZ_HUGE) return MM_MISS;
435 |
436 | if (vis) {
437 | Sprintf(buf,"%s swallows", Monnam(magr));
438 | pline("%s %s.", buf, mon_nam(mdef));
439 | }
440 | for (obj = mdef->minvent; obj; obj = obj->nobj)
441 | (void) snuff_lit(obj);
442 |
443 | /*
444 | * All of this maniuplation is needed to keep the display correct.
445 | * There is a flush at the next pline().
446 | */
447 | ax = magr->mx;
448 | ay = magr->my;
449 | dx = mdef->mx;
450 | dy = mdef->my;
451 | /*
452 | * Leave the defender in the monster chain at it's current position,
453 | * but don't leave it on the screen. Move the agressor to the def-
454 | * ender's position.
455 | */
456 | remove_monster(ax, ay);
457 | place_monster(magr, dx, dy);
458 | newsym(ax,ay); /* erase old position */
459 | newsym(dx,dy); /* update new position */
460 |
461 | status = mdamagem(magr, mdef, mattk);
462 |
463 | if ((status & MM_AGR_DIED) && (status & MM_DEF_DIED)) {
464 | ; /* both died -- do nothing */
465 | }
466 | else if (status & MM_DEF_DIED) { /* defender died */
467 | /*
468 | * Note: remove_monster() was called in relmon(), wiping out
469 | * magr from level.monsters[mdef->mx][mdef->my]. We need to
470 | * put it back and display it. -kd
471 | */
472 | place_monster(magr, dx, dy);
473 | newsym(dx, dy);
474 | }
475 | else if (status & MM_AGR_DIED) { /* agressor died */
476 | place_monster(mdef, dx, dy);
477 | newsym(dx, dy);
478 | }
479 | else { /* both alive, put them back */
480 | if (cansee(dx, dy))
481 | pline("%s is regurgitated!", Monnam(mdef));
482 |
483 | place_monster(magr, ax, ay);
484 | place_monster(mdef, dx, dy);
485 | newsym(ax, ay);
486 | newsym(dx, dy);
487 | }
488 |
489 | return status;
490 | }
491 |
492 | STATIC_OVL int
493 | explmm(magr, mdef, mattk)
494 | register struct monst *magr, *mdef;
495 | register struct attack *mattk;
496 | {
497 | int result;
498 |
499 | if(cansee(magr->mx, magr->my))
500 | pline("%s explodes!", Monnam(magr));
501 | else noises(magr, mattk);
502 |
503 | result = mdamagem(magr, mdef, mattk);
504 |
505 | /* Kill off agressor if it didn't die. */
506 | if (!(result & MM_AGR_DIED)) {
507 | mondead(magr);
508 | if (magr->mhp > 0) return result; /* life saved */
509 | result |= MM_AGR_DIED;
510 | }
511 | if (magr->mtame) /* give this one even if it was visible */
512 | You(brief_feeling, "melancholy");
513 |
514 | return result;
515 | }
516 |
517 | /*
518 | * See comment at top of mattackm(), for return values.
519 | */
520 | STATIC_OVL int
521 | mdamagem(magr, mdef, mattk)
522 | register struct monst *magr, *mdef;
523 | register struct attack *mattk;
524 | {
525 | struct permonst *pa = magr->data, *pd = mdef->data;
526 | int tmp = d((int)mattk->damn,(int)mattk->damd);
527 | struct obj *obj;
528 | char buf[BUFSZ];
529 |
530 | if (touch_petrifies(pd) && !resists_ston(magr) &&
531 | (mattk->aatyp != AT_WEAP || !otmp) &&
532 | (mattk->aatyp != AT_GAZE && mattk->aatyp != AT_EXPL) &&
533 | !(magr->misc_worn_check & W_ARMG)) {
534 | if (poly_when_stoned(pa)) {
535 | mon_to_stone(magr);
536 | return MM_HIT; /* no damage during the polymorph */
537 | }
538 | if (vis) pline("%s turns to stone!", Monnam(magr));
539 | monstone(magr);
540 | if (magr->mhp > 0) return 0;
541 | else if (magr->mtame && !vis)
542 | You(brief_feeling, "peculiarly sad");
543 | return MM_AGR_DIED;
544 | }
545 |
546 | switch(mattk->adtyp) {
547 | case AD_DGST:
548 | /* eating a Rider or its corpse is fatal */
549 | if (is_rider(mdef->data)) {
550 | if (vis)
551 | pline("%s %s!", Monnam(magr),
552 | mdef->data == &mons[PM_FAMINE] ?
553 | "belches feebly, shrivels up and dies" :
554 | mdef->data == &mons[PM_PESTILENCE] ?
555 | "coughs spasmodically and collapses" :
556 | "vomits violently and drops dead");
557 | mondied(magr);
558 | if (magr->mhp > 0) return 0; /* lifesaved */
559 | else if (magr->mtame && !vis)
560 | You(brief_feeling, "queasy");
561 | return MM_AGR_DIED;
562 | }
563 | if(flags.verbose && flags.soundok) verbalize("Burrrrp!");
564 | tmp = mdef->mhp;
565 | /* Use up amulet of life saving */
566 | if (!!(obj = mlifesaver(mdef))) m_useup(mdef, obj);
567 | break;
568 | case AD_STUN:
569 | if (magr->mcan) break;
570 | if(vis) pline("%s staggers for a moment.", Monnam(mdef));
571 | mdef->mstun = 1;
572 | /* fall through */
573 | case AD_WERE:
574 | case AD_HEAL:
575 | case AD_LEGS:
576 | case AD_PHYS:
577 | if (mattk->aatyp == AT_KICK && thick_skinned(pd))
578 | tmp = 0;
579 | else if(mattk->aatyp == AT_WEAP) {
580 | if(otmp) {
581 | if (otmp->otyp == CORPSE &&
582 | touch_petrifies(&mons[otmp->corpsenm]))
583 | goto do_stone_goto_label;
584 | tmp += dmgval(otmp, mdef);
585 | if (otmp->oartifact) {
586 | (void)artifact_hit(magr,mdef, otmp, &tmp, dieroll);
587 | if (mdef->mhp <= 0)
588 | return (MM_DEF_DIED |
589 | (grow_up(magr,mdef) ? 0 : MM_AGR_DIED));
590 | }
591 | if (tmp)
592 | mrustm(magr, mdef, otmp);
593 | }
594 | } else if (magr->data == &mons[PM_PURPLE_WORM] &&
595 | mdef->data == &mons[PM_SHRIEKER]) {
596 | /* hack to enhance mm_aggression(); we don't want purple
597 | worm's bite attack to kill a shrieker because then it
598 | won't swallow the corpse; but if the target survives,
599 | the subsequent engulf attack should accomplish that */
600 | if (tmp >= mdef->mhp) tmp = mdef->mhp - 1;
601 | }
602 | break;
603 | case AD_FIRE:
604 | if (magr->mcan) {
605 | tmp = 0;
606 | break;
607 | }
608 | if (vis)
609 | pline("%s is %s!", Monnam(mdef),
610 | mattk->aatyp == AT_HUGS ?
611 | "being roasted" : "on fire");
612 | if (pd == &mons[PM_STRAW_GOLEM] ||
613 | pd == &mons[PM_PAPER_GOLEM]) {
614 | if (vis) pline("%s burns completely!", Monnam(mdef));
615 | mondied(mdef);
616 | if (mdef->mhp > 0) return 0;
617 | else if (mdef->mtame && !vis)
618 | pline("May %s roast in peace.", mon_nam(mdef));
619 | return (MM_DEF_DIED | (grow_up(magr,mdef) ?
620 | 0 : MM_AGR_DIED));
621 | }
622 | tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
623 | tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
624 | if (resists_fire(mdef)) {
625 | if (vis)
626 | pline_The("fire doesn't seem to burn %s!",
627 | mon_nam(mdef));
628 | shieldeff(mdef->mx, mdef->my);
629 | golemeffects(mdef, AD_FIRE, tmp);
630 | tmp = 0;
631 | }
632 | /* only potions damage resistant players in destroy_item */
633 | tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
634 | break;
635 | case AD_COLD:
636 | if (magr->mcan) {
637 | tmp = 0;
638 | break;
639 | }
640 | if (vis) pline("%s is covered in frost!", Monnam(mdef));
641 | if (resists_cold(mdef)) {
642 | if (vis)
643 | pline_The("frost doesn't seem to chill %s!",
644 | mon_nam(mdef));
645 | shieldeff(mdef->mx, mdef->my);
646 | golemeffects(mdef, AD_COLD, tmp);
647 | tmp = 0;
648 | }
649 | tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
650 | break;
651 | case AD_ELEC:
652 | if (magr->mcan) {
653 | tmp = 0;
654 | break;
655 | }
656 | if (vis) pline("%s gets zapped!", Monnam(mdef));
657 | tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
658 | if (resists_elec(mdef)) {
659 | if (vis) pline_The("zap doesn't shock %s!", mon_nam(mdef));
660 | shieldeff(mdef->mx, mdef->my);
661 | golemeffects(mdef, AD_ELEC, tmp);
662 | tmp = 0;
663 | }
664 | /* only rings damage resistant players in destroy_item */
665 | tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
666 | break;
667 | case AD_ACID:
668 | if (magr->mcan) {
669 | tmp = 0;
670 | break;
671 | }
672 | if (resists_acid(mdef)) {
673 | if (vis)
674 | pline("%s is covered in acid, but it seems harmless.",
675 | Monnam(mdef));
676 | tmp = 0;
677 | } else if (vis) {
678 | pline("%s is covered in acid!", Monnam(mdef));
679 | pline("It burns %s!", mon_nam(mdef));
680 | }
681 | if (!rn2(30)) erode_armor(mdef, TRUE);
682 | if (!rn2(6)) erode_weapon(MON_WEP(mdef), TRUE);
683 | break;
684 | case AD_RUST:
685 | if (!magr->mcan && pd == &mons[PM_IRON_GOLEM]) {
686 | if (vis) pline("%s falls to pieces!", Monnam(mdef));
687 | mondied(mdef);
688 | if (mdef->mhp > 0) return 0;
689 | else if (mdef->mtame && !vis)
690 | pline("May %s rust in peace.", mon_nam(mdef));
691 | return (MM_DEF_DIED | (grow_up(magr,mdef) ?
692 | 0 : MM_AGR_DIED));
693 | }
694 | hurtmarmor(mdef, AD_RUST);
695 | tmp = 0;
696 | break;
697 | case AD_CORRODE:
698 | hurtmarmor(mdef, AD_CORRODE);
699 | tmp = 0;
700 | break;
701 | case AD_DCAY:
702 | if (!magr->mcan && (pd == &mons[PM_WOOD_GOLEM] ||
703 | pd == &mons[PM_LEATHER_GOLEM])) {
704 | if (vis) pline("%s falls to pieces!", Monnam(mdef));
705 | mondied(mdef);
706 | if (mdef->mhp > 0) return 0;
707 | else if (mdef->mtame && !vis)
708 | pline("May %s rot in peace.", mon_nam(mdef));
709 | return (MM_DEF_DIED | (grow_up(magr,mdef) ?
710 | 0 : MM_AGR_DIED));
711 | }
712 | hurtmarmor(mdef, AD_DCAY);
713 | tmp = 0;
714 | break;
715 | case AD_STON:
716 | do_stone_goto_label:
717 | /* may die from the acid if it eats a stone-curing corpse */
718 | if (munstone(mdef, FALSE)) goto label2;
719 | if (poly_when_stoned(pd)) {
720 | mon_to_stone(mdef);
721 | tmp = 0;
722 | break;
723 | }
724 | if (!resists_ston(mdef)) {
725 | if (vis) pline("%s turns to stone!", Monnam(mdef));
726 | monstone(mdef);
727 | label2: if (mdef->mhp > 0) return 0;
728 | else if (mdef->mtame && !vis)
729 | You(brief_feeling, "peculiarly sad");
730 | return (MM_DEF_DIED | (grow_up(magr,mdef) ?
731 | 0 : MM_AGR_DIED));
732 | }
733 | tmp = (mattk->adtyp == AD_STON ? 0 : 1);
734 | break;
735 | case AD_TLPT:
736 | if (!magr->mcan && tmp < mdef->mhp && !tele_restrict(mdef)) {
737 | char mdef_Monnam[BUFSZ];
738 | /* save the name before monster teleports, otherwise
739 | we'll get "it" in the suddenly disappears message */
740 | if (vis) Strcpy(mdef_Monnam, Monnam(mdef));
741 | rloc(mdef);
742 | if (vis && !canspotmon(mdef)
743 | #ifdef STEED
744 | && mdef != u.usteed
745 | #endif
746 | )
747 | pline("%s suddenly disappears!", mdef_Monnam);
748 | }
749 | break;
750 | case AD_SLEE:
751 | if (!magr->mcan && !mdef->msleeping &&
752 | sleep_monst(mdef, rnd(10), -1)) {
753 | if (vis) {
754 | Strcpy(buf, Monnam(mdef));
755 | pline("%s is put to sleep by %s.", buf, mon_nam(magr));
756 | }
757 | slept_monst(mdef);
758 | }
759 | break;
760 | case AD_PLYS:
761 | if(!magr->mcan && mdef->mcanmove) {
762 | if (vis) {
763 | Strcpy(buf, Monnam(mdef));
764 | pline("%s is frozen by %s.", buf, mon_nam(magr));
765 | }
766 | mdef->mcanmove = 0;
767 | mdef->mfrozen = rnd(10);
768 | }
769 | break;
770 | case AD_SLOW:
771 | if (!magr->mcan && vis && mdef->mspeed != MSLOW) {
772 | unsigned int oldspeed = mdef->mspeed;
773 |
774 | mon_adjust_speed(mdef, -1);
775 | if (mdef->mspeed != oldspeed && vis)
776 | pline("%s slows down.", Monnam(mdef));
777 | }
778 | break;
779 | case AD_CONF:
780 | /* Since confusing another monster doesn't have a real time
781 | * limit, setting spec_used would not really be right (though
782 | * we still should check for it).
783 | */
784 | if (!magr->mcan && !mdef->mconf && !magr->mspec_used) {
785 | if (vis) pline("%s looks confused.", Monnam(mdef));
786 | mdef->mconf = 1;
787 | }
788 | break;
789 | case AD_BLND:
790 | if (can_blnd(magr, mdef, mattk->aatyp, (struct obj*)0)) {
791 | register unsigned rnd_tmp;
792 |
793 | if (vis && mdef->mcansee)
794 | pline("%s is blinded.", Monnam(mdef));
795 | rnd_tmp = d((int)mattk->damn, (int)mattk->damd);
796 | if ((rnd_tmp += mdef->mblinded) > 127) rnd_tmp = 127;
797 | mdef->mblinded = rnd_tmp;
798 | mdef->mcansee = 0;
799 | }
800 | tmp = 0;
801 | break;
802 | case AD_HALU:
803 | if (!magr->mcan && haseyes(pd) && mdef->mcansee) {
804 | if (vis) pline("%s looks %sconfused.",
805 | Monnam(mdef), mdef->mconf ? "more " : "");
806 | mdef->mconf = 1;
807 | }
808 | tmp = 0;
809 | break;
810 | case AD_CURS:
811 | if (!night() && (pa == &mons[PM_GREMLIN])) break;
812 | if (!magr->mcan && !rn2(10)) {
813 | mdef->mcan = 1; /* cancelled regardless of lifesave */
814 | if (is_were(pd) && pd->mlet != S_HUMAN)
815 | were_change(mdef);
816 | if (pd == &mons[PM_CLAY_GOLEM]) {
817 | if (vis) {
818 | pline("Some writing vanishes from %s head!",
819 | s_suffix(mon_nam(mdef)));
820 | pline("%s is destroyed!", Monnam(mdef));
821 | }
822 | mondied(mdef);
823 | if (mdef->mhp > 0) return 0;
824 | else if (mdef->mtame && !vis)
825 | You(brief_feeling, "strangely sad");
826 | return (MM_DEF_DIED | (grow_up(magr,mdef) ?
827 | 0 : MM_AGR_DIED));
828 | }
829 | if (flags.soundok) {
830 | if (!vis) You_hear("laughter.");
831 | else pline("%s chuckles.", Monnam(magr));
832 | }
833 | }
834 | break;
835 | case AD_SGLD:
836 | tmp = 0;
837 | if (magr->mcan || !mdef->mgold) break;
838 | /* technically incorrect; no check for stealing gold from
839 | * between mdef's feet...
840 | */
841 | magr->mgold += mdef->mgold;
842 | mdef->mgold = 0;
843 | if (vis) {
844 | Strcpy(buf, Monnam(magr));
845 | pline("%s steals some gold from %s.", buf, mon_nam(mdef));
846 | }
847 | if (!tele_restrict(magr)) {
848 | rloc(magr);
849 | if (vis && !canspotmon(magr))
850 | pline("%s suddenly disappears!", buf);
851 | }
852 | break;
853 | case AD_DRLI:
854 | if (rn2(2) && !resists_drli(mdef)) {
855 | tmp = d(2,6);
856 | if (vis)
857 | pline("%s suddenly seems weaker!", Monnam(mdef));
858 | mdef->mhpmax -= tmp;
859 | if (mdef->m_lev == 0)
860 | tmp = mdef->mhp;
861 | else mdef->m_lev--;
862 | /* Automatic kill if drained past level 0 */
863 | }
864 | break;
865 | #ifdef SEDUCE
866 | case AD_SSEX:
867 | #endif
868 | case AD_SITM: /* for now these are the same */
869 | case AD_SEDU:
870 | if (!magr->mcan && mdef->minvent) {
871 | char onambuf[BUFSZ], mdefnambuf[BUFSZ];
872 |
873 | /* make a special x_monnam() call that never omits
874 | the saddle, and save it for later messages */
875 | Strcpy(mdefnambuf, x_monnam(mdef, ARTICLE_THE, (char *)0, 0, FALSE));
876 |
877 | otmp = mdef->minvent;
878 | #ifdef STEED
879 | if (u.usteed == mdef &&
880 | otmp == which_armor(mdef, W_SADDLE))
881 | /* "You can no longer ride <steed>." */
882 | dismount_steed(DISMOUNT_POLY);
883 | #endif
884 | obj_extract_self(otmp);
885 | if (otmp->owornmask) {
886 | mdef->misc_worn_check &= ~otmp->owornmask;
887 | otmp->owornmask = 0L;
888 | update_mon_intrinsics(mdef, otmp, FALSE);
889 | }
890 | /* add_to_minv() might free otmp [if it merges] */
891 | if (vis)
892 | Strcpy(onambuf, doname(otmp));
893 | (void) add_to_minv(magr, otmp);
894 | if (vis) {
895 | Strcpy(buf, Monnam(magr));
896 | pline("%s steals %s from %s!", buf,
897 | onambuf, mdefnambuf);
898 | }
899 | possibly_unwield(mdef);
900 | mselftouch(mdef, (const char *)0, FALSE);
901 | if (mdef->mhp <= 0)
902 | return (MM_DEF_DIED | (grow_up(magr,mdef) ?
903 | 0 : MM_AGR_DIED));
904 | if (magr->data->mlet == S_NYMPH &&
905 | !tele_restrict(magr)) {
906 | rloc(magr);
907 | if (vis && !canspotmon(magr))
908 | pline("%s suddenly disappears!", buf);
909 | }
910 | }
911 | tmp = 0;
912 | break;
913 | case AD_DRST:
914 | case AD_DRDX:
915 | case AD_DRCO:
916 | if (!magr->mcan && !rn2(8)) {
917 | if (vis)
918 | pline("%s %s was poisoned!", s_suffix(Monnam(magr)),
919 | mpoisons_subj(magr, mattk));
920 | if (resists_poison(mdef)) {
921 | if (vis)
922 | pline_The("poison doesn't seem to affect %s.",
923 | mon_nam(mdef));
924 | } else {
925 | if (rn2(10)) tmp += rn1(10,6);
926 | else {
927 | if (vis) pline_The("poison was deadly...");
928 | tmp = mdef->mhp;
929 | }
930 | }
931 | }
932 | break;
933 | case AD_DRIN:
934 | if (notonhead || !has_head(pd)) {
935 | if (vis) pline("%s doesn't seem harmed.", Monnam(mdef));
936 | tmp = 0;
937 | break;
938 | }
939 | if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) {
940 | if (vis) {
941 | Strcpy(buf, s_suffix(Monnam(mdef)));
942 | pline("%s helmet blocks %s attack to %s head.",
943 | buf, s_suffix(mon_nam(magr)),
944 | his[pronoun_gender(mdef)]);
945 | }
946 | break;
947 | }
948 | if (vis) pline("%s brain is eaten!", s_suffix(Monnam(mdef)));
949 | if (mindless(pd)) {
950 | if (vis) pline("%s doesn't notice.", Monnam(mdef));
951 | break;
952 | }
953 | tmp += rnd(10); /* fakery, since monsters lack INT scores */
954 | if (magr->mtame && !magr->isminion) {
955 | EDOG(magr)->hungrytime += rnd(60);
956 | magr->mconf = 0;
957 | }
958 | if (tmp >= mdef->mhp && vis)
959 | pline("%s last thought fades away...",
960 | s_suffix(Monnam(mdef)));
961 | break;
962 | case AD_SLIM:
963 | if (!rn2(4) && mdef->data != &mons[PM_FIRE_VORTEX] &&
964 | mdef->data != &mons[PM_FIRE_ELEMENTAL] &&
965 | mdef->data != &mons[PM_GREEN_SLIME]) {
966 | if (vis) pline("%s turns into slime.", Monnam(mdef));
967 | (void) newcham(mdef, &mons[PM_GREEN_SLIME]);
968 | tmp = 0;
969 | }
970 | break;
971 | case AD_STCK:
972 | case AD_WRAP: /* monsters cannot grab one another, it's too hard */
973 | case AD_ENCH: /* There's no msomearmor() function, so just do damage */
974 | break;
975 | default: tmp = 0;
976 | break;
977 | }
978 | if(!tmp) return(MM_MISS);
979 |
980 | if((mdef->mhp -= tmp) < 1) {
981 | if (m_at(mdef->mx, mdef->my) == magr) { /* see gulpmm() */
982 | remove_monster(mdef->mx, mdef->my);
983 | mdef->mhp = 1; /* otherwise place_monster will complain */
984 | place_monster(mdef, mdef->mx, mdef->my);
985 | mdef->mhp = 0;
986 | }
987 | monkilled(mdef, "", (int)mattk->adtyp);
988 | if (mdef->mhp > 0) return 0; /* mdef lifesaved */
989 | return (MM_DEF_DIED | (grow_up(magr,mdef) ? 0 : MM_AGR_DIED));
990 | }
991 | return(MM_HIT);
992 | }
993 |
994 | #endif /* OVLB */
995 |
996 |
997 | #ifdef OVL0
998 |
999 | int
1000 | noattacks(ptr) /* returns 1 if monster doesn't attack */
1001 | struct permonst *ptr;
1002 | {
1003 | int i;
1004 |
1005 | for(i = 0; i < NATTK; i++)
1006 | if(ptr->mattk[i].aatyp) return(0);
1007 |
1008 | return(1);
1009 | }
1010 |
1011 | /* `mon' is hit by a sleep attack; return 1 if it's affected, 0 otherwise */
1012 | int
1013 | sleep_monst(mon, amt, how)
1014 | struct monst *mon;
1015 | int amt, how;
1016 | {
1017 | if (resists_sleep(mon) ||
1018 | (how >= 0 && resist(mon, (char)how, 0, NOTELL))) {
1019 | shieldeff(mon->mx, mon->my);
1020 | } else if (mon->mcanmove) {
1021 | amt += (int) mon->mfrozen;
1022 | if (amt > 0) { /* sleep for N turns */
1023 | mon->mcanmove = 0;
1024 | mon->mfrozen = min(amt, 127);
1025 | } else { /* sleep until awakened */
1026 | mon->msleeping = 1;
1027 | }
1028 | return 1;
1029 | }
1030 | return 0;
1031 | }
1032 |
1033 | /* sleeping grabber releases, engulfer doesn't; don't use for paralysis! */
1034 | void
1035 | slept_monst(mon)
1036 | struct monst *mon;
1037 | {
1038 | if ((mon->msleeping || !mon->mcanmove) && mon == u.ustuck &&
1039 | !sticks(youmonst.data) && !u.uswallow) {
1040 | pline("%s grip relaxes.", s_suffix(Monnam(mon)));
1041 | unstuck(mon);
1042 | }
1043 | }
1044 |
1045 | #endif /* OVL0 */
1046 | #ifdef OVLB
1047 |
1048 | STATIC_OVL void
1049 | mrustm(magr, mdef, obj)
1050 | register struct monst *magr, *mdef;
1051 | register struct obj *obj;
1052 | {
1053 | boolean is_acid;
1054 |
1055 | if (!magr || !mdef || !obj) return; /* just in case */
1056 |
1057 | if (dmgtype(mdef->data, AD_CORRODE))
1058 | is_acid = TRUE;
1059 | else if (dmgtype(mdef->data, AD_RUST))
1060 | is_acid = FALSE;
1061 | else
1062 | return;
1063 |
1064 | if (!mdef->mcan &&
1065 | (is_acid ? is_corrodeable(obj) : is_rustprone(obj)) &&
1066 | (is_acid ? obj->oeroded2 : obj->oeroded) < MAX_ERODE) {
1067 | if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) {
1068 | if (cansee(mdef->mx, mdef->my) && flags.verbose)
1069 | pline("%s weapon is not affected.",
1070 | s_suffix(Monnam(magr)));
1071 | if (obj->greased && !rn2(2)) obj->greased = 0;
1072 | } else {
1073 | if (cansee(mdef->mx, mdef->my)) {
1074 | pline("%s %s%s!", s_suffix(Monnam(magr)),
1075 | aobjnam(obj, (is_acid ? "corrode" : "rust")),
1076 | (is_acid ? obj->oeroded2 : obj->oeroded)
1077 | ? " further" : "");
1078 | }
1079 | if (is_acid) obj->oeroded2++;
1080 | else obj->oeroded++;
1081 | }
1082 | }
1083 | }
1084 |
1085 | STATIC_OVL void
1086 | mswingsm(magr, mdef, otemp)
1087 | register struct monst *magr, *mdef;
1088 | register struct obj *otemp;
1089 | {
1090 | char buf[BUFSZ];
1091 | Strcpy(buf, mon_nam(mdef));
1092 | if (!flags.verbose || Blind) return;
1093 | pline("%s %s %s %s at %s.", Monnam(magr),
1094 | (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",
1095 | his[pronoun_gender(magr)], xname(otemp), buf);
1096 | }
1097 |
1098 | /*
1099 | * Passive responses by defenders. Does not replicate responses already
1100 | * handled above. Returns same values as mattackm.
1101 | */
1102 | STATIC_OVL int
1103 | passivemm(magr,mdef,mhit,mdead)
1104 | register struct monst *magr, *mdef;
1105 | boolean mhit;
1106 | int mdead;
1107 | {
1108 | register struct permonst *mddat = mdef->data;
1109 | register struct permonst *madat = magr->data;
1110 | char buf[BUFSZ];
1111 | int i, tmp;
1112 |
1113 | for(i = 0; ; i++) {
1114 | if(i >= NATTK) return (mdead | mhit); /* no passive attacks */
1115 | if(mddat->mattk[i].aatyp == AT_NONE) break;
1116 | }
1117 | if (mddat->mattk[i].damn)
1118 | tmp = d((int)mddat->mattk[i].damn,
1119 | (int)mddat->mattk[i].damd);
1120 | else if(mddat->mattk[i].damd)
1121 | tmp = d((int)mddat->mlevel+1, (int)mddat->mattk[i].damd);
1122 | else
1123 | tmp = 0;
1124 |
1125 | /* These affect the enemy even if defender killed */
1126 | switch(mddat->mattk[i].adtyp) {
1127 | case AD_ACID:
1128 | if (mhit && !rn2(2)) {
1129 | Strcpy(buf, Monnam(magr));
1130 | if(canseemon(magr))
1131 | pline("%s is splashed by %s acid!",
1132 | buf, s_suffix(mon_nam(mdef)));
1133 | if (resists_acid(magr)) {
1134 | if(canseemon(magr))
1135 | pline("%s is not affected.", Monnam(magr));
1136 | tmp = 0;
1137 | }
1138 | } else tmp = 0;
1139 | goto assess_dmg;
1140 | case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
1141 | if (mhit && !mdef->mcan && otmp) {
1142 | (void) drain_item(otmp);
1143 | /* No message */
1144 | }
1145 | break;
1146 | default:
1147 | break;
1148 | }
1149 | if (mdead || mdef->mcan) return (mdead|mhit);
1150 |
1151 | /* These affect the enemy only if defender is still alive */
1152 | if (rn2(3)) switch(mddat->mattk[i].adtyp) {
1153 | case AD_PLYS: /* Floating eye */
1154 | if (tmp > 127) tmp = 127;
1155 | if (mddat == &mons[PM_FLOATING_EYE]) {
1156 | if (!rn2(4)) tmp = 127;
1157 | if (magr->mcansee && haseyes(madat) && mdef->mcansee &&
1158 | (perceives(madat) || !mdef->minvis)) {
1159 | Sprintf(buf, "%s gaze is reflected by %%s %%s.",
1160 | s_suffix(mon_nam(mdef)));
1161 | if (mon_reflects(magr,
1162 | canseemon(magr) ? buf : (char *)0))
1163 | return(mdead|mhit);
1164 | Strcpy(buf, Monnam(magr));
1165 | if(canseemon(magr))
1166 | pline("%s is frozen by %s gaze!",
1167 | buf, s_suffix(mon_nam(mdef)));
1168 | magr->mcanmove = 0;
1169 | magr->mfrozen = tmp;
1170 | return (mdead|mhit);
1171 | }
1172 | } else { /* gelatinous cube */
1173 | Strcpy(buf, Monnam(magr));
1174 | if(canseemon(magr))
1175 | pline("%s is frozen by %s.", buf, mon_nam(mdef));
1176 | magr->mcanmove = 0;
1177 | magr->mfrozen = tmp;
1178 | return (mdead|mhit);
1179 | }
1180 | return 1;
1181 | case AD_COLD:
1182 | if (resists_cold(magr)) {
1183 | if (canseemon(magr)) {
1184 | pline("%s is mildly chilly.", Monnam(magr));
1185 | golemeffects(magr, AD_COLD, tmp);
1186 | }
1187 | tmp = 0;
1188 | break;
1189 | }
1190 | if(canseemon(magr))
1191 | pline("%s is suddenly very cold!", Monnam(magr));
1192 | mdef->mhp += tmp / 2;
1193 | if (mdef->mhpmax < mdef->mhp) mdef->mhpmax = mdef->mhp;
1194 | if (mdef->mhpmax > ((int) (mdef->m_lev+1) * 8))
1195 | (void)split_mon(mdef, magr);
1196 | break;
1197 | case AD_STUN:
1198 | if (!magr->mstun) {
1199 | magr->mstun = 1;
1200 | if (canseemon(magr))
1201 | pline("%s staggers...", Monnam(magr));
1202 | }
1203 | tmp = 0;
1204 | break;
1205 | case AD_FIRE:
1206 | if (resists_fire(magr)) {
1207 | if (canseemon(magr)) {
1208 | pline("%s is mildly warmed.", Monnam(magr));
1209 | golemeffects(magr, AD_FIRE, tmp);
1210 | }
1211 | tmp = 0;
1212 | break;
1213 | }
1214 | if(canseemon(magr))
1215 | pline("%s is suddenly very hot!", Monnam(magr));
1216 | break;
1217 | case AD_ELEC:
1218 | if (resists_elec(magr)) {
1219 | if (canseemon(magr)) {
1220 | pline("%s is mildly tingled.", Monnam(magr));
1221 | golemeffects(magr, AD_ELEC, tmp);
1222 | }
1223 | tmp = 0;
1224 | break;
1225 | }
1226 | if(canseemon(magr))
1227 | pline("%s is jolted with electricity!", Monnam(magr));
1228 | break;
1229 | default: tmp = 0;
1230 | break;
1231 | }
1232 | else tmp = 0;
1233 |
1234 | assess_dmg:
1235 | if((magr->mhp -= tmp) <= 0) {
1236 | monkilled(magr, "", (int)mddat->mattk[i].adtyp);
1237 | return (mdead | mhit | MM_AGR_DIED);
1238 | }
1239 | return (mdead | mhit);
1240 | }
1241 |
1242 | #endif /* OVLB */
1243 |
1244 | /*mhitm.c*/
1245 |