Fandom

Wikihack

Source:NetHack 3.1.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.1.0. To link to a particular line, write [[NetHack 3.1.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.1	92/12/10	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    
7.    static boolean FDECL(known_hitum, (struct monst *,int));
8.    static boolean FDECL(hitum, (struct monst *,int));
9.    #ifdef POLYSELF
10.   static int FDECL(explum, (struct monst *,struct attack *));
11.   static int FDECL(gulpum, (struct monst *,struct attack *));
12.   static boolean FDECL(hmonas, (struct monst *,int));
13.   #endif
14.   static void FDECL(nohandglow, (struct monst *));
15.   
16.   extern boolean notonhead;	/* for long worms */
17.   /* The below might become a parameter instead if we use it a lot */
18.   static int dieroll;
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.   	if (!enexto(&mm, mm.x, mm.y, mon->data)) return (struct monst *)0;
30.   	if (MON_AT(mm.x, mm.y) || mon->mhp <= 1) return (struct monst *)0;
31.   	/* may have been extinguished for population control */
32.   	if(mon->data->geno & G_EXTINCT) return((struct monst *) 0);
33.   	m2 = newmonst(0);
34.   	*m2 = *mon;			/* copy condition of old monster */
35.   	m2->nmon = fmon;
36.   	fmon = m2;
37.   	m2->m_id = flags.ident++;
38.   	m2->mx = mm.x;
39.   	m2->my = mm.y;
40.   
41.   	m2->minvent = (struct obj *) 0; /* objects don't clone */
42.   	m2->mleashed = FALSE;
43.   	m2->mgold = 0L;
44.   	/* Max HP the same, but current HP halved for both.  The caller
45.   	 * might want to override this by halving the max HP also.
46.   	 */
47.   	m2->mhpmax = mon->mhpmax;
48.   	m2->mhp = mon->mhp /= 2;
49.   
50.   	/* since shopkeepers and guards will only be cloned if they've been
51.   	 * polymorphed away from their original forms, the clone doesn't have
52.   	 * room for the extra information.  we also don't want two shopkeepers
53.   	 * around for the same shop.
54.   	 * similarly, clones of named monsters don't have room for the name,
55.   	 * so we just make the clone unnamed instead of bothering to create
56.   	 * a clone with room and copying over the name from the right place
57.   	 * (which changes if the original was a shopkeeper or guard).
58.   	 */
59.   	if (mon->isshk) m2->isshk = FALSE;
60.   	if (mon->isgd) m2->isgd = FALSE;
61.   	if (mon->ispriest) m2->ispriest = FALSE;
62.   	m2->mxlth = 0;
63.   	m2->mnamelth = 0;
64.   	place_monster(m2, m2->mx, m2->my);
65.   	newsym(m2->mx,m2->my);	/* display the new monster */
66.   	if (mon->mtame) {
67.   	    struct monst *m3;
68.   
69.   	    /* because m2 is a copy of mon it is tame but not init'ed.
70.   	     * however, tamedog will not re-tame a tame dog, so m2
71.   	     * must be made non-tame to get initialized properly.
72.   	     */
73.   	    m2->mtame = 0;
74.   	    if ((m3 = tamedog(m2, (struct obj *)0)) != 0)
75.   		m2 = m3;
76.   	}
77.   	return m2;
78.   }
79.   
80.   boolean
81.   special_case(mtmp)
82.   /* Moved this code from attack() in order to 	*/
83.   /* avoid having to duplicate it in dokick.	*/
84.   register struct monst *mtmp;
85.   {
86.   	char qbuf[QBUFSZ];
87.   
88.   	if(mtmp->m_ap_type && !Protection_from_shape_changers
89.   						&& !sensemon(mtmp)) {
90.   		stumble_onto_mimic(mtmp);
91.   		mtmp->data->mflags3 &= ~M3_WAITMASK;
92.   		return(1);
93.   	}
94.   
95.   	if(mtmp->mundetected && hides_under(mtmp->data) && !canseemon(mtmp)) {
96.   		mtmp->mundetected = 0;
97.   		if (!(Blind ? Telepat : (HTelepat & (W_ARMH|W_AMUL|W_ART)))) {
98.   			register struct obj *obj;
99.   
100.  			if(Blind)
101.  			    pline("Wait!  There's a hidden monster there!");
102.  			else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0)
103.  			    pline("Wait!  There's %s hiding under %s!",
104.  					an(l_monnam(mtmp)), doname(obj));
105.  			wakeup(mtmp);
106.  			mtmp->data->mflags3 &= ~M3_WAITMASK;
107.  			return(TRUE);
108.  		}
109.  	}
110.  
111.  	if (flags.confirm && mtmp->mpeaceful
112.  	    && !Confusion && !Hallucination && !Stunned) {
113.  		/* Intelligent chaotic weapons (Stormbringer) want blood */
114.  		if (uwep && uwep->oartifact == ART_STORMBRINGER)
115.  			return(FALSE);
116.  
117.  		if (canspotmon(mtmp)) {
118.  			Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp));
119.  			if (yn(qbuf) != 'y') {
120.  				flags.move = 0;
121.  				mtmp->data->mflags3 &= ~M3_WAITMASK;
122.  				return(TRUE);
123.  			}
124.  		}
125.  	}
126.  
127.  	return(FALSE);
128.  }
129.  
130.  schar
131.  find_roll_to_hit(mtmp)
132.  register struct monst *mtmp;
133.  {
134.  	schar tmp;
135.  	int tmp2;
136.  	struct permonst *mdat = mtmp->data;
137.  
138.  	tmp = 1 + Luck + abon() +
139.  		find_mac(mtmp) +
140.  #ifdef POLYSELF
141.  		((u.umonnum >= 0) ? uasmon->mlevel : u.ulevel);
142.  #else
143.  		u.ulevel;
144.  #endif
145.  
146.  /*	it is unchivalrous to attack the defenseless or from behind */
147.  	if (pl_character[0] == 'K' && u.ualign.type == A_LAWFUL &&
148.  	    (!mtmp->mcanmove || mtmp->msleep || mtmp->mflee) &&
149.  	    u.ualign.record > -10) adjalign(-1);
150.  
151.  /*	attacking peaceful creatures is bad for the samurai's giri */
152.  	if (pl_character[0] == 'S' && mtmp->mpeaceful &&
153.  	    u.ualign.record > -10) adjalign(-1);
154.  
155.  /*	Adjust vs. (and possibly modify) monster state.		*/
156.  
157.  	if(mtmp->mstun) tmp += 2;
158.  	if(mtmp->mflee) tmp += 2;
159.  
160.  	if(mtmp->msleep) {
161.  		mtmp->msleep = 0;
162.  		tmp += 2;
163.  	}
164.  	if(!mtmp->mcanmove) {
165.  		tmp += 4;
166.  		if(!rn2(10)) {
167.  			mtmp->mcanmove = 1;
168.  			mtmp->mfrozen = 0;
169.  		}
170.  	}
171.  	if (is_orc(mtmp->data) && pl_character[0]=='E') tmp++;
172.  
173.  /*	with a lot of luggage, your agility diminishes */
174.  	if(tmp2 = near_capacity()) tmp -= (tmp2*2) - 1;
175.  	if(u.utrap) tmp -= 3;
176.  #ifdef POLYSELF
177.  /*	Some monsters have a combination of weapon attacks and non-weapon
178.   *	attacks.  It is therefore wrong to add hitval to tmp; we must add it
179.   *	only for the specific attack (in hmonas()).
180.   */
181.  	if(uwep && u.umonnum == -1) tmp += hitval(uwep, mdat);
182.  #else
183.  	if(uwep) tmp += hitval(uwep, mdat);
184.  #endif
185.  	return tmp;
186.  }
187.  
188.  /* try to attack; return FALSE if monster evaded */
189.  /* u.dx and u.dy must be set */
190.  boolean
191.  attack(mtmp)
192.  register struct monst *mtmp;
193.  {
194.  	schar tmp;
195.  	register struct permonst *mdat = mtmp->data;
196.  
197.  	/* This section of code provides protection against accidentally
198.  	 * hitting peaceful (like '@') and tame (like 'd') monsters.
199.  	 * Protection is provided as long as player is not: blind, confused,
200.  	 * hallucinating or stunned.
201.  	 * changes by wwp 5/16/85
202.  	 * More changes 12/90, -dkh-. if its tame and safepet, (and protected
203.  	 * 07/92) then we assume that you're not trying to attack. Instead,
204.  	 * you'll usually just swap places if this is a movement command
205.  	 */
206.  	/* Intelligent chaotic weapons (Stormbringer) want blood */
207.  	if (is_safepet(mtmp) &&
208.  	    (!uwep || uwep->oartifact != ART_STORMBRINGER)) {
209.  		/* there are some additional considerations: this won't work
210.  		 * if in a shop or Punished or you miss a random roll or
211.  		 * if you can walk thru walls and your pet cannot (KAA) or
212.  		 * if your pet is a long worm (unless someone does better).
213.  		 * there's also a chance of displacing a "frozen" monster.
214.  		 * sleeping monsters might magically walk in their sleep.
215.  		 */
216.  		unsigned int foo = (Punished ||
217.  				    !rn2(7) || is_longworm(mtmp->data));
218.  
219.  		if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || foo
220.  #ifdef POLYSELF
221.  			|| (IS_ROCK(levl[u.ux][u.uy].typ) &&
222.  					!passes_walls(mtmp->data))
223.  #endif
224.  			) {
225.  		    mtmp->mflee = 1;
226.  		    mtmp->mfleetim = rnd(6);
227.  		    You("stop.  %s is in your way!",
228.  			(mtmp->mnamelth ? NAME(mtmp) : Monnam(mtmp)));
229.  		    return(TRUE);
230.  		} else if ((mtmp->mfrozen || (! mtmp->mcanmove)
231.  				|| (mtmp->data->mmove == 0)) && rn2(6)) {
232.  		    pline("%s doesn't seem to move!", Monnam(mtmp));
233.  		    return(TRUE);
234.  		} else return(FALSE);
235.  	}
236.  
237.  	/* moved code to a separate function to share with dokick */
238.  	if(special_case(mtmp)) return(TRUE);
239.  
240.  #ifdef POLYSELF
241.  	if(u.umonnum >= 0) {	/* certain "pacifist" monsters don't attack */
242.  		set_uasmon();
243.  		if(noattacks(uasmon)) {
244.  			You("have no way to attack monsters physically.");
245.  			mtmp->data->mflags3 &= ~M3_WAITMASK;
246.  			return(TRUE);
247.  		}
248.  	}
249.  #endif
250.  
251.  	if(check_capacity("You cannot fight while so heavily loaded."))
252.  	    return (TRUE);
253.  
254.  	if(unweapon) {
255.  	    unweapon=FALSE;
256.  	    if(flags.verbose)
257.  		if(uwep)
258.  		    You("begin bashing monsters with your %s.",
259.  			aobjnam(uwep, NULL));
260.  		else
261.  #ifdef POLYSELF
262.  		    if (!cantwield(uasmon))
263.  #endif
264.  		    You("begin bashing monsters with your %s hands.",
265.  			uarmg ? "gloved" : "bare");		/* Del Lamb */
266.  	}
267.  	exercise(A_STR, TRUE);		/* you're exercising muscles */
268.  	/* andrew@orca: prevent unlimited pick-axe attacks */
269.  	u_wipe_engr(3);
270.  
271.  	if(mdat->mlet == S_LEPRECHAUN && mtmp->mfrozen && !mtmp->msleep &&
272.  	   !mtmp->mconf && mtmp->mcansee && !rn2(7) &&
273.  	   (m_move(mtmp, 0) == 2 ||			    /* it died */
274.  	   mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) /* it moved */
275.  		return(FALSE);
276.  
277.  	tmp = find_roll_to_hit(mtmp);
278.  #ifdef POLYSELF
279.  	if (u.umonnum >= 0) (void) hmonas(mtmp, tmp);
280.  	else
281.  #endif
282.  	    (void) hitum(mtmp, tmp);
283.  
284.  	mtmp->data->mflags3 &= ~M3_WAITMASK;
285.  	return(TRUE);
286.  }
287.  
288.  static boolean
289.  known_hitum(mon, mhit)	/* returns TRUE if monster still lives */
290.  /* Made into a separate function because in some cases we want to know
291.   * in the calling function whether we hit.
292.   */
293.  register struct monst *mon;
294.  register int mhit;
295.  {
296.  	register boolean malive = TRUE, special;
297.  
298.  	/* we need to know whether the special monster was peaceful */
299.  	/* before the attack, to save idle calls to angry_guards()  */
300.  	special = (mon->mpeaceful && (mon->data == &mons[PM_WATCHMAN] ||
301.  				mon->data == &mons[PM_WATCH_CAPTAIN] ||
302.  				      mon->ispriest || mon->isshk));
303.  
304.  	if(!mhit) {
305.  	    if(flags.verbose) You("miss %s.", mon_nam(mon));
306.  	    else			You("miss it.");
307.  	    if(!mon->msleep && mon->mcanmove)
308.  		wakeup(mon);
309.  #ifdef MUSE
310.  	    else if (uwep && uwep->otyp == TSURUGI &&
311.  		     MON_WEP(mon) && !rn2(20)) {
312.  		/* 1/20 chance of shattering defender's weapon */
313.  		struct obj *obj = MON_WEP(mon);
314.  
315.  		MON_NOWEP(mon);
316.  		m_useup(mon, obj);
317.  		pline("%s weapon shatters!", s_suffix(Monnam(mon)));
318.  		/* perhaps this will freak out the monster */
319.  		if (!rn2(3)) {
320.  		    mon->mflee = 1;
321.  		    mon->mfleetim += rnd(20);
322.  		}
323.  	    }
324.  #endif
325.  	} else {
326.  	    /* we hit the monster; be careful: it might die! */
327.  	    notonhead = (mon->mx != u.ux+u.dx || mon->my != u.uy+u.dy);
328.  	    if((malive = hmon(mon, uwep, 0)) == TRUE) {
329.  		/* monster still alive */
330.  		if(!rn2(25) && mon->mhp < mon->mhpmax/2) {
331.  			mon->mflee = 1;
332.  			if(!rn2(3)) mon->mfleetim = rnd(100);
333.  			if(u.ustuck == mon && !u.uswallow
334.  #ifdef POLYSELF
335.  						&& !sticks(uasmon)
336.  #endif
337.  								)
338.  				u.ustuck = 0;
339.  		}
340.  		if (mon->wormno) cutworm(mon, u.ux+u.dx, u.uy+u.dy, uwep);
341.  	    }
342.  	    if(mon->ispriest && !rn2(2)) ghod_hitsu(mon);
343.  	    if(special) (void) angry_guards(!flags.soundok);
344.  	}
345.  	return(malive);
346.  }
347.  
348.  static boolean
349.  hitum(mon, tmp)		/* returns TRUE if monster still lives */
350.  struct monst *mon;
351.  int tmp;
352.  {
353.  	static int NEARDATA malive;
354.  	boolean mhit = (tmp > (dieroll = rnd(20)) || u.uswallow);
355.  
356.  	if(tmp > dieroll) exercise(A_DEX, TRUE);
357.  	malive = known_hitum(mon, mhit);
358.  	(void) passive(mon, mhit, malive, FALSE);
359.  	return(malive);
360.  }
361.  
362.  boolean			/* general "damage monster" routine */
363.  hmon(mon, obj, thrown)		/* return TRUE if mon still alive */
364.  register struct monst *mon;
365.  register struct obj *obj;
366.  register int thrown;
367.  {
368.  	int tmp;
369.  	struct permonst *mdat = mon->data;
370.  	/* Why all these booleans?  This stuff has to be done in the
371.  	 *      following order:
372.  	 * 1) Know what we're attacking with, and print special hittxt for
373.  	 *	unusual cases.
374.  	 * 2a) Know whether we did damage (depends on 1)
375.  	 * 2b) Know if it's poisoned (depends on 1)
376.  	 * 2c) Know whether we get a normal damage bonus or not (depends on 1)
377.  	 * 3a) Know what the value of the damage bonus is (depends on 2c)
378.  	 * 3b) Know how much poison damage was taken (depends on 2b) and if the
379.  	 *	poison instant-killed it
380.  	 * 4) Know if it was killed (requires knowing 3a, 3b) except by instant-
381.  	 *	kill poison
382.  	 * 5) Print hit message (depends on 1 and 4)
383.  	 * 6a) Print poison message (must be done after 5)
384.  #if 0
385.  	 * 6b) Rust weapon (must be done after 5)
386.  #endif
387.  	 * 7) Possibly kill monster (must be done after 6a, 6b)
388.  	 * 8) Instant-kill from poison (can happen anywhere between 5 and 9)
389.  	 * 9) Hands not glowing (must be done after 7 and 8)
390.  	 * The major problem is that since we don't want a "hit" message
391.  	 * when the monster dies, we have to know how much damage it did
392.  	 * _before_ outputting a hit message, but any messages associated with
393.  	 * the damage don't come out until _after_ outputting a hit message.
394.  	 */
395.  	boolean hittxt = FALSE, destroyed = FALSE;
396.  	boolean get_dmg_bonus = TRUE;
397.  	boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE;
398.  	boolean silvermsg = FALSE;
399.  
400.  	wakeup(mon);
401.  	if(!obj) {	/* attack with bare hands */
402.  	    if (mdat == &mons[PM_SHADE])
403.  		tmp = 0;
404.  	    else
405.  		tmp = rnd(2);
406.  #if 0
407.  	    if(mdat == &mons[PM_COCKATRICE] && !uarmg
408.  #ifdef POLYSELF
409.  		&& !resists_ston(uasmon)
410.  #endif
411.  		) {
412.  
413.  		You("hit %s with your bare %s.",
414.  			mon_nam(mon), makeplural(body_part(HAND)));
415.  # ifdef POLYSELF
416.  		if(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))
417.  		    return TRUE;
418.  # endif
419.  		You("turn to stone...");
420.  		done_in_by(mon);
421.  		hittxt = TRUE; /* maybe lifesaved */
422.  	    }
423.  #endif
424.  	} else {
425.  	    if(obj->oclass == WEAPON_CLASS || obj->otyp == PICK_AXE ||
426.  	       obj->otyp == UNICORN_HORN || obj->oclass == ROCK_CLASS) {
427.  
428.  		/* If not a melee weapon, and either not thrown, or thrown */
429.  		/* and a bow (bows are >BOOMERANG), or thrown and a missile */
430.  		/* without a propellor (missiles are <DART), do 1-2 points */
431.  		if((obj->otyp >= BOW || obj->otyp < DART)
432.  			&& obj->otyp != PICK_AXE && obj->otyp != UNICORN_HORN
433.  			&& (!thrown ||
434.  			    (obj->oclass != ROCK_CLASS &&
435.  			    (obj->otyp > BOOMERANG ||
436.  				(obj->otyp < DART &&
437.  				    (!uwep ||
438.  				    objects[obj->otyp].w_propellor !=
439.  				    -objects[uwep->otyp].w_propellor)
440.  				))))) {
441.  		    if (mdat == &mons[PM_SHADE] && obj->otyp != SILVER_ARROW)
442.  			tmp = 0;
443.  		    else
444.  			tmp = rnd(2);
445.  		} else {
446.  		    tmp = dmgval(obj, mdat);
447.  		    if (obj->oartifact &&
448.  			artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) {
449.  			if(mon->mhp <= 0) /* artifact killed monster */
450.  			    return FALSE;
451.  			hittxt = TRUE;
452.  		    }
453.  		    if (objects[obj->otyp].oc_material == SILVER
454.  				&& hates_silver(mdat))
455.  			silvermsg = TRUE;
456.  		    if(!thrown && obj == uwep && obj->otyp == BOOMERANG &&
457.  		       !rnl(3)) {
458.  			pline("As you hit %s, %s breaks into splinters.",
459.  			      mon_nam(mon), the(xname(obj)));
460.  			useup(obj);
461.  			obj = (struct obj *) 0;
462.  			hittxt = TRUE;
463.  			if (mdat != &mons[PM_SHADE])
464.  			    tmp++;
465.  		    } else if(thrown &&
466.  			      (obj->otyp >= ARROW && obj->otyp <= SHURIKEN)) {
467.  			if(uwep && obj->otyp < DART &&
468.  			   objects[obj->otyp].w_propellor ==
469.  			   -objects[uwep->otyp].w_propellor) {
470.  			    /* Elves and Samurai do extra damage using
471.  			     * their bows&arrows; they're highly trained.
472.  			     */
473.  			    if (pl_character[0] == 'S' &&
474.  				obj->otyp == YA && uwep->otyp == YUMI)
475.  				tmp++;
476.  			    else if (pl_character[0] == 'E' &&
477.  				     obj->otyp == ELVEN_ARROW &&
478.  				     uwep->otyp == ELVEN_BOW)
479.  				tmp++;
480.  			}
481.  			if(((uwep && objects[obj->otyp].w_propellor ==
482.  				-objects[uwep->otyp].w_propellor)
483.  				|| obj->otyp==DART || obj->otyp==SHURIKEN) &&
484.  				obj->opoisoned)
485.  			    ispoisoned = TRUE;
486.  		    }
487.  		}
488.  	    } else if(obj->oclass == POTION_CLASS) {
489.  			if (obj->quan > 1L) setuwep(splitobj(obj, 1L));
490.  			else setuwep((struct obj *)0);
491.  			freeinv(obj);
492.  			potionhit(mon,obj);
493.  			hittxt = TRUE;
494.  			if (mdat == &mons[PM_SHADE])
495.  			    tmp = 0;
496.  			else
497.  			    tmp = 1;
498.  	    } else {
499.  		switch(obj->otyp) {
500.  		    case HEAVY_IRON_BALL:
501.  			tmp = rnd(25); break;
502.  		    case BOULDER:
503.  			tmp = rnd(20); break;
504.  		    case MIRROR:
505.  			You("break your mirror.  That's bad luck!");
506.  			change_luck(-2);
507.  			useup(obj);
508.  			obj = (struct obj *) 0;
509.  			hittxt = TRUE;
510.  			tmp = 1;
511.  			break;
512.  #ifdef TOURIST
513.  		    case EXPENSIVE_CAMERA:
514.  	You("succeed in destroying your camera.  Congratulations!");
515.  			useup(obj);
516.  			return(TRUE);
517.  #endif
518.  		    case CORPSE:		/* fixed by polder@cs.vu.nl */
519.  			if(obj->corpsenm == PM_COCKATRICE) {
520.  			    You("hit %s with the cockatrice corpse.",
521.  				  mon_nam(mon));
522.  			    if(resists_ston(mdat)) {
523.  				tmp = 1;
524.  				hittxt = TRUE;
525.  				break;
526.  			    }
527.  			    if(poly_when_stoned(mdat)) {
528.  				mon_to_stone(mon);
529.  				tmp = 1;
530.  				hittxt = TRUE;
531.  				break;
532.  			    }
533.  			    pline("%s turns to stone.", Monnam(mon));
534.  			    stoned = TRUE;
535.  			    xkilled(mon,0);
536.  			    return(FALSE);
537.  			}
538.  			tmp = mons[obj->corpsenm].msize + 1;
539.  			break;
540.  		    case EGG: /* only possible if hand-to-hand */
541.  			if(obj->corpsenm > -1
542.  					&& obj->corpsenm != PM_COCKATRICE
543.  					&& mdat == &mons[PM_COCKATRICE]) {
544.  				You("hit %s with the %s egg%s.",
545.  					mon_nam(mon),
546.  					mons[obj->corpsenm].mname,
547.  					plur(obj->quan));
548.  				hittxt = TRUE;
549.  				pline("The egg%sn't live any more...",
550.  					(obj->quan == 1L) ? " is" : "s are");
551.  				obj->otyp = ROCK;
552.  				obj->oclass = GEM_CLASS;
553.  				obj->known = obj->dknown = 0;
554.  				obj->owt = weight(obj);
555.  			}
556.  			tmp = 1;
557.  			break;
558.  		    case CLOVE_OF_GARLIC:	/* no effect against demons */
559.  			if(is_undead(mdat)) mon->mflee = 1;
560.  			tmp = 1;
561.  			break;
562.  		    case CREAM_PIE:
563.  #ifdef POLYSELF
564.  		    case BLINDING_VENOM:
565.  			if(Blind || !haseyes(mon->data))
566.  			    pline(obj->otyp==CREAM_PIE ? "Splat!" : "Splash!");
567.  			else if (obj->otyp == BLINDING_VENOM)
568.  			    pline("The venom blinds %s%s!", mon_nam(mon),
569.  					mon->mcansee ? "" : " further");
570.  #else
571.  			if(Blind) pline("Splat!");
572.  #endif
573.  			else
574.  			    pline("The cream pie splashes over %s%s!",
575.  				mon_nam(mon),
576.  				(haseyes(mdat) &&
577.  				    mdat != &mons[PM_FLOATING_EYE])
578.  				? (*(eos(mon_nam(mon))-1) == 's' ? "' face" :
579.  					 "'s face") : "");
580.  			if(mon->msleep) mon->msleep = 0;
581.  			setmangry(mon);
582.  			if(haseyes(mon->data)) {
583.  			    mon->mcansee = 0;
584.  			    tmp = rn1(25, 21);
585.  			    if(((int) mon->mblinded + tmp) > 127)
586.  				mon->mblinded = 127;
587.  			    else mon->mblinded += tmp;
588.  			}
589.  			hittxt = TRUE;
590.  			get_dmg_bonus = FALSE;
591.  			tmp = 0;
592.  			break;
593.  #ifdef POLYSELF
594.  		    case ACID_VENOM: /* only possible if thrown */
595.  			if(resists_acid(mdat)) {
596.  				Your("venom hits %s harmlessly.",
597.  					mon_nam(mon));
598.  				tmp = 0;
599.  			} else {
600.  				Your("venom burns %s!", mon_nam(mon));
601.  				tmp = dmgval(obj, mdat);
602.  			}
603.  			hittxt = TRUE;
604.  			get_dmg_bonus = FALSE;
605.  			break;
606.  #endif
607.  		    default:
608.  			/* non-weapons can damage because of their weight */
609.  			/* (but not too much) */
610.  			tmp = obj->owt/100;
611.  			if(tmp < 1) tmp = 1;
612.  			else tmp = rnd(tmp);
613.  			if(tmp > 6) tmp = 6;
614.  		}
615.  		if (mdat == &mons[PM_SHADE] && obj &&
616.  				objects[obj->otyp].oc_material != SILVER)
617.  		    tmp = 0;
618.  	    }
619.  	}
620.  
621.  	/****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG)
622.  	 *      *OR* if attacking bare-handed!! */
623.  
624.  	if (get_dmg_bonus && tmp) {
625.  		tmp += u.udaminc;
626.  		/* If you throw using a propellor, you don't get a strength
627.  		 * bonus but you do get an increase-damage bonus.
628.  		 */
629.  		if(!thrown || !obj || !uwep ||
630.  		   (obj->oclass != GEM_CLASS && obj->oclass != WEAPON_CLASS) ||
631.  		   !objects[obj->otyp].w_propellor ||
632.  		   (objects[obj->otyp].w_propellor !=
633.  				-objects[uwep->otyp].w_propellor))
634.  		    tmp += dbon();
635.  	}
636.  
637.  /* TODO:	Fix this up.  multiple engulf attacks now exist.
638.  	if(u.uswallow) {
639.  	    if((tmp -= u.uswldtim) <= 0) {
640.  		Your("%s are no longer able to hit.",
641.  			makeplural(body_part(ARM)));
642.  		return(TRUE);
643.  	    }
644.  	}
645.   */
646.  	if (ispoisoned) {
647.  	    if(resists_poison(mdat))
648.  		needpoismsg = TRUE;
649.  	    else if (rn2(10))
650.  		tmp += rnd(6);
651.  	    else poiskilled = TRUE;
652.  	}
653.  	if(tmp < 1)
654.  	    if (mdat == &mons[PM_SHADE]) {
655.  		Your("attack passes harmlessly through %s.",
656.  			mon_nam(mon));
657.  		hittxt = TRUE;
658.  	    } else
659.  		tmp = 1;
660.  
661.  	mon->mhp -= tmp;
662.  	if(mon->mhp < 1)
663.  		destroyed = TRUE;
664.  	if(mon->mtame && (!mon->mflee || mon->mfleetim)) {
665.  #ifdef SOUNDS
666.  		if (rn2(8)) yelp(mon);
667.  		else growl(mon); /* give them a moment's worry */
668.  #endif
669.  		mon->mtame--;
670.  		if(!mon->mtame) newsym(mon->mx, mon->my);
671.  		mon->mflee = TRUE;		/* Rick Richardson */
672.  		mon->mfleetim += 10*rnd(tmp);
673.  	}
674.  	if((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
675.  		   && obj && obj == uwep
676.  		   && objects[obj->otyp].oc_material == IRON
677.  		   && mon->mhp > 1 && !thrown && !mon->mcan
678.  		   /* && !destroyed  -- guaranteed by mhp > 1 */ ) {
679.  
680.  		if (clone_mon(mon)) {
681.  			pline("%s divides as you hit it!", Monnam(mon));
682.  			hittxt = TRUE;
683.  		}
684.  	}
685.  
686.  	if(!hittxt && !destroyed) {
687.  		if(thrown)
688.  		    /* thrown => obj exists */
689.  		    hit(xname(obj), mon, exclam(tmp) );
690.  		else if(!flags.verbose) You("hit it.");
691.  		else	You("hit %s%s", mon_nam(mon), canseemon(mon)
692.  			? exclam(tmp) : ".");
693.  	}
694.  
695.  	if (silvermsg) {
696.  		if (canseemon(mon) || sensemon(mon))
697.  			pline("The silver sears %s%s!",
698.  				mon_nam(mon),
699.  				noncorporeal(mdat) ? "" : 
700.  			          (*(eos(mon_nam(mon))-1) == 's' ?
701.  				       "' flesh" : "'s flesh"));
702.  		else
703.  			pline("It%s is seared!",
704.  				noncorporeal(mdat) ? "" : "s flesh");
705.  	}
706.  
707.  	if (needpoismsg)
708.  		pline("The poison doesn't seem to affect %s.", mon_nam(mon));
709.  	if (poiskilled) {
710.  		pline("The poison was deadly...");
711.  		xkilled(mon, 0);
712.  		return FALSE;
713.  	} else if (destroyed) {
714.  		killed(mon);	/* takes care of most messages */
715.  	} else if(u.umconf && !thrown) {
716.  		nohandglow(mon);
717.  		if(!mon->mconf && !resist(mon, '+', 0, NOTELL)) {
718.  			mon->mconf = 1;
719.  			if(!mon->mstun && mon->mcanmove && !mon->msleep &&
720.  			   !Blind)
721.  				pline("%s appears confused.", Monnam(mon));
722.  		}
723.  	}
724.  
725.  #if 0
726.  	if(mdat == &mons[PM_RUST_MONSTER] && obj && obj == uwep &&
727.  		is_rustprone(obj) && obj->oeroded < MAX_ERODE) {
728.  	    if (obj->greased)
729.  		grease_protect(obj,NULL,FALSE);
730.  	    else if (obj->oerodeproof || (obj->blessed && !rnl(4))) {
731.  	        if (flags.verbose)
732.  			pline("Somehow, your %s is not affected.",
733.  			      is_sword(obj) ? "sword" : "weapon");
734.  	    } else {
735.  		Your("%s%s!", aobjnam(obj, "rust"),
736.  		     obj->oeroded+1 == MAX_ERODE ? " completely" :
737.  		     obj->oeroded ? " further" : "");
738.  		obj->oeroded++;
739.  	    }
740.  	}
741.  #endif
742.  
743.  	return(destroyed ? FALSE : TRUE);
744.  }
745.  
746.  #ifdef POLYSELF
747.  
748.  int
749.  damageum(mdef, mattk)
750.  register struct monst *mdef;
751.  register struct attack *mattk;
752.  {
753.  	register struct permonst *pd = mdef->data;
754.  	register int	tmp = d((int)mattk->damn, (int)mattk->damd);
755.  
756.  	if (is_demon(uasmon) && !rn2(13) && !uwep
757.  		&& u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
758.  		&& u.umonnum != PM_BALROG) {
759.  	    struct monst *dtmp;
760.  	    pline("Some hell-p has arrived!");
761.  	    if((dtmp = makemon(!rn2(6) ? &mons[ndemon()] : uasmon, u.ux, u.uy)))
762.  		(void)tamedog(dtmp, (struct obj *)0);
763.  	    exercise(A_WIS, TRUE);
764.  	    return(0);
765.  	}
766.  
767.  	switch(mattk->adtyp) {
768.  	    case AD_STUN:
769.  		if(!Blind)
770.  		    pline("%s staggers for a moment.", Monnam(mdef));
771.  		mdef->mstun = 1;
772.  		/* fall through to next case */
773.  	    case AD_WERE:	    /* no effect on monsters */
774.  	    case AD_HEAL:
775.  	    case AD_LEGS:
776.  	    case AD_PHYS:
777.  		if(mattk->aatyp == AT_WEAP) {
778.  			if(uwep) tmp = 0;
779.  		} else if(mattk->aatyp == AT_KICK)
780.  			if(thick_skinned(mdef->data)) tmp = 0;
781.  		break;
782.  	    case AD_FIRE:
783.  		if(!Blind) pline("%s is on fire!", Monnam(mdef));
784.  		tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
785.  		tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
786.  		if(resists_fire(pd)) {
787.  		    if (!Blind)
788.  			pline("The fire doesn't heat %s!", mon_nam(mdef));
789.  		    golemeffects(mdef, AD_FIRE, tmp);
790.  		    shieldeff(mdef->mx, mdef->my);
791.  		    tmp = 0;
792.  		}
793.  		/* only potions damage resistant players in destroy_item */
794.  		tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
795.  		break;
796.  	    case AD_COLD:
797.  		if(!Blind) pline("%s is covered in frost!", Monnam(mdef));
798.  		if(resists_cold(pd)) {
799.  		    shieldeff(mdef->mx, mdef->my);
800.  		    if (!Blind)
801.  			pline("The frost doesn't chill %s!", mon_nam(mdef));
802.  		    golemeffects(mdef, AD_COLD, tmp);
803.  		    tmp = 0;
804.  		}
805.  		tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
806.  		break;
807.  	    case AD_ELEC:
808.  		if (!Blind) pline("%s is zapped!", Monnam(mdef));
809.  		tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
810.  		if(resists_elec(pd)) {
811.  		    if (!Blind)
812.  			pline("The zap doesn't shock %s!", mon_nam(mdef));
813.  		    golemeffects(mdef, AD_ELEC, tmp);
814.  		    shieldeff(mdef->mx, mdef->my);
815.  		    tmp = 0;
816.  		}
817.  		/* only rings damage resistant players in destroy_item */
818.  		tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
819.  		break;
820.  	    case AD_ACID:
821.  		if(resists_acid(pd)) tmp = 0;
822.  		break;
823.  	    case AD_STON:
824.  		if(poly_when_stoned(pd))
825.  		   mon_to_stone(mdef);
826.  		else if(!resists_ston(pd)) {
827.  		    stoned = TRUE;
828.  		    if(!Blind) pline("%s turns to stone.", Monnam(mdef));
829.  		    xkilled(mdef, 0);
830.  		    return(2);
831.  		}
832.  		tmp = 0;	/* no damage if this fails */
833.  		break;
834.  # ifdef SEDUCE
835.  	    case AD_SSEX:
836.  # endif
837.  	    case AD_SEDU:
838.  	    case AD_SITM:
839.  		if(mdef->minvent) {
840.  		    struct obj *otmp, *stealoid;
841.  
842.  		    stealoid = (struct obj *)0;
843.  		/* Without MUSE we can only change a monster's AC by stealing
844.  		 * armor with the "unarmored soldier" kludge.  With it there
845.  		 * are many monsters which wear armor, and all can be stripped.
846.  		 */
847.  		    if(
848.  #ifndef MUSE
849.  			is_mercenary(pd) &&
850.  #endif
851.  					could_seduce(&youmonst,mdef,mattk)){
852.  			for(otmp = mdef->minvent; otmp; otmp=otmp->nobj)
853.  #ifdef MUSE
854.  			    if (otmp->owornmask & W_ARM) stealoid = otmp;
855.  #else
856.  			    if (otmp->otyp >= PLATE_MAIL && otmp->otyp
857.  				<= ELVEN_CLOAK) stealoid = otmp;
858.  #endif
859.  		    }
860.  		    if (stealoid) {
861.  			boolean stolen = FALSE;
862.  			/* Is "he"/"his" always correct? */
863.  			if (gender(mdef) == u.mfemale &&
864.  						uasmon->mlet == S_NYMPH)
865.  	You("charm %s.  She gladly hands over her possessions.", mon_nam(mdef));
866.  			else
867.  		You("seduce %s and %s starts to take off %s clothes.",
868.  				mon_nam(mdef),
869.  				gender(mdef) ? "she" : "he",
870.  				gender(mdef) ? "her" : "his");
871.  			while(mdef->minvent) {
872.  				otmp = mdef->minvent;
873.  				mdef->minvent = otmp->nobj;
874.  				/* set dknown to insure proper merge */
875.  				if (!Blind) otmp->dknown = 1;
876.  #ifdef MUSE
877.  				otmp->owornmask = 0L;
878.  #endif
879.  				if (!stolen && otmp==stealoid) {
880.  				    otmp = hold_another_object(otmp,
881.  					      (const char *)0, (const char *)0,
882.  							      (const char *)0);
883.  				    stealoid = otmp;
884.  				    stolen = TRUE;
885.  				} else {
886.  				    otmp = hold_another_object(otmp,
887.  						 "You steal %s.", doname(otmp),
888.  								"You steal: ");
889.  				}
890.  			}
891.  			if (!stolen)
892.  				impossible("Player steal fails!");
893.  			else {
894.  				pline("%s finishes taking off %s suit.",
895.  				   Monnam(mdef), gender(mdef) ? "her" : "his");
896.  				You("steal %s!", doname(stealoid));
897.  # if defined(ARMY) && !defined(MUSE)
898.  				mdef->data = &mons[PM_UNARMORED_SOLDIER];
899.  # endif
900.  			}
901.  #ifdef MUSE
902.  			possibly_unwield(mdef);
903.  			mdef->misc_worn_check = 0L;
904.  #endif
905.  		   } else {
906.  			otmp = mdef->minvent;
907.  			mdef->minvent = otmp->nobj;
908.  			otmp = hold_another_object(otmp, "You steal %s.",
909.  						  doname(otmp), "You steal: ");
910.  #ifdef MUSE
911.  			possibly_unwield(mdef);
912.  			otmp->owornmask = 0L;
913.  #endif
914.  		   }
915.  		}
916.  		tmp = 0;
917.  		break;
918.  	    case AD_SGLD:
919.  		if (mdef->mgold) {
920.  		    u.ugold += mdef->mgold;
921.  		    mdef->mgold = 0;
922.  		    Your("purse feels heavier.");
923.  		}
924.  		exercise(A_DEX, TRUE);
925.  		tmp = 0;
926.  		break;
927.  	    case AD_TLPT:
928.  		if(tmp <= 0) tmp = 1;
929.  		if(tmp < mdef->mhp) {
930.  		    rloc(mdef);
931.  		    if(!Blind) pline("%s suddenly disappears!", Monnam(mdef));
932.  		}
933.  		break;
934.  	    case AD_BLND:
935.  		if(haseyes(pd)) {
936.  
937.  		    if(!Blind) pline("%s is blinded.", Monnam(mdef));
938.  		    mdef->mcansee = 0;
939.  		    mdef->mblinded += tmp;
940.  		}
941.  		tmp = 0;
942.  		break;
943.  	    case AD_CURS:
944.  		if (night() && !rn2(10) && !mdef->mcan) {
945.  		    if (mdef->data == &mons[PM_CLAY_GOLEM]) {
946.  			if (!Blind)
947.  			    pline("Some writing vanishes from %s head!",
948.  				s_suffix(mon_nam(mdef)));
949.  			xkilled(mdef, 0);
950.  			return 2;
951.  		    }
952.  		    mdef->mcan = 1;
953.  		    You("chuckle.");
954.  		}
955.  		tmp = 0;
956.  		break;
957.  	    case AD_DRLI:
958.  		if(rn2(2) && !resists_drli(pd)) {
959.  			int xtmp = d(2,6);
960.  			pline("%s suddenly seems weaker!", Monnam(mdef));
961.  			mdef->mhpmax -= xtmp;
962.  			if ((mdef->mhp -= xtmp) <= 0 || !mdef->m_lev--) {
963.  				pline("%s dies!", Monnam(mdef));
964.  				xkilled(mdef,0);
965.  				return(2);
966.  			}
967.  		}
968.  		tmp = 0;
969.  		break;
970.  	    case AD_RUST:
971.  		if (pd == &mons[PM_IRON_GOLEM]) {
972.  			pline("%s falls to pieces!", Monnam(mdef));
973.  			xkilled(mdef,0);
974.  			return(2);
975.  		}
976.  		tmp = 0;
977.  		break;
978.  	    case AD_DCAY:
979.  		if (pd == &mons[PM_WOOD_GOLEM] ||
980.  		    pd == &mons[PM_LEATHER_GOLEM]) {
981.  			pline("%s falls to pieces!", Monnam(mdef));
982.  			xkilled(mdef,0);
983.  			return(2);
984.  		}
985.  	    case AD_DRST:
986.  	    case AD_DRDX:
987.  	    case AD_DRCO:
988.  		if (!rn2(8)) {
989.  		    Your("%s was poisoned!", mattk->aatyp==AT_BITE ?
990.  			"bite" : "sting");
991.  		    if (resists_poison(mdef->data))
992.  			pline("The poison doesn't seem to affect %s.",
993.  				mon_nam(mdef));
994.  		    else {
995.  			if (!rn2(10)) {
996.  			    Your("poison was deadly...");
997.  			    tmp = mdef->mhp;
998.  			} else tmp += rn1(10,6);
999.  		    }
1000. 		}
1001. 		break;
1002. 	    case AD_DRIN:
1003. 		if (!has_head(mdef->data)) {
1004. 		    pline("%s doesn't seem harmed.", Monnam(mdef));
1005. 		    tmp = 0;
1006. 		    break;
1007. 		}
1008. #ifdef MUSE
1009. 		if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) {
1010. 		    pline("%s helmet blocks your attack to %s head.",
1011. 			  s_suffix(Monnam(mdef)),
1012. 			  (Blind || !humanoid(mdef->data)) ? "its" :
1013. 				(mdef->female ? "her" : "his"));
1014. 		    break;
1015. 		}
1016. #endif
1017. 		You("eat %s brain!", s_suffix(mon_nam(mdef)));
1018. 		if (mindless(mdef->data)) {
1019. 		    pline("%s doesn't notice.", Monnam(mdef));
1020. 		    break;
1021. 		}
1022. 		tmp += rnd(10);
1023. 		morehungry(-rnd(30)); /* cannot choke */
1024. 		if (ABASE(A_INT) < AMAX(A_INT)) {
1025. 			ABASE(A_INT) += rnd(4);
1026. 			if (ABASE(A_INT) > AMAX(A_INT))
1027. 				ABASE(A_INT) = AMAX(A_INT);
1028. 			flags.botl = 1;
1029. 		}
1030. 		exercise(A_WIS, TRUE);
1031. 		break;
1032. 	    case AD_WRAP:
1033. 	    case AD_STCK:
1034. 		if (!sticks(mdef->data))
1035. 		    u.ustuck = mdef; /* it's now stuck to you */
1036. 		break;
1037. 	    case AD_PLYS:
1038. 		if (mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) {
1039. 		    if (!Blind) pline("%s is frozen by you!", Monnam(mdef));
1040. 		    mdef->mcanmove = 0;
1041. 		    mdef->mfrozen = rnd(10);
1042. 		}
1043. 		break;
1044. 	    case AD_SLEE:
1045. 		if (!resists_sleep(mdef->data) && !mdef->msleep &&
1046. 							mdef->mcanmove) {
1047. 		    if (!Blind)
1048. 			pline("%s suddenly falls asleep!", Monnam(mdef));
1049. 		    mdef->mcanmove = 0;
1050. 		    mdef->mfrozen = rnd(10);
1051. 		}
1052. 		break;
1053. 	    default:	tmp = 0;
1054. 			break;
1055. 	}
1056. 	if(!tmp) return(1);
1057. 
1058. 	if((mdef->mhp -= tmp) < 1) {
1059. 
1060. 	    if (mdef->mtame && !cansee(mdef->mx,mdef->my)) {
1061. 		You("feel embarrassed for a moment.");
1062. 		xkilled(mdef, 0);
1063. 	    } else if (!flags.verbose) {
1064. 		You("destroy it!");
1065. 		xkilled(mdef, 0);
1066. 	    } else
1067. 		killed(mdef);
1068. 	    return(2);
1069. 	}
1070. 	return(1);
1071. }
1072. 
1073. static int
1074. explum(mdef, mattk)
1075. register struct monst *mdef;
1076. register struct attack *mattk;
1077. {
1078. 	register int tmp = d((int)mattk->damn, (int)mattk->damd);
1079. 
1080. 	You("explode!");
1081. 	switch(mattk->adtyp) {
1082. 	    case AD_BLND:
1083. 		if (haseyes(mdef->data)) {
1084. 		    pline("%s is blinded by your flash of light!", Monnam(mdef));
1085. 		    if (mdef->mcansee) {
1086. 			mdef->mblinded += tmp;
1087. 			mdef->mcansee = 0;
1088. 		    }
1089. 		}
1090. 		break;
1091. 	    case AD_COLD:
1092. 		if (!resists_cold(mdef->data)) {
1093. 		    pline("%s gets blasted!", Monnam(mdef));
1094. 		    mdef->mhp -= tmp;
1095. 		    if (mdef->mhp <= 0) {
1096. 			 killed(mdef);
1097. 			 return(2);
1098. 		    }
1099. 		} else {
1100. 		    shieldeff(mdef->mx, mdef->my);
1101. 		    if (is_golem(mdef->data))
1102. 			golemeffects(mdef, AD_COLD, tmp);
1103. 		    else
1104. 			pline("The blast doesn't seem to affect %s.",
1105. 				mon_nam(mdef));
1106. 		}
1107. 		break;
1108. 	    default:
1109. 		break;
1110. 	}
1111. 	return(1);
1112. }
1113. 
1114. static int
1115. gulpum(mdef,mattk)
1116. register struct monst *mdef;
1117. register struct attack *mattk;
1118. {
1119. 	register int tmp;
1120. 	register int dam = d((int)mattk->damn, (int)mattk->damd);
1121. 	/* Not totally the same as for real monsters.  Specifically, these
1122. 	 * don't take multiple moves.  (It's just too hard, for too little
1123. 	 * result, to program monsters which attack from inside you, which
1124. 	 * would be necessary if done accurately.)  Instead, we arbitrarily
1125. 	 * kill the monster immediately for AD_DGST and we regurgitate them
1126. 	 * after exactly 1 round of attack otherwise.  -KAA
1127. 	 */
1128. 
1129. 	if(mdef->data->msize >= MZ_HUGE) return 0;
1130. 
1131. 	if(u.uhunger < 1500 && !u.uswallow) {
1132. 
1133. 	    if(mdef->data->mlet != S_COCKATRICE) {
1134. # ifdef LINT	/* static char msgbuf[BUFSZ]; */
1135. 		char msgbuf[BUFSZ];
1136. # else
1137. 		static char msgbuf[BUFSZ];
1138. # endif
1139. /* TODO: get the symbol display also to work (monster symbol is removed from
1140.  * the screen and you moved onto it, then you get moved back and it gets
1141.  * moved back if the monster survives--just like when monsters swallow you.
1142.  */
1143. 		You("engulf %s!", mon_nam(mdef));
1144. 		switch(mattk->adtyp) {
1145. 		    case AD_DGST:
1146. 			u.uhunger += mdef->data->cnutrit;
1147. 			newuhs(FALSE);
1148. 			xkilled(mdef,2);
1149. 			Sprintf(msgbuf, "You totally digest %s.",
1150. 					mon_nam(mdef));
1151. 			if ((tmp = 3 + (mdef->data->cwt >> 6)) != 0) {
1152. 			    You("digest %s.", mon_nam(mdef));
1153. 			    nomul(-tmp);
1154. 			    nomovemsg = msgbuf;
1155. 			} else pline(msgbuf);
1156. 			exercise(A_CON, TRUE);
1157. 			return(2);
1158. 		    case AD_PHYS:
1159. 			pline("%s is pummeled with your debris!",Monnam(mdef));
1160. 			break;
1161. 		    case AD_ACID:
1162. 			pline("%s is covered with your goo!", Monnam(mdef));
1163. 			if (resists_acid(mdef->data)) {
1164. 			    pline("It seems harmless to %s.", mon_nam(mdef));
1165. 			    dam = 0;
1166. 			}
1167. 			break;
1168. 		    case AD_BLND:
1169. 			if(haseyes(mdef->data)) {
1170. 			    if (mdef->mcansee)
1171. 				pline("%s can't see in there!", Monnam(mdef));
1172. 			    mdef->mcansee = 0;
1173. 			    dam += mdef->mblinded;
1174. 			    if (dam > 127) dam = 127;
1175. 			    mdef->mblinded = dam;
1176. 			}
1177. 			dam = 0;
1178. 			break;
1179. 		    case AD_ELEC:
1180. 			if (rn2(2)) {
1181. 			    pline("The air around %s crackles with electricity.", mon_nam(mdef));
1182. 			    if (resists_elec(mdef->data)) {
1183. 				pline("%s seems unhurt.", Monnam(mdef));
1184. 				dam = 0;
1185. 			    }
1186. 			    golemeffects(mdef,(int)mattk->adtyp,dam);
1187. 			} else dam = 0;
1188. 			break;
1189. 		    case AD_COLD:
1190. 			if (rn2(2)) {
1191. 			    if (resists_cold(mdef->data)) {
1192. 				pline("%s seems mildly chilly.", Monnam(mdef));
1193. 				dam = 0;
1194. 			    } else
1195. 				pline("%s is freezing to death!",Monnam(mdef));
1196. 			    golemeffects(mdef,(int)mattk->adtyp,dam);
1197. 			} else dam = 0;
1198. 			break;
1199. 		    case AD_FIRE:
1200. 			if (rn2(2)) {
1201. 			    if (resists_fire(mdef->data)) {
1202. 				pline("%s seems mildly hot.", Monnam(mdef));
1203. 				dam = 0;
1204. 			    } else
1205. 				pline("%s is burning to a crisp!",Monnam(mdef));
1206. 			    golemeffects(mdef,(int)mattk->adtyp,dam);
1207. 			} else dam = 0;
1208. 			break;
1209. 		}
1210. 		if ((mdef->mhp -= dam) <= 0) {
1211. 		    killed(mdef);
1212. 		    return(2);
1213. 		}
1214. 		You("%s %s!", is_animal(uasmon) ? "regurgitate"
1215. 			: "expel", mon_nam(mdef));
1216. 		if (is_animal(uasmon)) {
1217. 		    pline("Obviously, you didn't like %s taste.",
1218. 			  s_suffix(mon_nam(mdef)));
1219. 		}
1220. 	    } else {
1221. 		You("bite into %s", mon_nam(mdef));
1222. 		You("turn to stone...");
1223. 		killer_format = KILLED_BY;
1224. 		killer = "swallowing a cockatrice whole";
1225. 		done(STONING);
1226. 	    }
1227. 	}
1228. 	return(0);
1229. }
1230. 
1231. void
1232. missum(mdef,mattk)
1233. register struct monst *mdef;
1234. register struct attack *mattk;
1235. {
1236. 	if (could_seduce(&youmonst, mdef, mattk))
1237. 		You("pretend to be friendly to %s.", mon_nam(mdef));
1238. 	else if(!Blind && flags.verbose)
1239. 		You("miss %s.", mon_nam(mdef));
1240. 	else
1241. 		You("miss it.");
1242. 	wakeup(mdef);
1243. }
1244. 
1245. static boolean
1246. hmonas(mon, tmp)		/* attack monster as a monster. */
1247. register struct monst *mon;
1248. register int tmp;
1249. {
1250. 	register struct attack *mattk;
1251. 	int	i, sum[NATTK];
1252. 	int	nsum = 0;
1253. 	schar	dhit;
1254. 
1255. #ifdef GCC_WARN
1256. 	dhit = 0;
1257. #endif
1258. 
1259. 	for(i = 0; i < NATTK; i++) {
1260. 
1261. 	    sum[i] = 0;
1262. 	    mattk = &(uasmon->mattk[i]);
1263. 	    switch(mattk->aatyp) {
1264. 		case AT_WEAP:
1265. use_weapon:
1266. 	/* Certain monsters don't use weapons when encountered as enemies,
1267. 	 * but players who polymorph into them have hands or claws and thus
1268. 	 * should be able to use weapons.  This shouldn't prohibit the use
1269. 	 * of most special abilities, either.
1270. 	 */
1271. 	/* Potential problem: if the monster gets multiple weapon attacks,
1272. 	 * we currently allow the player to get each of these as a weapon
1273. 	 * attack.  Is this really desirable?
1274. 	 */
1275. 			if(uwep) tmp += hitval(uwep, mon->data);
1276. 			dhit = (tmp > (dieroll = rnd(20)) || u.uswallow);
1277. 			/* Enemy dead, before any special abilities used */
1278. 			if (!known_hitum(mon,dhit)) return 0;
1279. 			/* might be a worm that gets cut in half */
1280. 			if (m_at(u.ux+u.dx, u.uy+u.dy) != mon) return(nsum);
1281. 			/* Do not print "You hit" message, since known_hitum
1282. 			 * already did it.
1283. 			 */
1284. 			if (dhit && mattk->adtyp != AD_SPEL
1285. 				&& mattk->adtyp != AD_PHYS)
1286. 				sum[i] = damageum(mon,mattk);
1287. 			break;
1288. 		case AT_CLAW:
1289. 			if (i==0 && uwep && !cantwield(uasmon)) goto use_weapon;
1290. # ifdef SEDUCE
1291. 			/* succubi/incubi are humanoid, but their _second_
1292. 			 * attack is AT_CLAW, not their first...
1293. 			 */
1294. 			if (i==1 && uwep && (u.umonnum == PM_SUCCUBUS ||
1295. 				u.umonnum == PM_INCUBUS)) goto use_weapon;
1296. # endif
1297. 		case AT_KICK:
1298. 		case AT_BITE:
1299. 		case AT_STNG:
1300. 		case AT_TUCH:
1301. 		case AT_BUTT:
1302. 		case AT_TENT:
1303. 			if (i==0 && uwep && (u.usym==S_LICH)) goto use_weapon;
1304. 			if ((dhit = (tmp > rnd(20) || u.uswallow)) != 0) {
1305. 			    int compat;
1306. 
1307. 			    if (!u.uswallow &&
1308. 				(compat=could_seduce(&youmonst, mon, mattk))) {
1309. 				You("%s %s %s.",
1310. 				    mon->mcansee && haseyes(mon->data)
1311. 				    ? "smile at" : "talk to",
1312. 				    mon_nam(mon),
1313. 				    compat == 2 ? "engagingly":"seductively");
1314. 				/* doesn't anger it; no wakeup() */
1315. 				sum[i] = damageum(mon, mattk);
1316. 				break;
1317. 			    }
1318. 			    wakeup(mon);
1319. 			    if (mon->data == &mons[PM_SHADE]) {
1320. 				Your("attack passes harmlessly through %s.",
1321. 				    mon_nam(mon));
1322. 				break;
1323. 			    }
1324. 			    if (mattk->aatyp == AT_KICK)
1325. 				    You("kick %s.", mon_nam(mon));
1326. 			    else if (mattk->aatyp == AT_BITE)
1327. 				    You("bite %s.", mon_nam(mon));
1328. 			    else if (mattk->aatyp == AT_STNG)
1329. 				    You("sting %s.", mon_nam(mon));
1330. 			    else if (mattk->aatyp == AT_BUTT)
1331. 				    You("butt %s.", mon_nam(mon));
1332. 			    else if (mattk->aatyp == AT_TUCH)
1333. 				    You("touch %s.", mon_nam(mon));
1334. 			    else if (mattk->aatyp == AT_TENT)
1335. 				    Your("tentacles suck %s.", mon_nam(mon));
1336. 			    else You("hit %s.", mon_nam(mon));
1337. 			    sum[i] = damageum(mon, mattk);
1338. 			} else
1339. 			    missum(mon, mattk);
1340. 			break;
1341. 
1342. 		case AT_HUGS:
1343. 			/* automatic if prev two attacks succeed, or if
1344. 			 * already grabbed in a previous attack
1345. 			 */
1346. 			dhit = 1;
1347. 			wakeup(mon);
1348. 			if (mon->data == &mons[PM_SHADE])
1349. 			    Your("hug passes harmlessly through %s.",
1350. 				mon_nam(mon));
1351. 			else if (!sticks(mon->data))
1352. 			    if (mon==u.ustuck) {
1353. 				pline("%s is being %s.", Monnam(mon),
1354. 				    u.umonnum==PM_ROPE_GOLEM ? "choked":
1355. 				    "crushed");
1356. 				sum[i] = damageum(mon, mattk);
1357. 			    } else if(sum[i-1] && sum[i-2]) {
1358. 				You("grab %s!", mon_nam(mon));
1359. 				u.ustuck = mon;
1360. 				sum[i] = damageum(mon, mattk);
1361. 			    }
1362. 			break;
1363. 
1364. 		case AT_EXPL:	/* automatic hit if next to */
1365. 			dhit = -1;
1366. 			wakeup(mon);
1367. 			sum[i] = explum(mon, mattk);
1368. 			break;
1369. 
1370. 		case AT_ENGL:
1371. 			if((dhit = (tmp > rnd(20+i)))) {
1372. 				wakeup(mon);
1373. 				if (mon->data == &mons[PM_SHADE])
1374. 				    Your("attempt to surround %s is harmless.",
1375. 					mon_nam(mon));
1376. 				else
1377. 				    sum[i]= gulpum(mon,mattk);
1378. 			} else
1379. 				missum(mon, mattk);
1380. 			break;
1381. 
1382. 		case AT_MAGC:
1383. 			/* No check for uwep; if wielding nothing we want to
1384. 			 * do the normal 1-2 points bare hand damage...
1385. 			 */
1386. 			if (i==0 && (u.usym==S_KOBOLD
1387. 				|| u.usym==S_ORC
1388. 				|| u.usym==S_GNOME
1389. 				)) goto use_weapon;
1390. 
1391. 		case AT_NONE:
1392. 			continue;
1393. 			/* Not break--avoid passive attacks from enemy */
1394. 
1395. 		case AT_BREA:
1396. 		case AT_SPIT:
1397. 		case AT_GAZE:	/* all done using #monster command */
1398. 			dhit = 0;
1399. 			break;
1400. 
1401. 		default: /* Strange... */
1402. 			impossible("strange attack of yours (%d)",
1403. 				 mattk->aatyp);
1404. 	    }
1405. 	    if (dhit == -1)
1406. 		rehumanize();
1407. 	    if(sum[i] == 2) return(passive(mon, 1, 0, (mattk->aatyp==AT_KICK)));
1408. 							/* defender dead */
1409. 	    else {
1410. 		(void) passive(mon, sum[i], 1, (mattk->aatyp==AT_KICK));
1411. 		nsum |= sum[i];
1412. 	    }
1413. 	    if (uasmon == &playermon)
1414. 		break; /* No extra attacks if no longer a monster */
1415. 	    if (multi < 0)
1416. 		break; /* If paralyzed while attacking, i.e. floating eye */
1417. 	}
1418. 	return(nsum);
1419. }
1420. 
1421. #endif /* POLYSELF */
1422. 
1423. /*	Special (passive) attacks on you by monsters done here.		*/
1424. 
1425. int
1426. passive(mon, mhit, malive, kicked)
1427. register struct monst *mon;
1428. register boolean mhit;
1429. register int malive;
1430. boolean kicked;
1431. {
1432. 	register struct permonst *ptr = mon->data;
1433. 	register int i, tmp;
1434. 
1435. 	for(i = 0; ; i++) {
1436. 	    if(i >= NATTK) return(malive | mhit);	/* no passive attacks */
1437. 	    if(ptr->mattk[i].aatyp == AT_NONE) break;	/* try this one */
1438. 	}
1439. 	/* Note: tmp not always used */
1440. 	if (ptr->mattk[i].damn)
1441. 	    tmp = d((int)ptr->mattk[i].damn, (int)ptr->mattk[i].damd);
1442. 	else if(ptr->mattk[i].damd)
1443. 	    tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd);
1444. 	else
1445. 	    tmp = 0;
1446. 
1447. /*	These affect you even if they just died */
1448. 
1449. 	switch(ptr->mattk[i].adtyp) {
1450. 
1451. 	  case AD_ACID:
1452. 	    if(mhit && rn2(2)) {
1453. 		if (Blind || !flags.verbose) You("are splashed!");
1454. 		else	You("are splashed by %s acid!", 
1455. 			                s_suffix(mon_nam(mon)));
1456. 
1457. #ifdef POLYSELF
1458. 		if(!resists_acid(uasmon))
1459. #endif
1460. 			mdamageu(mon, tmp);
1461. 		if(!rn2(30)) erode_armor(TRUE);
1462. 	    }
1463. 	    if(mhit && !rn2(6)) {
1464. 		if (kicked) {
1465. 		    if (uarmf)
1466. 			(void) rust_dmg(uarmf, xname(uarmf), 3, TRUE);
1467. 		} else erode_weapon(TRUE);
1468. 	    }
1469. 	    exercise(A_STR, FALSE);
1470. 	    break;
1471. 	  case AD_STON:
1472. 	    if(mhit)
1473. 	      if (!kicked)
1474. 		if (!uwep && !uarmg
1475. #ifdef POLYSELF
1476. 		    && !resists_ston(uasmon)
1477. 		    && !(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))
1478. #endif
1479. 		   ) {
1480. 		    You("turn to stone...");
1481. 		    done_in_by(mon);
1482. 		    return 2;
1483. 		}
1484. 	    break;
1485. 	  case AD_RUST:
1486. 	    if(mhit && !mon->mcan)
1487. 	      if (kicked) {
1488. 		if (uarmf)
1489. 		    (void) rust_dmg(uarmf, xname(uarmf), 1, TRUE);
1490. 	      } else
1491. 		erode_weapon(FALSE);
1492. 	    break;
1493. 	  case AD_MAGM:
1494. 	    /* wrath of gods for attacking Oracle */
1495. 	    if(Antimagic) {
1496. 		shieldeff(u.ux, u.uy);
1497. 		pline("A hail of magic missiles narrowly misses you!");
1498. 	    } else {
1499. 		You("are hit by magic missiles appearing from thin air!");
1500. 		mdamageu(mon, tmp);
1501. 	    }
1502. 	    break;
1503. 	  default:
1504. 	    break;
1505. 	}
1506. 
1507. /*	These only affect you if they still live */
1508. 
1509. 	if(malive && !mon->mcan && rn2(3)) {
1510. 
1511. 	    switch(ptr->mattk[i].adtyp) {
1512. 
1513. 	      case AD_PLYS:
1514. 		if(ptr == &mons[PM_FLOATING_EYE]) {
1515. 		    if (!canseemon(mon)) {
1516. 			break;
1517. 		    }
1518. 		    if(mon->mcansee) {
1519. 			if(Reflecting & W_AMUL) {
1520. 			    makeknown(AMULET_OF_REFLECTION);
1521. 			    pline("%s gaze is reflected by your medallion.",
1522. 				  s_suffix(Monnam(mon)));
1523. 			} else if(Reflecting & W_ARMS) {
1524. 			    makeknown(SHIELD_OF_REFLECTION);
1525. 			    pline("%s gaze is reflected by your shield.",
1526. 				  s_suffix(Monnam(mon)));
1527. 			} else {
1528. 			    You("are frozen by %s gaze!", 
1529. 				  s_suffix(mon_nam(mon)));
1530. 			    nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -120);
1531. 			}
1532. 		    } else {
1533. 			pline("%s cannot defend itself.",
1534. 				Adjmonnam(mon,"blind"));
1535. 			if(!rn2(500)) change_luck(-1);
1536. 		    }
1537. 		} else { /* gelatinous cube */
1538. 		    You("are frozen by %s!", mon_nam(mon));
1539. 		    nomul(-tmp);
1540. 		    exercise(A_DEX, FALSE);
1541. 		}
1542. 		break;
1543. 	      case AD_COLD:		/* brown mold or blue jelly */
1544. 		if(monnear(mon, u.ux, u.uy)) {
1545. 		    if(Cold_resistance) {
1546.   			shieldeff(u.ux, u.uy);
1547. 			You("feel a mild chill.");
1548. #ifdef POLYSELF
1549. 			ugolemeffects(AD_COLD, tmp);
1550. #endif
1551. 			break;
1552. 		    }
1553. 		    You("are suddenly very cold!");
1554. 		    mdamageu(mon, tmp);
1555. 		/* monster gets stronger with your heat! */
1556. 		    mon->mhp += tmp / 2;
1557. 		    if (mon->mhpmax < mon->mhp) mon->mhpmax = mon->mhp;
1558. 		/* at a certain point, the monster will reproduce! */
1559. 		    if(mon->mhpmax > ((int) (mon->m_lev+1) * 8)) {
1560. 			register struct monst *mtmp;
1561. 
1562. 			if ((mtmp = clone_mon(mon)) != 0) {
1563. 			    mtmp->mhpmax = mon->mhpmax /= 2;
1564. 			    if(!Blind)
1565. 				pline("%s multiplies from your heat!",
1566. 								Monnam(mon));
1567. 			}
1568. 		    }
1569. 		}
1570. 		break;
1571. 	      case AD_STUN:		/* specifically yellow mold */
1572. 		if(!Stunned)
1573. 		    make_stunned((long)tmp, TRUE);
1574. 		break;
1575. 	      case AD_FIRE:
1576. 		if(monnear(mon, u.ux, u.uy)) {
1577. 		    if(Fire_resistance) {
1578. 			shieldeff(u.ux, u.uy);
1579. 			You("feel mildly warm.");
1580. #ifdef POLYSELF
1581. 			ugolemeffects(AD_FIRE, tmp);
1582. #endif
1583. 			break;
1584. 		    }
1585. 		    You("are suddenly very hot!");
1586. 		    mdamageu(mon, tmp);
1587. 		}
1588. 		break;
1589. 	      case AD_ELEC:
1590. 		if(Shock_resistance) {
1591. 		    shieldeff(u.ux, u.uy);
1592. 		    You("feel a mild tingle.");
1593. #ifdef POLYSELF
1594. 		    ugolemeffects(AD_ELEC, tmp);
1595. #endif
1596. 		    break;
1597. 		}
1598. 		You("are jolted with electricity!");
1599. 		mdamageu(mon, tmp);
1600. 		break;
1601. 	      default:
1602. 		break;
1603. 	    }
1604. 	}
1605. 	return(malive | mhit);
1606. }
1607. 
1608. /* Note: caller must ascertain mtmp is mimicing... */
1609. void
1610. stumble_onto_mimic(mtmp)
1611. register struct monst *mtmp;
1612. {
1613. 	if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK))
1614. 	    u.ustuck = mtmp;
1615. 	if (Blind) {
1616. 	    if(!Telepat)
1617. 		pline("Wait!  That's a monster!");
1618. 	} else if (glyph_is_cmap(levl[u.ux+u.dx][u.uy+u.dy].glyph) &&
1619. 		(glyph_to_cmap(levl[u.ux+u.dx][u.uy+u.dy].glyph) == S_hcdoor ||
1620. 		 glyph_to_cmap(levl[u.ux+u.dx][u.uy+u.dy].glyph) == S_vcdoor))
1621. 	    pline("The door actually was %s!", a_monnam(mtmp));
1622. 	else if (glyph_is_object(levl[u.ux+u.dx][u.uy+u.dy].glyph) &&
1623. 		glyph_to_obj(levl[u.ux+u.dx][u.uy+u.dy].glyph) == GOLD_PIECE)
1624. 	    pline("That gold was %s!", a_monnam(mtmp));
1625. 	else {
1626. 	    pline("Wait!  That's %s!", a_monnam(mtmp));
1627. 	}
1628. 
1629. 	wakeup(mtmp);	/* clears mimicing */
1630. }
1631. 
1632. static void
1633. nohandglow(mon)
1634. struct monst *mon;
1635. {
1636. 	char *hands=makeplural(body_part(HAND));
1637. 
1638. 	if (!u.umconf || mon->mconf) return;
1639. 	if (u.umconf == 1) {
1640. 		if (Blind)
1641. 			Your("%s stop tingling.", hands);
1642. 		else
1643. 			Your("%s stop glowing %s.", hands,
1644. 				Hallucination ? hcolor() : red);
1645. 	} else {
1646. 		if (Blind)
1647. 			pline("The tingling in your %s lessens.", hands);
1648. 		else
1649. 			Your("%s no longer glow so brightly %s.", hands,
1650. 				Hallucination ? hcolor() : red);
1651. 	}
1652. 	u.umconf--;
1653. }
1654. 
1655. /*uhitm.c*/

Also on Fandom

Random Wiki