Fandom

Wikihack

Source:NetHack 3.0.0/uhitm.c

2,034pages on
this wiki
Add New Page
Talk0

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Below is the full text to uhitm.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/uhitm.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

The NetHack General Public License applies to screenshots, source code and other content from NetHack.
1.    /*	SCCS Id: @(#)uhitm.c	3.0	88/04/11
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include	"hack.h"
6.    #ifdef NAMED_ITEMS
7.    #  include "artifact.h"
8.    #endif
9.    
10.   static boolean hitum();
11.   #ifdef POLYSELF
12.   static boolean hmonas();
13.   #endif
14.   static int passive();
15.   
16.   #ifdef WORM
17.   extern boolean notonhead;
18.   #endif
19.   
20.   struct monst *
21.   clone_mon(mon)
22.   struct monst *mon;
23.   {
24.   	coord mm;
25.   	struct monst *m2;
26.   
27.   	mm.x = mon->mx;
28.   	mm.y = mon->my;
29.   	enexto(&mm, mm.x, mm.y);
30.   	if (levl[mm.x][mm.y].mmask || mon->mhp <= 1) return (struct monst *)0;
31.   	m2 = newmonst(0);
32.   	*m2 = *mon;			/* copy condition of old monster */
33.   	m2->nmon = fmon;
34.   	fmon = m2;
35.   	m2->m_id = flags.ident++;
36.   	m2->mx = mm.x;
37.   	m2->my = mm.y;
38.   
39.   	m2->minvent = (struct obj *) 0; /* objects don't clone */
40.   	m2->mleashed = FALSE;
41.   	m2->mgold = 0L;
42.   	/* Max HP the same, but current HP halved for both.  The caller
43.   	 * might want to override this by halving the max HP also.
44.   	 */
45.   	m2->mhpmax = mon->mhpmax;
46.   	m2->mhp = mon->mhp /= 2;
47.   
48.   	/* since shopkeepers and guards will only be cloned if they've been
49.   	 * polymorphed away from their original forms, the clone doesn't have
50.   	 * room for the extra information.  we also don't want two shopkeepers
51.   	 * around for the same shop.
52.   	 * similarly, clones of named monsters don't have room for the name,
53.   	 * so we just make the clone unnamed instead of bothering to create
54.   	 * a clone with room and copying over the name from the right place
55.   	 * (which changes if the original was a shopkeeper or guard).
56.   	 */
57.   	if (mon->isshk) m2->isshk = FALSE;
58.   	if (mon->isgd) m2->isgd = FALSE;
59.   #if defined(ALTARS) && defined(THEOLOGY)
60.   	if (mon->ispriest) m2->ispriest = FALSE;
61.   #endif
62.   	m2->mxlth = 0;
63.   	m2->mnamelth = 0;
64.   	m2->mdispl = 0;
65.   	pmon(m2);	/* display the new monster */
66.   	levl[m2->mx][m2->my].mmask = 1;
67.   	if (mon->mtame) (void) tamedog(m2, (struct obj *)0);
68.   	return m2;
69.   }
70.   
71.   boolean
72.   special_case(mtmp)
73.   /* Moved this code from attack() in order to 	*/
74.   /* avoid having to duplicate it in dokick.	*/
75.   register struct monst *mtmp;
76.   {
77.   	if (flags.confirm && (mtmp->mpeaceful || mtmp->mtame) && !Confusion
78.   	    && !Hallucination && (!mtmp->mhide || !mtmp->mundetected)
79.   	    && (!mtmp->mimic || Protection_from_shape_changers)) {
80.   		if (Blind ? Telepat : (!mtmp->minvis || See_invisible)) {
81.   			pline("Really attack %s? ", mon_nam(mtmp));
82.   			(void) fflush(stdout);
83.   			if (yn() != 'y') {
84.   				flags.move = 0;
85.   				return(TRUE);
86.   			}
87.   		}
88.   	}
89.   
90.   	if(mtmp->mimic && !Protection_from_shape_changers) {
91.   		if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK))
92.   			u.ustuck = mtmp;
93.   		if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == DOOR_SYM)
94.   #ifdef SPELLS
95.   		{
96.   		    if (okdoor(u.ux+u.dx, u.uy+u.dy))
97.   #endif
98.   			pline("The door actually was %s.", defmonnam(mtmp));
99.   #ifdef SPELLS
100.  		    else
101.  			pline("That spellbook was %s.", defmonnam(mtmp));
102.  		}
103.  #endif
104.  		else if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == GOLD_SYM)
105.  			pline("That gold was %s!", defmonnam(mtmp));
106.  		else
107.  			pline("Wait!  That's %s!", defmonnam(mtmp));
108.  		wakeup(mtmp);	/* clears mtmp->mimic */
109.  		return(TRUE);
110.  	}
111.  
112.  	if(mtmp->mhide && mtmp->mundetected && !canseemon(mtmp)) {
113.  		mtmp->mundetected = 0;
114.  		if (!(Blind ? Telepat : (HTelepat & WORN_HELMET))) {
115.  		    register struct obj *obj;
116.  
117.  		    if(levl[mtmp->mx][mtmp->my].omask == 1) {
118.  			if(obj = o_at(mtmp->mx,mtmp->my))
119.  				pline("Wait!  There's %s hiding under %s!",
120.  					defmonnam(mtmp), doname(obj));
121.  		    } else if (levl[mtmp->mx][mtmp->my].gmask == 1)
122.  				pline("Wait!  There's %s hiding under some gold!",
123.  					defmonnam(mtmp));
124.  		    wakeup(mtmp);
125.  		    return(TRUE);
126.  		}
127.  	}
128.  	return(FALSE);
129.  }
130.  
131.  
132.  /* try to attack; return FALSE if monster evaded */
133.  /* u.dx and u.dy must be set */
134.  boolean
135.  attack(mtmp)
136.  register struct monst *mtmp;
137.  {
138.  	schar tmp = 0;
139.  	register struct permonst *mdat = mtmp->data;
140.  
141.  	if(unweapon) {
142.  	    unweapon=FALSE;
143.  	    if(flags.verbose)
144.  		if(uwep)
145.  		    You("begin bashing monsters with your %s.",
146.  			aobjnam(uwep, NULL));
147.  		else
148.  #ifdef POLYSELF
149.  		    if (!cantwield(uasmon))
150.  #endif
151.  		    You("begin bashing monsters with your %s hands.",
152.  			uarmg ? "gloved" : "bare");		/* Del Lamb */
153.  	}
154.  	/* andrew@orca: prevent unlimited pick-axe attacks */
155.  	u_wipe_engr(3);
156.  
157.  	if(mdat->mlet == S_LEPRECHAUN && !mtmp->mfroz && !mtmp->msleep &&
158.  	   !mtmp->mconf && mtmp->mcansee && !rn2(7) &&
159.  	   (m_move(mtmp, 0) == 2 ||			    /* he died */
160.  	   mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) /* he moved */
161.  		return(FALSE);
162.  
163.  	/* This section of code provides protection against accidentally
164.  	 * hitting peaceful (like '@') and tame (like 'd') monsters.
165.  	 * There is protection only if you're not blind, confused, or hallu-
166.  	 * cinating.
167.  	 */
168.  	/*  changes by wwp 5/16/85 */
169.  	if (!Blind && !Confusion && !Hallucination && flags.safe_dog &&
170.  	    (mdat->mlet == S_DOG || mdat->mlet == S_FELINE) && mtmp->mtame) {
171.  		mtmp->mflee = 1;
172.  		mtmp->mfleetim = rnd(6);
173.  		if (mtmp->mnamelth)
174.  		    You("stop to avoid hitting %s.", NAME(mtmp));
175.  		else
176.  		    You("stop to avoid hitting your %s.",
177.  			  mdat->mname);
178.  		return(TRUE);
179.  	}
180.  
181.  	/* moved code to a separate function to share with dokick */
182.  	if(special_case(mtmp)) return(TRUE);
183.  
184.  #ifdef POLYSELF
185.  	if(u.umonnum >= 0) {	/* certain "pacifist" monsters don't attack */
186.  		set_uasmon();
187.  		if(noattacks(uasmon)) {
188.  			You("have no way to attack monsters physically.");
189.  			return(TRUE);
190.  		}
191.  	}
192.  	tmp = Luck + mdat->ac + abon() +
193.  		     ((u.umonnum >= 0) ? uasmon->mlevel : u.ulevel);
194.  #else
195.  	tmp = Luck + u.ulevel + mdat->ac + abon();
196.  #endif
197.  
198.  /*	it is unchivalrous to attack the defenseless or from behind */
199.  	if (pl_character[0] == 'K' && u.ualigntyp == U_LAWFUL &&
200.  	    (mtmp->mfroz || mtmp->msleep || mtmp->mflee) &&
201.  	    u.ualign > -10) adjalign(-1);
202.  
203.  /*	Adjust vs. (and possibly modify) monster state.		*/
204.  
205.  	if(mtmp->mstun) tmp += 2;
206.  	if(mtmp->mflee) tmp += 2;
207.  
208.  	if(mtmp->msleep) {
209.  		mtmp->msleep = 0;
210.  		tmp += 2;
211.  	}
212.  	if(mtmp->mfroz) {
213.  		tmp += 4;
214.  		if(!rn2(10)) mtmp->mfroz = 0;
215.  	}
216.  	if (is_orc(mtmp->data) && pl_character[0]=='E') tmp++;
217.  
218.  /*	with a lot of luggage, your agility diminishes */
219.  	tmp -= (inv_weight() + 40)/20;
220.  	if(u.utrap) tmp -= 3;
221.  
222.  #ifdef POLYSELF
223.  	if(u.umonnum >= 0) (void) hmonas(mtmp, tmp);
224.  	else {
225.  #endif
226.  		if(uwep) tmp += hitval(uwep, mdat);
227.  		(void) hitum(mtmp, tmp);
228.  #ifdef POLYSELF
229.  	}
230.  #endif
231.  
232.  	return(TRUE);
233.  }
234.  
235.  static boolean
236.  known_hitum(mon, mhit)	/* returns TRUE if monster still lives */
237.  /* Made into a separate function because in some cases we want to know
238.   * in the calling function whether we hit.
239.   */
240.  register struct monst *mon;
241.  register int mhit;
242.  {
243.  	register boolean malive = TRUE;
244.  
245.  	stoned = FALSE;		/* this refers to the thing hit, not you */
246.  
247.  	if(!mhit) {
248.  	    if(!Blind && flags.verbose) You("miss %s.", mon_nam(mon));
249.  	    else			You("miss it.");
250.  	    if(is_human(mon->data) && !(mon->msleep || mon->mfroz))
251.  		wakeup(mon);
252.  	} else {
253.  	    /* we hit the monster; be careful: it might die! */
254.  
255.  #ifdef WORM
256.  	    if (mon->mx != u.ux+u.dx || mon->my != u.uy+u.dy)
257.  		notonhead = TRUE;
258.  #endif
259.  	    if((malive = hmon(mon, uwep, 0)) == TRUE) {
260.  		/* monster still alive */
261.  		if(!rn2(25) && mon->mhp < mon->mhpmax/2) {
262.  			mon->mflee = 1;
263.  			if(!rn2(3)) mon->mfleetim = rnd(100);
264.  			if(u.ustuck == mon && !u.uswallow
265.  #ifdef POLYSELF
266.  						&& !sticks(uasmon)
267.  #endif
268.  								)
269.  				u.ustuck = 0;
270.  		}
271.  #ifdef WORM
272.  		if(mon->wormno)
273.  		    cutworm(mon, u.ux+u.dx, u.uy+u.dy,
274.  			    uwep ? uwep->otyp : 0);
275.  #endif
276.  	    }
277.  #if defined(ALTARS) && defined(THEOLOGY)
278.  	    if(mon->ispriest && !rn2(2)) ghod_hitsu();
279.  #endif
280.  	}
281.  	return(malive);
282.  }
283.  
284.  static boolean
285.  hitum(mon, tmp)		/* returns TRUE if monster still lives */
286.  struct monst *mon;
287.  int tmp;
288.  {
289.  	static int malive;
290.  	boolean mhit = !((tmp <= rnd(20)) && !u.uswallow);
291.  
292.  	malive = known_hitum(mon, mhit);
293.  	(void) passive(mon, mhit, malive);
294.  	return(malive);
295.  }
296.  
297.  boolean			/* general "damage monster" routine */
298.  hmon(mon, obj, thrown)		/* return TRUE if mon still alive */
299.  register struct monst *mon;
300.  register struct obj *obj;
301.  register int thrown;
302.  {
303.  	register int tmp;
304.  	boolean hittxt = FALSE;
305.  	boolean get_dmg_bonus = TRUE;
306.  	boolean ispoisoned = FALSE;
307.  
308.  	wakeup(mon);
309.  	if(!obj) {
310.  	    tmp = rnd(2);	/* attack with bare hands */
311.  	    if(mon->data == &mons[PM_COCKATRICE] && !uarmg
312.  #ifdef POLYSELF
313.  		&& !resists_ston(uasmon)
314.  #endif
315.  		) {
316.  
317.  		kludge("You hit %s with your bare %s.",
318.  			mon_nam(mon), makeplural(body_part(HAND)));
319.  		You("turn to stone...");
320.  		done_in_by(mon);
321.  	    }
322.  	} else {
323.  	    if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE ||
324.  	       obj->olet == ROCK_SYM) {
325.  
326.  		if(mon->data == &mons[PM_RUST_MONSTER] && obj == uwep &&
327.  			objects[obj->otyp].oc_material == METAL &&
328.  			obj->spe > -2) {
329.  		    if(obj->rustfree) {
330.  			pline("The rust on your %s vanishes instantly!",
331.  			      is_sword(obj) ? "sword" : "weapon");
332.  		    } else if(obj->blessed && rnl(4))
333.  			pline("Somehow your %s is not affected!",
334.  			      is_sword(obj) ? "sword" : "weapon");
335.  		    else {
336.  		    	Your("%s!", aobjnam(uwep, "corrode"));
337.  		    	uwep->spe--;
338.  		    }
339.  		}
340.  
341.  		if(obj == uwep && (obj->otyp > VOULGE || obj->otyp < BOOMERANG)
342.  				&& obj->otyp != PICK_AXE)
343.  		    tmp = rnd(2);
344.  		else {
345.  		    tmp = dmgval(obj, mon->data);
346.  #ifdef NAMED_ITEMS
347.  		    if(spec_ability(obj, SPFX_DRLI) &&
348.  						!resists_drli(mon->data)) {
349.  			if (!Blind) {
350.  			    pline("The %s blade draws the life from %s!",
351.  				Hallucination ? hcolor() : black,
352.  				mon_nam(mon));
353.  			    hittxt = TRUE;
354.  			}
355.  			if (mon->m_lev == 0) tmp = mon->mhp;
356.  			else {
357.  			    int drain = rnd(8);
358.  			    tmp += drain;
359.  			    mon->mhpmax -= drain;
360.  			    mon->m_lev--;
361.  			}
362.  		    }
363.  #endif
364.  		    if(!thrown && obj == uwep && obj->otyp == BOOMERANG &&
365.  		       !rnl(3)) {
366.  			kludge("As you hit %s, the boomerang breaks into splinters.",
367.  			      mon_nam(mon));
368.  			useup(obj);
369.  			hittxt = TRUE;
370.  			tmp++;
371.  		    }
372.  		    if(thrown && (obj->otyp >= ARROW && obj->otyp <= SHURIKEN)){
373.  			if(((uwep && objects[obj->otyp].w_propellor ==
374.  				-objects[uwep->otyp].w_propellor)
375.  				|| obj->otyp==DART || obj->otyp==SHURIKEN) &&
376.  				obj->opoisoned)
377.  			    ispoisoned = TRUE;
378.  		    }
379.  		}
380.  	    } else if(obj->olet == POTION_SYM) {
381.  			if (obj->quan > 1) setuwep(splitobj(obj, 1));
382.  			else setuwep((struct obj *)0);
383.  			freeinv(obj);
384.  			potionhit(mon,obj);
385.  			hittxt = TRUE;
386.  			tmp = 1;
387.  	    } else	switch(obj->otyp) {
388.  		case HEAVY_IRON_BALL:
389.  			tmp = rnd(25); break;
390.  		case BOULDER:
391.  			tmp = rnd(20); break;
392.  #ifdef MEDUSA
393.  		case MIRROR:
394.  			You("break your mirror.  That's bad luck!");
395.  			change_luck(-2);
396.  			useup(obj);
397.  			return(TRUE);
398.  #endif
399.  		case EXPENSIVE_CAMERA:
400.  	You("succeed in destroying your camera.  Congratulations!");
401.  			useup(obj);
402.  			return(TRUE);
403.  		case CORPSE:		/* fixed by polder@cs.vu.nl */
404.  			if(obj->corpsenm == PM_COCKATRICE) {
405.  			    kludge("You hit %s with the cockatrice corpse.",
406.  				  mon_nam(mon));
407.  			    if(resists_ston(mon->data)) {
408.  				tmp = 1;
409.  				hittxt = TRUE;
410.  				break;
411.  			    }
412.  			    kludge("%s turns to stone.", Monnam(mon));
413.  			    stoned = TRUE;
414.  			    xkilled(mon,0);
415.  			    return(FALSE);
416.  			}
417.  			tmp = bigmonst(&mons[obj->corpsenm]) ? 5 : 2 ;
418.  			break;
419.  		case EGG: /* only possible if hand-to-hand */
420.  			if(obj->corpsenm > -1
421.  					&& obj->corpsenm != PM_COCKATRICE
422.  					&& mon->data==&mons[PM_COCKATRICE]) {
423.  				kludge("You hit %s with the %s egg%s.",
424.  					mon_nam(mon),
425.  					mons[obj->corpsenm].mname,
426.  					(obj->quan==1) ? "" : "s");
427.  				hittxt = TRUE;
428.  				pline("The egg%sn't live any more...",
429.  					(obj->quan==1) ? " is" : "s are");
430.  				obj->otyp = ROCK;
431.  				obj->olet = GEM_SYM;
432.  				obj->known = obj->dknown = 0;
433.  				obj->owt = weight(obj);
434.  			}
435.  			tmp = 1;
436.  			break;
437.  		case CLOVE_OF_GARLIC:		/* no effect against demons */
438.  			if(is_undead(mon->data)) mon->mflee = 1;
439.  			tmp = 1;
440.  			break;
441.  		case CREAM_PIE:
442.  #ifdef POLYSELF
443.  		case BLINDING_VENOM:
444.  			if(Blind)
445.  			    pline(obj->otyp==CREAM_PIE ? "Splat!" : "Splash!");
446.  			else if (obj->otyp == BLINDING_VENOM)
447.  			    pline("The venom blinds %s%s!", mon_nam(mon),
448.  					mon->mcansee ? "" : " further");
449.  #else
450.  			if(Blind) pline("Splat!");
451.  #endif
452.  			else
453.  			    pline("The cream pie splashes over %s%s!",
454.  				mon_nam(mon),
455.  				(haseyes(mon->data) &&
456.  					mon->data != &mons[PM_FLOATING_EYE])
457.  				? "'s face" : "");
458.  			if(mon->msleep) mon->msleep = 0;
459.  			setmangry(mon);
460.  			mon->mcansee = 0;
461.  			if((mon->mblinded + tmp) > 127) mon->mblinded = 127;
462.  			else mon->mblinded += tmp;
463.  			hittxt = TRUE;
464.  			get_dmg_bonus = FALSE;
465.  			tmp = 0;
466.  			break;
467.  #ifdef POLYSELF
468.  		case ACID_VENOM: /* only possible if thrown */
469.  			if(resists_acid(mon->data)) {
470.  				kludge("Your venom hits %s harmlessly.",
471.  					mon_nam(mon));
472.  				tmp = 0;
473.  			} else {
474.  				kludge("Your venom burns %s!", mon_nam(mon));
475.  				tmp = dmgval(obj, mon->data);
476.  			}
477.  			hittxt = TRUE;
478.  			get_dmg_bonus = FALSE;
479.  			break;
480.  #endif
481.  		default:
482.  			/* non-weapons can damage because of their weight */
483.  			/* (but not too much) */
484.  			tmp = obj->owt/10;
485.  			if(tmp < 1) tmp = 1;
486.  			else tmp = rnd(tmp);
487.  			if(tmp > 6) tmp = 6;
488.  	    }
489.  	}
490.  
491.  	/****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG)
492.  	 *      *OR* if attacking bare-handed!! */
493.  
494.  	if (get_dmg_bonus) {
495.  		tmp += u.udaminc;
496.  		/* If you throw using a propellor, you don't get a strength
497.  		 * bonus but you do get an increase-damage bonus.
498.  		 */
499.  		if(!obj || !uwep ||
500.  			(obj->olet != GEM_SYM && obj->olet != WEAPON_SYM) ||
501.  			objects[obj->otyp].w_propellor !=
502.  				-objects[uwep->otyp].w_propellor)
503.  		    tmp += dbon();
504.  	}
505.  
506.  /* TODO:	Fix this up.  multiple engulf attacks now exist.
507.  	if(u.uswallow) {
508.  	    if((tmp -= u.uswldtim) <= 0) {
509.  		Your("%s are no longer able to hit.",
510.  			makeplural(body_part(ARM)));
511.  		return(TRUE);
512.  	    }
513.  	}
514.   */
515.  	if (ispoisoned) {
516.  	    /* OK to reference obj because ispoisoned can only be set
517.  	     * when obj is a throwing weapon */
518.  	    hit(xname(obj), mon, exclam(tmp));
519.  	    hittxt = TRUE;
520.  	    if(resists_poison(mon->data))
521.  		kludge("The poison doesn't seem to affect %s.", mon_nam(mon));
522.  	    else if (rn2(10))
523.  		tmp += rnd(6);
524.  	    else {
525.  		pline("The poison was deadly...");
526.  		xkilled(mon,0);
527.  		return FALSE;
528.  	    }
529.  	}
530.  	if(tmp < 1) tmp = 1;
531.  
532.  	mon->mhp -= tmp;
533.  	if(mon->mhp < 1) {
534.  		killed(mon);
535.  		return(FALSE);
536.  	}
537.  	if(mon->mtame && (!mon->mflee || mon->mfleetim)) {
538.  #ifdef SOUNDS
539.  		if (rn2(8)) yelp(mon);
540.  		else growl(mon); /* give them a moment's worry */
541.  #endif
542.  		mon->mtame--;
543.  		mon->mflee = 1;			/* Rick Richardson */
544.  		mon->mfleetim += 10*rnd(tmp);
545.  	}
546.  	if((mon->data == &mons[PM_BLACK_PUDDING] ||
547.  		   mon->data == &mons[PM_BROWN_PUDDING]) && uwep &&
548.  		   uwep == obj && objects[obj->otyp].oc_material == METAL
549.  		   && mon->mhp > 1 && !thrown && !mon->mcan) {
550.  
551.  		if (clone_mon(mon)) {
552.  			pline("%s divides as you hit it!", Monnam(mon));
553.  			hittxt = TRUE;
554.  		}
555.  	}
556.  
557.  	if(!hittxt) {
558.  		if(thrown)
559.  		    /* thrown => obj exists */
560.  		    hit(xname(obj), mon, exclam(tmp) );
561.  		else if(Blind || !flags.verbose) You("hit it.");
562.  		else	You("hit %s%s", mon_nam(mon), exclam(tmp));
563.  	}
564.  
565.  	if(u.umconf && !thrown) {
566.  		if(!Blind) {
567.  			Your("%s stop glowing %s.",
568.  			makeplural(body_part(HAND)),
569.  			Hallucination ? hcolor() : red);
570.  		}
571.  		if(!resist(mon, '+', 0, NOTELL)) mon->mconf = 1;
572.  		if(!mon->mstun && !mon->mfroz && !mon->msleep &&
573.  		   !Blind && mon->mconf)
574.  			pline("%s appears confused.", Monnam(mon));
575.  		u.umconf = 0;
576.  	}
577.  	return(TRUE);	/* mon still alive */
578.  }
579.  
580.  #ifdef POLYSELF
581.  static int
582.  damageum(mdef, mattk)
583.  register struct monst *mdef;
584.  register struct attack *mattk;
585.  {
586.  	register struct permonst *pd = mdef->data;
587.  	register int	tmp = d((int)mattk->damn, (int)mattk->damd);
588.  
589.  	stoned = FALSE;
590.  	if (is_demon(uasmon) && !rn2(13) && !uwep
591.  #ifdef HARD
592.  		&& u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
593.  		&& u.umonnum != PM_BALROG
594.  #endif
595.  	    ) {
596.  	    struct monst *dtmp;
597.  	    pline("Some hell-p has arrived!");
598.  /*	    if((dtmp = mkmon_at(uasmon, u.ux, u.uy)))*/
599.  /*	    if((dtmp = makemon(uasmon, u.ux, u.uy)))*/
600.  	    if((dtmp = makemon(&mons[ndemon()], u.ux, u.uy)))
601.  		(void)tamedog(dtmp, (struct obj *)0);
602.  	    return(0);
603.  	}
604.  
605.  	switch(mattk->adtyp) {
606.  	    case AD_STUN:
607.  		if(!Blind)
608.  		    pline("%s staggers for a moment.", Monnam(mdef));
609.  		mdef->mstun = 1;
610.  		/* fall through to next case */
611.  	    case AD_WERE:	    /* no effect on monsters */
612.  	    case AD_PHYS:
613.  		if(mattk->aatyp == AT_WEAP) {
614.  			if(uwep) tmp = 0;
615.  		} else if(mattk->aatyp == AT_KICK)
616.  			if(thick_skinned(mdef->data)) tmp = 0;
617.  		break;
618.  	    case AD_FIRE:
619.  #ifdef GOLEMS
620.  		golemeffects(mdef, AD_FIRE, tmp);
621.  #endif /* GOLEMS */
622.  		if(resists_fire(pd)) {
623.  		    shieldeff(mdef->mx, mdef->my);
624.  		    tmp = 0;
625.  		} else {
626.  		    if(!Blind) pline("%s is on fire!", Monnam(mdef));
627.  		    tmp += destroy_mitem(mdef, SCROLL_SYM, AD_FIRE);
628.  		    tmp += destroy_mitem(mdef, POTION_SYM, AD_FIRE);
629.  #ifdef SPELLS
630.  		    tmp += destroy_mitem(mdef, SPBOOK_SYM, AD_FIRE);
631.  #endif
632.  		}
633.  		break;
634.  	    case AD_COLD:
635.  #ifdef GOLEMS
636.  		golemeffects(mdef, AD_COLD, tmp);
637.  #endif /* GOLEMS */
638.  		if(resists_cold(pd)) {
639.  		    shieldeff(mdef->mx, mdef->my);
640.  		    tmp = 0;
641.  		} else {
642.  		    if(!Blind) pline("%s is covered in frost.", Monnam(mdef));
643.  		    tmp += destroy_mitem(mdef, POTION_SYM, AD_COLD);
644.  		}
645.  		break;
646.  	    case AD_ELEC:
647.  #ifdef GOLEMS
648.  		golemeffects(mdef, AD_ELEC, tmp);
649.  #endif /* GOLEMS */
650.  		if(resists_elec(pd)) {
651.  		    shieldeff(mdef->mx, mdef->my);
652.  		    tmp = 0;
653.  		}
654.  		break;
655.  	    case AD_ACID:
656.  		if(resists_acid(pd)) tmp = 0;
657.  		break;
658.  	    case AD_STON:
659.  		if(!resists_ston(pd)) {
660.  		    stoned = TRUE;
661.  		    if(!Blind) pline("%s turns to stone.", Monnam(mdef));
662.  		    xkilled(mdef, 0);
663.  		    return(2);
664.  		}
665.  		tmp = 0;	/* no damage if this fails */
666.  		break;
667.  #ifdef SEDUCE
668.  	    case AD_SSEX:
669.  #endif
670.  	    case AD_SEDU:
671.  	    case AD_SITM:
672.  		if(mdef->minvent) {
673.  		    struct obj *otmp, *addinv(), *stealoid;
674.  		    int isize = inv_cnt();
675.  
676.  		    stealoid = (struct obj *)0;
677.  		    if (is_mercenary(pd)) {
678.  			for(otmp = mdef->minvent; otmp; otmp=otmp->nobj)
679.  			    if (otmp->otyp >= PLATE_MAIL && otmp->otyp
680.  				<= ELVEN_CLOAK) stealoid = otmp;
681.  		    }
682.  		    if (stealoid) {
683.  			boolean stolen = FALSE;
684.  			/* Is "he"/"his" always correct? */
685.  	 kludge("You seduce %s and he starts to take off his clothes.",
686.  				mon_nam(mdef));
687.  			while(mdef->minvent) {
688.  				otmp = mdef->minvent;
689.  				mdef->minvent = otmp->nobj;
690.  				if (!stolen && otmp==stealoid) {
691.  					if(isize < 52) {
692.  						otmp = addinv(otmp);
693.  						isize++;
694.  					} else dropy(otmp);
695.  					stealoid = otmp;
696.  					stolen = TRUE;
697.  				} else {
698.  					if(isize < 52) {
699.  						otmp = addinv(otmp);
700.  						isize++;
701.  					} else dropy(otmp);
702.  					You("steal: ");
703.  					prinv(otmp);
704.  				}
705.  			}
706.  			if (!stolen)
707.  				impossible("Player steal fails!");
708.  			else {
709.  				kludge("%s finishes taking off his suit.",
710.  							Monnam(mdef));
711.  				You("steal a %s.", xname(stealoid));
712.  #ifdef ARMY
713.  				mdef->data = &mons[PM_UNARMORED_SOLDIER];
714.  #endif
715.  			}
716.  		   } else {
717.  		   	   otmp = mdef->minvent;
718.  			   mdef->minvent = otmp->nobj;
719.  			   if(isize < 52) otmp = addinv(otmp);
720.  			   else dropy(otmp);
721.  			   You("steal: ");
722.  			   prinv(otmp);
723.  		   }
724.  		}
725.  		tmp = 0;
726.  		break;
727.  	    case AD_SGLD:
728.  		if (mdef->mgold) {
729.  		    u.ugold += mdef->mgold;
730.  		    mdef->mgold = 0;
731.  		    Your("purse feels heavier.");
732.  		}
733.  		tmp = 0;
734.  		break;
735.  	    case AD_TLPT:
736.  		if(tmp <= 0) tmp = 1;
737.  		if(tmp < mdef->mhp) {
738.  		    rloc(mdef);
739.  		    if(!Blind) pline("%s suddenly disappears!", Monnam(mdef));
740.  		}
741.  		break;
742.  	    case AD_BLND:
743.  		if(haseyes(pd)) {
744.  
745.  		    if(!Blind) pline("%s is blinded.", Monnam(mdef));
746.  		    mdef->mcansee = 0;
747.  		    mdef->mblinded += tmp;
748.  		}
749.  		tmp = 0;
750.  		break;
751.  	    case AD_CURS:
752.  		if (night() && !rn2(10) && !mdef->mcan) {
753.  #ifdef GOLEMS
754.  		    if (mdef->data == &mons[PM_CLAY_GOLEM]) {
755.  			if (!Blind)
756.  			    pline("Some writing vanishes from %s's head!",
757.  				mon_nam(mdef));
758.  			xkilled(mdef, 0);
759.  			return 2;
760.  		      }
761.  #endif /* GOLEMS */
762.  		    mdef->mcan = 1;
763.  		    You("chuckle.");
764.  		}
765.  		tmp = 0;
766.  		break;
767.  	    case AD_DRLI:
768.  		if(rn2(2) && !resists_drli(pd)) {
769.  			int xtmp = d(2,6);
770.  			kludge("%s suddenly seems weaker!", Monnam(mdef));
771.  			mdef->mhpmax -= xtmp;
772.  			if ((mdef->mhp -= xtmp) <= 0 || !mdef->m_lev--) {
773.  				kludge("%s dies.", Monnam(mdef));
774.  				xkilled(mdef,0);
775.  				return(2);
776.  			}
777.  		}
778.  		tmp = 0;
779.  		break;
780.  	    case AD_RUST:
781.  #ifdef GOLEMS
782.  		if (pd == &mons[PM_IRON_GOLEM]) {
783.  			kludge("%s falls to pieces!", Monnam(mdef));
784.  			xkilled(mdef,0);
785.  			return(2);
786.  		}
787.  #endif /* GOLEMS */
788.  		tmp = 0;
789.  		break;
790.  	    case AD_DCAY:
791.  #ifdef GOLEMS
792.  		if (pd == &mons[PM_WOOD_GOLEM] ||
793.  		    pd == &mons[PM_LEATHER_GOLEM]) {
794.  			kludge("%s falls to pieces!", Monnam(mdef));
795.  			xkilled(mdef,0);
796.  			return(2);
797.  		}
798.  #endif /* GOLEMS */
799.  	    case AD_DRST:
800.  	    case AD_DRDX:
801.  	    case AD_DRCO:
802.  		if (!rn2(8)) {
803.  		    Your("%s was poisoned!", mattk->aatyp==AT_BITE ?
804.  			"bite" : "sting");
805.  		    if (resists_poison(mdef->data))
806.  			kludge("The poison doesn't seem to affect %s.",
807.  				mon_nam(mdef));
808.  		    else {
809.  			if (!rn2(10)) {
810.  			    Your("poison was deadly...");
811.  			    tmp = mdef->mhp;
812.  			} else tmp += rn1(10,6);
813.  		    }
814.  		}
815.  		break;
816.  	    case AD_WRAP:
817.  	    case AD_STCK:
818.  		if (!sticks(mdef->data))
819.  		    u.ustuck = mdef; /* it's now stuck to you */
820.  		break;
821.  	    default:	tmp = 0;
822.  			break;
823.  	}
824.  	if(!tmp) return(1);
825.  
826.  	if((mdef->mhp -= tmp) < 1) {
827.  
828.  	    if(mdef->mtame) {
829.  		if(!Blind) You("killed your %s!", mon_nam(mdef));
830.  		else	You("feel embarrassed for a moment.");
831.  	    } else {
832.  		if(!Blind && flags.verbose)  pline("%s is killed!", Monnam(mdef));
833.  		else	    You("kill it!");
834.  	    }
835.  	    xkilled(mdef, 0);
836.  	    return(2);
837.  	}
838.  	return(1);
839.  }
840.  
841.  static int
842.  explum(mdef, mattk)
843.  register struct monst *mdef;
844.  register struct attack *mattk;
845.  {
846.  	switch(mattk->adtyp) {
847.  	    case AD_BLND:
848.  		if(mdef->data->mlet != S_YLIGHT) {
849.  		    kludge("%s is blinded by your flash of light!", Monnam(mdef));
850.  		    if (!mdef->mblinded) {
851.  			mdef->mblinded += rn2(25);
852.  			mdef->mcansee = 0;
853.  		    }
854.  		}
855.  		break;
856.  	    case AD_COLD:
857.  		You("explode!");
858.  		if (!resists_cold(mdef->data)) {
859.  		    kludge("%s gets blasted!", Monnam(mdef));
860.  		    mdef->mhp -= d(6,6);
861.  		    if (mdef->mhp <= 0) {
862.  			 killed(mdef);
863.  			 return(2);
864.  		    }
865.  #ifdef GOLEMS
866.  		} else if (is_golem(mdef->data)) {
867.  		    golemeffects(mdef, AD_COLD, d(6,6));
868.  		    shieldeff(mdef->mx, mdef->my);
869.  #endif /* GOLEMS */
870.  		} else {
871.  		    shieldeff(mdef->mx, mdef->my);
872.  		    kludge("The blast doesn't seem to affect %s.",
873.  			   mon_nam(mdef));
874.  		}
875.  		break;
876.  	    default:	break;
877.  	}
878.  	return(1);
879.  }
880.  
881.  static int
882.  gulpum(mdef,mattk)
883.  register struct monst *mdef;
884.  register struct attack *mattk;
885.  {
886.  	register int tmp;
887.  	register int dam = d((int)mattk->damn, (int)mattk->damd);
888.  	/* Not totally the same as for real monsters.  Specifically, these
889.  	 * don't take multiple moves.  (It's just too hard, for too little
890.  	 * result, to program monsters which attack from inside you, which
891.  	 * would be necessary if done accurately.)  Instead, we arbitrarily
892.  	 * kill the monster immediately for AD_DGST and we regurgitate them
893.  	 * after exactly 1 round of attack otherwise.  -KAA
894.  	 */
895.  
896.  #ifdef WORM
897.  	if(mdef->wormno) return 0;
898.  #endif
899.  	if(u.uhunger < 1500 && !u.uswallow) {
900.  
901.  	    if(mdef->data->mlet != S_COCKATRICE) {
902.  #ifdef LINT	/* static char msgbuf[BUFSZ]; */
903.  		char msgbuf[BUFSZ];
904.  #else
905.  		static char msgbuf[BUFSZ];
906.  #endif
907.  /* TODO: get the symbol display also to work (monster symbol is removed from
908.   * the screen and you moved onto it, then you get moved back and it gets
909.   * moved back if the monster survives--just like when monsters swallow you.
910.   */
911.  		kludge("You engulf %s!", mon_nam(mdef));
912.  		switch(mattk->adtyp) {
913.  		    case AD_DGST:
914.  			u.uhunger += 20*mdef->mhpmax;
915.  			newuhs(FALSE);
916.  			xkilled(mdef,2);
917.  			Sprintf(msgbuf, "You totally digest %s.",
918.  					Blind ? "it" : mon_nam(mdef));
919.  			if ((tmp = mdef->mhpmax/5)) {
920.  			    kludge("You digest %s.", mon_nam(mdef));
921.  			    nomul(-tmp);
922.  			    nomovemsg = msgbuf;
923.  			} else pline(msgbuf);
924.  			return(2);
925.  		    case AD_PHYS:
926.  			kludge("%s is pummeled with your debris!",Monnam(mdef));
927.  			break;
928.  		    case AD_ACID:
929.  			kludge("%s is covered with your goo!", Monnam(mdef));
930.  			if (resists_acid(mdef->data)) {
931.  			    kludge("It seems harmless to %s.", mon_nam(mdef));
932.  			    dam = 0;
933.  			}
934.  			break;
935.  		    case AD_BLND:
936.  			if (mdef->mcansee)
937.  			    kludge("%s can't see in there!", Monnam(mdef));
938.  			mdef->mcansee = 0;
939.  			dam += mdef->mblinded;
940.  			if (dam > 127) dam = 127;
941.  			mdef->mblinded = dam;
942.  			dam = 0;
943.  			break;
944.  		    case AD_ELEC:
945.  			if (rn2(2)) {
946.  			    kludge("The air around %s crackles with electricity.", mon_nam(mdef));
947.  			    if (resists_elec(mdef->data)) {
948.  				kludge("%s seems unhurt.", Monnam(mdef));
949.  				dam = 0;
950.  			    }
951.  #ifdef GOLEMS
952.  			    golemeffects(mdef,(int)mattk->adtyp,dam);
953.  #endif
954.  			} else dam = 0;
955.  			break;
956.  		    case AD_COLD:
957.  			if (rn2(2)) {
958.  			    if (resists_cold(mdef->data)) {
959.  				kludge("%s seems mildly chilly.", Monnam(mdef));
960.  				dam = 0;
961.  			    } else
962.  				kludge("%s is freezing to death!",Monnam(mdef));
963.  #ifdef GOLEMS
964.  			    golemeffects(mdef,(int)mattk->adtyp,dam);
965.  #endif
966.  			} else dam = 0;
967.  			break;
968.  		    case AD_FIRE:
969.  			if (rn2(2)) {
970.  			    if (resists_fire(mdef->data)) {
971.  				kludge("%s seems mildly hot.", Monnam(mdef));
972.  				dam = 0;
973.  			    } else
974.  				kludge("%s is burning to a crisp!",Monnam(mdef));
975.  #ifdef GOLEMS
976.  			    golemeffects(mdef,(int)mattk->adtyp,dam);
977.  #endif
978.  			} else dam = 0;
979.  			break;
980.  		}
981.  		if ((mdef->mhp -= dam) <= 0) {
982.  		    kludge("%s is killed!", Monnam(mdef));
983.  		    xkilled(mdef,0);
984.  		    return(2);
985.  		}
986.  		kludge("You regurgitate %s!", mon_nam(mdef));
987.  		if (Blind)
988.  		    pline("Obviously, you didn't like its taste.");
989.  		else
990.  		    pline("Obviously, you didn't like %s's taste.",
991.  								mon_nam(mdef));
992.  	    } else {
993.  		kludge("You bite into %s", mon_nam(mdef));
994.  		You("turn to stone...");
995.  		killer = "poor choice of food";
996.  		done("stoned");
997.  	    }
998.  	}
999.  	return(0);
1000. }
1001. 
1002. static void
1003. missum(mdef)
1004. register struct monst *mdef;
1005. {
1006. #ifdef POLYSELF
1007. 	if (u.usym==S_NYMPH
1008. #  ifdef SEDUCE
1009. || ((u.umonnum==PM_INCUBUS || u.umonnum==PM_SUCCUBUS) && !incompatible(mdef))
1010. #  endif
1011. 									)
1012. 		kludge("You pretend to be friendly to %s.", mon_nam(mdef));
1013. 	else
1014. #endif
1015. 	if(!Blind && flags.verbose)  You("miss %s.", mon_nam(mdef));
1016. 	else	    You("miss it.");
1017. 	if(is_human(mdef->data) && !(mdef->msleep || mdef->mfroz))
1018. 		wakeup(mdef);
1019. }
1020. 
1021. static boolean
1022. hmonas(mon, tmp)		/* attack monster as a monster. */
1023. register struct monst *mon;
1024. register int tmp;
1025. {
1026. 	register struct attack *mattk;
1027. 	int	i, sum[NATTK];
1028. 	int	nsum = 0;
1029. 	schar	dhit;
1030. 
1031. 	for(i = 0; i < NATTK; i++) {
1032. 
1033. 	    mattk = &(uasmon->mattk[i]);
1034. 	    switch(mattk->aatyp) {
1035. 		case AT_WEAP:
1036. use_weapon:
1037. 	/* Certain monsters don't use weapons when encountered as enemies,
1038. 	 * but players who polymorph into them have hands or claws and thus
1039. 	 * should be able to use weapons.  This shouldn't prohibit the use
1040. 	 * of most special abilities, either.
1041. 	 */
1042. 	/* Potential problem: if the monster gets multiple weapon attacks,
1043. 	 * we currently allow the player to get each of these as a weapon
1044. 	 * attack.  Is this really desirable?
1045. 	 */
1046. 			if(uwep) tmp += hitval(uwep, mon->data);
1047. 			dhit = !((tmp <= rnd(20)) && !u.uswallow);
1048. 			/* Enemy dead, before any special abilities used */
1049. 			if (!known_hitum(mon,dhit)) return 0;
1050. 			/* Do not print "You hit" message, since known_hitum
1051. 			 * already did it.
1052. 			 */
1053. 			if (dhit && mattk->adtyp != AD_SPEL
1054. 				&& mattk->adtyp != AD_PHYS)
1055. 				sum[i] = damageum(mon,mattk);
1056. 			else sum[i] = 0;
1057. 			break;
1058. 		case AT_CLAW:
1059. 			if (i==0 && uwep && humanoid(uasmon)) goto use_weapon;
1060. 		case AT_KICK:
1061. 		case AT_BITE:
1062. 		case AT_STNG:
1063. 		case AT_TUCH:
1064. 		case AT_BUTT:
1065. 			if (i==0 && uwep && (u.usym==S_LICH
1066. 				)) goto use_weapon;
1067. 			if(dhit = (tmp > rnd(20) || u.uswallow)) {
1068. /* <----- <----- <----- <----- <----- <----- <----- <----- <----- */
1069. if (!u.uswallow && (u.usym==S_NYMPH
1070. #ifdef SEDUCE
1071.   || ((u.umonnum==PM_INCUBUS || u.umonnum==PM_SUCCUBUS) && !incompatible(mon))
1072. #endif
1073. 									)) {
1074. 		kludge("You %s %s %s.", mon->mblinded ? "talk to" : "smile at",
1075. 			mon_nam(mon),
1076. 			incompatible(mon) ? "engagingly" : "seductively");
1077. }
1078. /* <----- <----- <----- <----- <----- <----- <----- <----- <----- */
1079. 				else if (mattk->aatyp == AT_KICK)
1080. 					kludge("You kick %s.", mon_nam(mon));
1081. 				else if (mattk->aatyp == AT_BITE)
1082. 					kludge("You bite %s.", mon_nam(mon));
1083. 				else if (mattk->aatyp == AT_STNG)
1084. 					kludge("You sting %s.", mon_nam(mon));
1085. 				else if (mattk->aatyp == AT_BUTT)
1086. 					kludge("You butt %s.", mon_nam(mon));
1087. 				else if (mattk->aatyp == AT_TUCH)
1088. 					kludge("You touch %s.", mon_nam(mon));
1089. 				else kludge("You hit %s.", mon_nam(mon));
1090. 				sum[i] = damageum(mon, mattk);
1091. 			} else {
1092. 				missum(mon);
1093. 				sum[i] = 0;
1094. 			}
1095. 			break;
1096. 
1097. 		case AT_HUGS:
1098. 			/* automatic if prev two attacks succeed, or if
1099. 			 * already grabbed in a previous attack
1100. 			 */
1101. 			dhit = 1;
1102. 			if (sticks(mon->data)) sum[i] = 0;
1103. 			else if (mon==u.ustuck) {
1104. 			    kludge("%s is being %s.", Monnam(mon),
1105. #ifdef GOLEMS
1106. 				u.umonnum==PM_ROPE_GOLEM ? "choked":
1107. #endif
1108. 				"crushed");
1109. 			    sum[i] = damageum(mon, mattk);
1110. 			} else if(sum[i-1] && sum[i-2]) {
1111. 			    kludge("You grab %s!", mon_nam(mon));
1112. 			    u.ustuck = mon;
1113. 			    sum[i] = damageum(mon, mattk);
1114. 			} else sum[i] = 0;
1115. 			break;
1116. 
1117. 		case AT_EXPL:	/* automatic hit if next to */
1118. 			dhit = -1;
1119. 			sum[i] = explum(mon, mattk);
1120. 			break;
1121. 
1122. 		case AT_ENGL:
1123. 			if((dhit = (tmp > rnd(20+i))))
1124. 				sum[i]= gulpum(mon,mattk);
1125. 			else {
1126. 				missum(mon);
1127. 				sum[i] = 0;
1128. 			}
1129. 			break;
1130. 
1131. 		case AT_MAGC:
1132. 			/* No check for uwep; if wielding nothing we want to
1133. 			 * do the normal 1-2 points bare hand damage...
1134. 			 */
1135. 			if (i==0 && (u.usym==S_KOBOLD
1136. 				|| u.usym==S_ORC
1137. 				|| u.usym==S_GNOME
1138. 				)) goto use_weapon;
1139. 
1140. 		case AT_NONE:
1141. 			sum[i] = 0;
1142. 			continue;
1143. 			/* Not break--avoid passive attacks from enemy */
1144. 
1145. 		default: /* Strange... */
1146. 			impossible("strange attack of yours (%d)",
1147. 				 mattk->aatyp);
1148. 		case AT_BREA:
1149. 		case AT_SPIT:
1150. 		case AT_GAZE:	/* all done using #monster command */
1151. 			sum[i] = dhit = 0;
1152. 			break;
1153. 	    }
1154. 	    if (dhit == -1)
1155. 		rehumanize();
1156. 	    if(sum[i] == 2) return(passive(mon, 1, 0)); /* defender dead */
1157. 	    else {
1158. 		(void) passive(mon, sum[i], 1);
1159. 		nsum |= sum[i];
1160. 	    }
1161. 	    if (uasmon == &playermon)
1162. 		break; /* No extra attacks if no longer a monster */
1163. 	    if (multi < 0)
1164. 		break; /* If paralyzed while attacking, i.e. floating eye */
1165. 	}
1166. 	return(nsum);
1167. }
1168. 
1169. #endif
1170. 
1171. /*	Special (passive) attacks on you by monsters done here.		*/
1172. 
1173. static int
1174. passive(mon, mhit, malive)
1175. register struct monst *mon;
1176. register boolean mhit;
1177. register int malive;
1178. {
1179. 	register struct permonst *ptr = mon->data;
1180. 	register int i, tmp;
1181. 
1182. 	for(i = 0; ; i++) {
1183. 	    if(i >= NATTK) return(malive | mhit);	/* no passive attacks */
1184. 	    if(ptr->mattk[i].aatyp == AT_NONE) break;	/* try this one */
1185. 	}
1186. 
1187. /*	These affect you even if they just died */
1188. 
1189. 	switch(ptr->mattk[i].adtyp) {
1190. 
1191. 	  case AD_ACID:
1192. 	    if(mhit && rn2(2)) {
1193. 		if (Blind || !flags.verbose) You("are splashed!");
1194. 		else	You("are splashed by %s's acid!", mon_nam(mon));
1195. 
1196. 		tmp = d((int)mon->m_lev, (int)ptr->mattk[i].damd);
1197. #ifdef POLYSELF
1198. 		if(!resists_acid(uasmon))
1199. #endif
1200. 			mdamageu(mon, tmp);
1201. 		if(!rn2(30)) corrode_armor();
1202. 	    }
1203. 	    if(mhit && !rn2(6)) corrode_weapon();
1204. 	    break;
1205. 	  case AD_MAGM:
1206. 	    /* wrath of gods for attacking Oracle */
1207. 	    if(Antimagic) {
1208. 		shieldeff(u.ux, u.uy);
1209. 		pline("A hail of magic missiles narrowly misses you!");
1210. 	    } else {
1211. 		tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd);
1212. 		You("are hit by magic missiles appearing from thin air!");
1213. 		mdamageu(mon, tmp);
1214. 	    }
1215. 	    break;
1216. 	  default:
1217. 	    break;
1218. 	}
1219. 
1220. /*	These only affect you if they still live */
1221. 
1222. 	if(malive && !mon->mcan && rn2(3)) {
1223. 
1224. 	    switch(ptr->mattk[i].adtyp) {
1225. 
1226. 	      case AD_PLYS:		/* specifically floating eye */
1227. 		if(canseemon(mon)) {
1228. 
1229. 		    tmp = -d((int)mon->m_lev+1, (int)ptr->mattk[i].damd);
1230. 		    if(mon->mcansee) {
1231. 			if(Reflecting & W_AMUL) {
1232. 			    makeknown(AMULET_OF_REFLECTION);
1233. 			    pline("%s's gaze is reflected by your medallion.",
1234. 				  Monnam(mon));
1235. 			} else if(Reflecting & W_ARMS) {
1236. 			    makeknown(SHIELD_OF_REFLECTION);
1237. 			    pline("%s's gaze is reflected by your shield.",
1238. 				  Monnam(mon));
1239. 			} else {
1240. 			    You("are frozen by %s's gaze!", mon_nam(mon));
1241. 			    nomul((ACURR(A_WIS) > 12 || rn2(4)) ? tmp : -120);
1242. 			}
1243. 		    } else {
1244. 			pline("%s cannot defend itself.", Amonnam(mon,"blind"));
1245. 			if(!rn2(500)) change_luck(-1);
1246. 		    }
1247. 		}
1248. 		break;
1249. 	      case AD_COLD:		/* brown mold or blue jelly */
1250. 		if(dist(mon->mx, mon->my) <= 3) {
1251. 		    tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd);
1252. 		    if(Cold_resistance) {
1253.   			shieldeff(u.ux, u.uy);
1254. 			You("feel a mild chill.");
1255. #ifdef POLYSELF
1256. #ifdef GOLEMS
1257. 			ugolemeffects(AD_COLD, tmp);
1258. #endif /* GOLEMS */
1259. #endif
1260. 			tmp = 0;
1261. 			break;
1262. 		    }
1263. 		    You("are suddenly very cold!");
1264. 		    mdamageu(mon, tmp);
1265. 		/* monster gets stronger with your heat! */
1266. 		    mon->mhp += tmp / 2;
1267. 		    if (mon->mhpmax < mon->mhp) mon->mhpmax = mon->mhp;
1268. 		/* at a certain point, the monster will reproduce! */
1269. 		    if(mon->mhpmax > ((mon->m_lev+1) * 8)) {
1270. 			register struct monst *mtmp;
1271. 
1272. 			if(mtmp = clone_mon(mon)) {
1273. 			    mtmp->mhpmax = mon->mhpmax /= 2;
1274. 			    if(!Blind)
1275. 				pline("%s multiplies from your heat!",
1276. 								Monnam(mon));
1277. 			}
1278. 		    }
1279. 		}
1280. 		break;
1281. 	      case AD_STUN:		/* specifically yellow mold */
1282. 		if(!Stunned)
1283. 		    make_stunned((long)d((int)mon->m_lev+1, (int)ptr->mattk[i].damd), TRUE);
1284. 		break;
1285. 	      case AD_FIRE:
1286. 		if(dist(mon->mx, mon->my) <= 3) {
1287. 		    tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd);
1288. 		    if(Fire_resistance) {
1289.   			shieldeff(u.ux, u.uy);
1290. 			You("feel mildly warm.");
1291. #ifdef POLYSELF
1292. #ifdef GOLEMS
1293. 			ugolemeffects(AD_FIRE, tmp);
1294. #endif /* GOLEMS */
1295. #endif
1296. 			tmp = 0;
1297. 			break;
1298. 		    }
1299. 		    You("are suddenly very hot!");
1300. 		    mdamageu(mon, tmp);
1301. 		}
1302. 		break;
1303. 	      default:
1304. 		break;
1305. 	    }
1306. 	}
1307. 	return(malive | mhit);
1308. }

Also on Fandom

Random Wiki