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 *
mon_nam_too(outbuf,mon,other_mon)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
noises(magr,mattk)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
missmm(magr,mdef,mattk)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
fightm(mtmp)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
mattackm(magr,mdef)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
hitmm(magr,mdef,mattk)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
gazemm(magr,mdef,mattk)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
gulpmm(magr,mdef,mattk)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
explmm(magr,mdef,mattk)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
mdamagem(magr,mdef,mattk)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
noattacks(ptr)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
sleep_monst(mon,amt,how)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
slept_monst(mon)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
mrustm(magr,mdef,obj)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
mswingsm(magr,mdef,otemp)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
passivemm(magr,mdef,mhit,mdead)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 
1246