1 /*	SCCS Id: @(#)muse.c	3.4	2002/12/23	*/
2 /*	Copyright (C) 1990 by Ken Arromdee			   */
3 /* NetHack may be freely redistributed.  See license for details.  */
4 
5 /*
6  * Monster item usage routines.
7  */
8 
9 #include "hack.h"
10 #include "edog.h"
11 
12 extern const int monstr[];
13 
14 boolean m_using = FALSE;
15 
16 /* Let monsters use magic items.  Arbitrary assumptions: Monsters only use
17  * scrolls when they can see, monsters know when wands have 0 charges, monsters
18  * cannot recognize if items are cursed are not, monsters which are confused
19  * don't know not to read scrolls, etc....
20  */
21 
22 STATIC_DCL struct permonst *FDECL(muse_newcham_mon, (struct monst *));
23 STATIC_DCL int FDECL(precheck, (struct monst *,struct obj *));
24 STATIC_DCL void FDECL(mzapmsg, (struct monst *,struct obj *,BOOLEAN_P));
25 STATIC_DCL void FDECL(mreadmsg, (struct monst *,struct obj *));
26 STATIC_DCL void FDECL(mquaffmsg, (struct monst *,struct obj *));
27 STATIC_PTR int FDECL(mbhitm, (struct monst *,struct obj *));
28 STATIC_DCL void FDECL(mbhit,
29 	(struct monst *,int,int FDECL((*),(MONST_P,OBJ_P)),
30 	int FDECL((*),(OBJ_P,OBJ_P)),struct obj *));
31 STATIC_DCL void FDECL(you_aggravate, (struct monst *));
32 STATIC_DCL void FDECL(mon_consume_unstone, (struct monst *,struct obj *,
33 	BOOLEAN_P,BOOLEAN_P));
34 
35 static struct musable {
36 	struct obj *offensive;
37 	struct obj *defensive;
38 	struct obj *misc;
39 	int has_offense, has_defense, has_misc;
40 	/* =0, no capability; otherwise, different numbers.
41 	 * If it's an object, the object is also set (it's 0 otherwise).
42 	 */
43 } m;
44 static int trapx, trapy;
45 static boolean zap_oseen;
46 	/* for wands which use mbhitm and are zapped at players.  We usually
47 	 * want an oseen local to the function, but this is impossible since the
48 	 * function mbhitm has to be compatible with the normal zap routines,
49 	 * and those routines don't remember who zapped the wand.
50 	 */
51 
52 /* Any preliminary checks which may result in the monster being unable to use
53  * the item.  Returns 0 if nothing happened, 2 if the monster can't do anything
54  * (i.e. it teleported) and 1 if it's dead.
55  */
56 STATIC_OVL int
precheck(mon,obj)57 precheck(mon, obj)
58 struct monst *mon;
59 struct obj *obj;
60 {
61 	boolean vis;
62 
63 	if (!obj) return 0;
64 	vis = cansee(mon->mx, mon->my);
65 
66 	if (obj->oclass == POTION_CLASS) {
67 	    coord cc;
68 	    static const char *empty = "The potion turns out to be empty.";
69 	    const char *potion_descr;
70 	    struct monst *mtmp;
71 #define POTION_OCCUPANT_CHANCE(n) (13 + 2*(n))	/* also in potion.c */
72 
73 	    potion_descr = OBJ_DESCR(objects[obj->otyp]);
74 	    if (potion_descr && !strcmp(potion_descr, "milky")) {
75 	        if ( flags.ghost_count < MAXMONNO &&
76 		    !rn2(POTION_OCCUPANT_CHANCE(flags.ghost_count))) {
77 		    if (!enexto(&cc, mon->mx, mon->my, &mons[PM_GHOST])) return 0;
78 		    mquaffmsg(mon, obj);
79 		    m_useup(mon, obj);
80 		    mtmp = makemon(&mons[PM_GHOST], cc.x, cc.y, NO_MM_FLAGS);
81 		    if (!mtmp) {
82 			if (vis) pline("%s", empty);
83 		    } else {
84 			if (vis) {
85 			    pline("As %s opens the bottle, an enormous %s emerges!",
86 			       mon_nam(mon),
87 			       Hallucination ? rndmonnam() : (const char *)"ghost");
88 			    pline("%s is frightened to death, and unable to move.",
89 				    Monnam(mon));
90 			}
91 			mon->mcanmove = 0;
92 			mon->mfrozen = 3;
93 		    }
94 		    return 2;
95 		}
96 	    }
97 	    if (potion_descr && !strcmp(potion_descr, "smoky") &&
98 		    flags.djinni_count < MAXMONNO &&
99 		    !rn2(POTION_OCCUPANT_CHANCE(flags.djinni_count))) {
100 		if (!enexto(&cc, mon->mx, mon->my, &mons[PM_DJINNI])) return 0;
101 		mquaffmsg(mon, obj);
102 		m_useup(mon, obj);
103 		mtmp = makemon(&mons[PM_DJINNI], cc.x, cc.y, NO_MM_FLAGS);
104 		if (!mtmp) {
105 		    if (vis) pline("%s", empty);
106 		} else {
107 		    if (vis)
108 			pline("In a cloud of smoke, %s emerges!",
109 							a_monnam(mtmp));
110 		    pline("%s speaks.", vis ? Monnam(mtmp) : Something);
111 		/* I suspect few players will be upset that monsters */
112 		/* can't wish for wands of death here.... */
113 		    if (rn2(2)) {
114 			verbalize("You freed me!");
115 			mtmp->mpeaceful = 1;
116 			set_malign(mtmp);
117 		    } else {
118 			verbalize("It is about time.");
119 			if (vis) pline("%s vanishes.", Monnam(mtmp));
120 			mongone(mtmp);
121 		    }
122 		}
123 		return 2;
124 	    }
125 	}
126 	/* same probability for blowing up a cursed wand as in dozap()
127 	 * for the player */
128 	if (obj->oclass == WAND_CLASS && obj->cursed && !rn2(30)) {
129 	    int dam = d(obj->spe+2, 6);
130 
131 	    if (flags.soundok) {
132 		if (vis) pline("%s %s %s, which suddenly explodes!",
133 		    Monnam(mon), is_weeping(mon->data) ? "is zapping" : "zaps", an(xname(obj)));
134 		else You_hear("a zap and an explosion in the distance.");
135 	    }
136 	    m_useup(mon, obj);
137 	    if (mon->mhp <= dam) {
138 		monkilled(mon, "", AD_RBRE);
139 		return 1;
140 	    }
141 	    else mon->mhp -= dam;
142 	    m.has_defense = m.has_offense = m.has_misc = 0;
143 	    /* Only one needed to be set to 0 but the others are harmless */
144 	}
145 	return 0;
146 }
147 
148 STATIC_OVL void
mzapmsg(mtmp,otmp,self)149 mzapmsg(mtmp, otmp, self)
150 struct monst *mtmp;
151 struct obj *otmp;
152 boolean self;
153 {
154 	if (!canseemon(mtmp)) {
155 		if (flags.soundok)
156 			You_hear("a %s zap.",
157 					(distu(mtmp->mx,mtmp->my) <= (BOLT_LIM+1)*(BOLT_LIM+1)) ?
158 					"nearby" : "distant");
159 	} else if (self)
160 		pline("%s %s %sself with %s!", Monnam(mtmp),
161 		    is_weeping(mtmp->data) ? "is zapping" : "zaps", mhim(mtmp), doname(otmp));
162 	else {
163 		pline("%s %s %s!", Monnam(mtmp),
164 		    is_weeping(mtmp->data) ? "is zapping" : "zaps", an(xname(otmp)));
165 		stop_occupation();
166 	}
167 }
168 
169 STATIC_OVL void
mreadmsg(mtmp,otmp)170 mreadmsg(mtmp, otmp)
171 struct monst *mtmp;
172 struct obj *otmp;
173 {
174 	boolean vismon = canseemon(mtmp);
175 	char onambuf[BUFSZ];
176 	short saverole;
177 	unsigned savebknown;
178 
179 	if (!vismon && !flags.soundok)
180 	    return;		/* no feedback */
181 
182 	otmp->dknown = 1;  /* seeing or hearing it read reveals its label */
183 	/* shouldn't be able to hear curse/bless status of unseen scrolls;
184 	   for priest characters, bknown will always be set during naming */
185 	savebknown = otmp->bknown;
186 	saverole = Role_switch;
187 	if (!vismon) {
188 	    otmp->bknown = 0;
189 	    if (Role_if(PM_PRIEST)) Role_switch = 0;
190 	}
191 	Strcpy(onambuf, singular(otmp, doname));
192 	Role_switch = saverole;
193 	otmp->bknown = savebknown;
194 
195 	if (vismon)
196 	    pline("%s reads %s!", Monnam(mtmp), onambuf);
197 	else
198 	    You_hear("%s reading %s.",
199 		x_monnam(mtmp, ARTICLE_A, (char *)0,
200 		    (SUPPRESS_IT|SUPPRESS_INVISIBLE|SUPPRESS_SADDLE), FALSE),
201 		onambuf);
202 
203 	if (mtmp->mconf)
204 	    pline("Being confused, %s mispronounces the magic words...",
205 		  vismon ? mon_nam(mtmp) : mhe(mtmp));
206 }
207 
208 STATIC_OVL void
mquaffmsg(mtmp,otmp)209 mquaffmsg(mtmp, otmp)
210 struct monst *mtmp;
211 struct obj *otmp;
212 {
213 	if (canseemon(mtmp)) {
214 		otmp->dknown = 1;
215 		pline("%s %s %s!", Monnam(mtmp), is_weeping(mtmp->data) ?
216 			"is drinking" : "drinks", singular(otmp, doname));
217 	} else
218 		if (flags.soundok)
219 			You_hear("a chugging sound.");
220 }
221 
222 /* Defines for various types of stuff.  The order in which monsters prefer
223  * to use them is determined by the order of the code logic, not the
224  * numerical order in which they are defined.
225  */
226 #define MUSE_SCR_TELEPORTATION 1
227 #define MUSE_WAN_TELEPORTATION_SELF 2
228 #define MUSE_POT_HEALING 3
229 #define MUSE_POT_EXTRA_HEALING 4
230 #define MUSE_WAN_DIGGING 5
231 #define MUSE_TRAPDOOR 6
232 #define MUSE_TELEPORT_TRAP 7
233 #define MUSE_UPSTAIRS 8
234 #define MUSE_DOWNSTAIRS 9
235 #define MUSE_WAN_CREATE_MONSTER 10
236 #define MUSE_SCR_CREATE_MONSTER 11
237 #define MUSE_UP_LADDER 12
238 #define MUSE_DN_LADDER 13
239 #define MUSE_SSTAIRS 14
240 #define MUSE_WAN_TELEPORTATION 15
241 #define MUSE_BUGLE 16
242 #define MUSE_UNICORN_HORN 17
243 #define MUSE_POT_FULL_HEALING 18
244 #define MUSE_LIZARD_CORPSE 19
245 #define MUSE_POT_VAMPIRE_BLOOD 20
246 /*
247 #define MUSE_INNATE_TPT 9999
248  * We cannot use this.  Since monsters get unlimited teleportation, if they
249  * were allowed to teleport at will you could never catch them.  Instead,
250  * assume they only teleport at random times, despite the inconsistency that if
251  * you polymorph into one you teleport at will.
252  */
253 
254 /* Select a defensive item/action for a monster.  Returns TRUE iff one is
255  * found.
256  */
257 boolean
find_defensive(mtmp)258 find_defensive(mtmp)
259 struct monst *mtmp;
260 {
261 	register struct obj *obj = 0;
262 	struct trap *t;
263 	int x=mtmp->mx, y=mtmp->my;
264 	boolean stuck = (mtmp == u.ustuck);
265 	boolean immobile = (mtmp->data->mmove == 0);
266 	int fraction;
267 
268 	if (is_animal(mtmp->data) || mindless(mtmp->data))
269 		return FALSE;
270 	if(dist2(x, y, mtmp->mux, mtmp->muy) > 25)
271 		return FALSE;
272 	if (u.uswallow && stuck) return FALSE;
273 
274 	m.defensive = (struct obj *)0;
275 	m.has_defense = 0;
276 
277 	/* since unicorn horns don't get used up, the monster would look
278 	 * silly trying to use the same cursed horn round after round
279 	 */
280 	if (mtmp->mconf || mtmp->mstun || !mtmp->mcansee) {
281 	    if (!is_unicorn(mtmp->data) && !nohands(mtmp->data)) {
282 		for(obj = mtmp->minvent; obj; obj = obj->nobj)
283 		    if (obj->otyp == UNICORN_HORN && !obj->cursed)
284 			break;
285 	    }
286 	    if (obj || is_unicorn(mtmp->data)) {
287 		m.defensive = obj;
288 		m.has_defense = MUSE_UNICORN_HORN;
289 		return TRUE;
290 	    }
291 	}
292 
293 	if (mtmp->mconf) {
294 	    for(obj = mtmp->minvent; obj; obj = obj->nobj) {
295 		if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD) {
296 		    m.defensive = obj;
297 		    m.has_defense = MUSE_LIZARD_CORPSE;
298 		    return TRUE;
299 		}
300 	    }
301 	}
302 
303 	/* It so happens there are two unrelated cases when we might want to
304 	 * check specifically for healing alone.  The first is when the monster
305 	 * is blind (healing cures blindness).  The second is when the monster
306 	 * is peaceful; then we don't want to flee the player, and by
307 	 * coincidence healing is all there is that doesn't involve fleeing.
308 	 * These would be hard to combine because of the control flow.
309 	 * Pestilence won't use healing even when blind.
310 	 */
311 	if (!mtmp->mcansee && !nohands(mtmp->data) &&
312 		mtmp->data != &mons[PM_PESTILENCE]) {
313 	    if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) {
314 		m.defensive = obj;
315 		m.has_defense = MUSE_POT_FULL_HEALING;
316 		return TRUE;
317 	    }
318 	    if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) {
319 		m.defensive = obj;
320 		m.has_defense = MUSE_POT_EXTRA_HEALING;
321 		return TRUE;
322 	    }
323 	    if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) {
324 		m.defensive = obj;
325 		m.has_defense = MUSE_POT_HEALING;
326 		return TRUE;
327 	    }
328 	}
329 
330 	fraction = u.ulevel < 10 ? 5 : u.ulevel < 14 ? 4 : 3;
331 	if(mtmp->mhp >= mtmp->mhpmax ||
332 			(mtmp->mhp >= 10 && mtmp->mhp*fraction >= mtmp->mhpmax))
333 		return FALSE;
334 
335 	if (mtmp->mpeaceful) {
336 	    if (!nohands(mtmp->data)) {
337 		if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) {
338 		    m.defensive = obj;
339 		    m.has_defense = MUSE_POT_FULL_HEALING;
340 		    return TRUE;
341 		}
342 		if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) {
343 		    m.defensive = obj;
344 		    m.has_defense = MUSE_POT_EXTRA_HEALING;
345 		    return TRUE;
346 		}
347 		if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) {
348 		    m.defensive = obj;
349 		    m.has_defense = MUSE_POT_HEALING;
350 		    return TRUE;
351 		}
352 		if (is_vampire(mtmp->data) &&
353 		  (obj = m_carrying(mtmp, POT_VAMPIRE_BLOOD)) !=0) {
354 		    m.defensive = obj;
355 		    m.has_defense = MUSE_POT_VAMPIRE_BLOOD;
356 		    return TRUE;
357 		}
358 	    }
359 	    return FALSE;
360 	}
361 
362 	if (levl[x][y].typ == STAIRS && !stuck && !immobile) {
363 		if (x == xdnstair && y == ydnstair && !is_floater(mtmp->data))
364 			m.has_defense = MUSE_DOWNSTAIRS;
365 		if (x == xupstair && y == yupstair && ledger_no(&u.uz) != 1)
366 	/* Unfair to let the monsters leave the dungeon with the Amulet */
367 	/* (or go to the endlevel since you also need it, to get there) */
368 			m.has_defense = MUSE_UPSTAIRS;
369 	} else if (levl[x][y].typ == LADDER && !stuck && !immobile) {
370 		if (x == xupladder && y == yupladder)
371 			m.has_defense = MUSE_UP_LADDER;
372 		if (x == xdnladder && y == ydnladder && !is_floater(mtmp->data))
373 			m.has_defense = MUSE_DN_LADDER;
374 	} else if (sstairs.sx && sstairs.sx == x && sstairs.sy == y) {
375 		m.has_defense = MUSE_SSTAIRS;
376 	} else if (!stuck && !immobile) {
377 	/* Note: trap doors take precedence over teleport traps. */
378 		int xx, yy;
379 
380 		for(xx = x-1; xx <= x+1; xx++) for(yy = y-1; yy <= y+1; yy++)
381 		if (isok(xx,yy))
382 		if (xx != u.ux && yy != u.uy)
383 		if (mtmp->data != &mons[PM_GRID_BUG] || xx == x || yy == y)
384 		if ((xx==x && yy==y) || !level.monsters[xx][yy])
385 		if ((t = t_at(xx,yy)) != 0)
386 		if ((verysmall(mtmp->data) || throws_rocks(mtmp->data) ||
387 		     passes_walls(mtmp->data)) || !sobj_at(BOULDER, xx, yy))
388 		if (!onscary(xx,yy,mtmp)) {
389 			if ((t->ttyp == TRAPDOOR || t->ttyp == HOLE)
390 				&& !is_floater(mtmp->data)
391 				&& !mtmp->isshk && !mtmp->isgd
392 				&& !mtmp->ispriest
393 				&& Can_fall_thru(&u.uz)
394 						) {
395 				trapx = xx;
396 				trapy = yy;
397 				m.has_defense = MUSE_TRAPDOOR;
398 			} else if (t->ttyp == TELEP_TRAP && m.has_defense != MUSE_TRAPDOOR) {
399 				trapx = xx;
400 				trapy = yy;
401 				m.has_defense = MUSE_TELEPORT_TRAP;
402 			}
403 		}
404 	}
405 
406 	if (nohands(mtmp->data))	/* can't use objects */
407 		goto botm;
408 
409 	if (is_mercenary(mtmp->data) && (obj = m_carrying(mtmp, BUGLE))) {
410 		int xx, yy;
411 		struct monst *mon;
412 
413 		/* Distance is arbitrary.  What we really want to do is
414 		 * have the soldier play the bugle when it sees or
415 		 * remembers soldiers nearby...
416 		 */
417 		for(xx = x-3; xx <= x+3; xx++) for(yy = y-3; yy <= y+3; yy++)
418 		if (isok(xx,yy))
419 		if ((mon = m_at(xx,yy)) && is_mercenary(mon->data) &&
420 				mon->data != &mons[PM_GUARD] &&
421 				(mon->msleeping || (!mon->mcanmove))) {
422 			m.defensive = obj;
423 			m.has_defense = MUSE_BUGLE;
424 		}
425 	}
426 
427 	/* use immediate physical escape prior to attempting magic */
428 	if (m.has_defense)    /* stairs, trap door or tele-trap, bugle alert */
429 		goto botm;
430 
431 	/* kludge to cut down on trap destruction (particularly portals) */
432 	t = t_at(x,y);
433 	if (t && (t->ttyp == PIT || t->ttyp == SPIKED_PIT ||
434 		  t->ttyp == WEB || t->ttyp == BEAR_TRAP))
435 		t = 0;		/* ok for monster to dig here */
436 
437 #define nomore(x) if(m.has_defense==x) continue;
438 	for (obj = mtmp->minvent; obj; obj = obj->nobj) {
439 		/* don't always use the same selection pattern */
440 		if (m.has_defense && !rn2(3)) break;
441 
442 		/* nomore(MUSE_WAN_DIGGING); */
443 		if (m.has_defense == MUSE_WAN_DIGGING) break;
444 		if (obj->otyp == WAN_DIGGING && obj->spe > 0 && !stuck && !t
445 		    && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest
446 		    && !is_floater(mtmp->data)
447 		    /* monsters digging in Sokoban can ruin things */
448 		    && !In_sokoban(&u.uz)
449 		    /* digging wouldn't be effective; assume they know that */
450 		    && !(levl[x][y].wall_info & W_NONDIGGABLE)
451 		    && !(Is_botlevel(&u.uz) || In_endgame(&u.uz))
452 		    && !(is_ice(x,y) || is_pool(x,y) || is_lava(x,y))
453 		    && !(mtmp->data == &mons[PM_VLAD_THE_IMPALER]
454 			 && In_V_tower(&u.uz))) {
455 			m.defensive = obj;
456 			m.has_defense = MUSE_WAN_DIGGING;
457 		}
458 		nomore(MUSE_WAN_TELEPORTATION_SELF);
459 		nomore(MUSE_WAN_TELEPORTATION);
460 		if(obj->otyp == WAN_TELEPORTATION && obj->spe > 0) {
461 		    /* use the TELEP_TRAP bit to determine if they know
462 		     * about noteleport on this level or not.  Avoids
463 		     * ineffective re-use of teleportation.  This does
464 		     * mean if the monster leaves the level, they'll know
465 		     * about teleport traps.
466 		     */
467 		    if (!level.flags.noteleport ||
468 			!(mtmp->mtrapseen & (1 << (TELEP_TRAP-1)))) {
469 			m.defensive = obj;
470 			m.has_defense = (mon_has_amulet(mtmp))
471 				? MUSE_WAN_TELEPORTATION
472 				: MUSE_WAN_TELEPORTATION_SELF;
473 		    }
474 		}
475 		nomore(MUSE_SCR_TELEPORTATION);
476 		if(obj->otyp == SCR_TELEPORTATION && mtmp->mcansee
477 		   && haseyes(mtmp->data) && !is_weeping(mtmp->data)
478 		   && (!obj->cursed ||
479 		       (!(mtmp->isshk && inhishop(mtmp))
480 			    && !mtmp->isgd && !mtmp->ispriest))) {
481 		    /* see WAN_TELEPORTATION case above */
482 		    if (!level.flags.noteleport ||
483 			!(mtmp->mtrapseen & (1 << (TELEP_TRAP-1)))) {
484 			m.defensive = obj;
485 			m.has_defense = MUSE_SCR_TELEPORTATION;
486 		    }
487 		}
488 
489 	    if (mtmp->data != &mons[PM_PESTILENCE]) {
490 		nomore(MUSE_POT_FULL_HEALING);
491 		if(obj->otyp == POT_FULL_HEALING) {
492 			m.defensive = obj;
493 			m.has_defense = MUSE_POT_FULL_HEALING;
494 		}
495 		nomore(MUSE_POT_EXTRA_HEALING);
496 		if(obj->otyp == POT_EXTRA_HEALING) {
497 			m.defensive = obj;
498 			m.has_defense = MUSE_POT_EXTRA_HEALING;
499 		}
500 		nomore(MUSE_WAN_CREATE_MONSTER);
501 		if(obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
502 			m.defensive = obj;
503 			m.has_defense = MUSE_WAN_CREATE_MONSTER;
504 		}
505 		nomore(MUSE_POT_HEALING);
506 		if(obj->otyp == POT_HEALING) {
507 			m.defensive = obj;
508 			m.has_defense = MUSE_POT_HEALING;
509 		}
510 		nomore(MUSE_POT_VAMPIRE_BLOOD);
511 		if(is_vampire(mtmp->data) && obj->otyp == POT_VAMPIRE_BLOOD) {
512 			m.defensive = obj;
513 			m.has_defense = MUSE_POT_VAMPIRE_BLOOD;
514 		}
515 	    } else {	/* Pestilence */
516 		nomore(MUSE_POT_FULL_HEALING);
517 		if (obj->otyp == POT_SICKNESS) {
518 			m.defensive = obj;
519 			m.has_defense = MUSE_POT_FULL_HEALING;
520 		}
521 		nomore(MUSE_WAN_CREATE_MONSTER);
522 		if (obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
523 			m.defensive = obj;
524 			m.has_defense = MUSE_WAN_CREATE_MONSTER;
525 		}
526 	    }
527 		nomore(MUSE_SCR_CREATE_MONSTER);
528 		if(obj->otyp == SCR_CREATE_MONSTER && !is_weeping(mtmp->data)) {
529 			m.defensive = obj;
530 			m.has_defense = MUSE_SCR_CREATE_MONSTER;
531 		}
532 	}
533 botm:	return((boolean)(!!m.has_defense));
534 #undef nomore
535 }
536 
537 /* Perform a defensive action for a monster.  Must be called immediately
538  * after find_defensive().  Return values are 0: did something, 1: died,
539  * 2: did something and can't attack again (i.e. teleported).
540  */
541 int
use_defensive(mtmp)542 use_defensive(mtmp)
543 struct monst *mtmp;
544 {
545 	int i, fleetim, how = 0;
546 	struct obj *otmp = m.defensive;
547 	boolean vis, vismon, oseen;
548 	const char *mcsa = "%s can see again.";
549 
550 	if ((i = precheck(mtmp, otmp)) != 0) return i;
551 	vis = cansee(mtmp->mx, mtmp->my);
552 	vismon = canseemon(mtmp);
553 	oseen = otmp && vismon;
554 
555 	/* when using defensive choice to run away, we want monster to avoid
556 	   rushing right straight back; don't override if already scared */
557 	fleetim = !mtmp->mflee ? (33 - (30 * mtmp->mhp / mtmp->mhpmax)) : 0;
558 #define m_flee(m)	if (fleetim && !m->iswiz) \
559 			{ monflee(m, fleetim, FALSE, FALSE); }
560 
561 	switch(m.has_defense) {
562 	case MUSE_UNICORN_HORN:
563 		if (vismon) {
564 		    if (otmp)
565 			pline("%s %s a unicorn horn!",
566 			    is_weeping(mtmp->data) ? "is using" : "uses", Monnam(mtmp));
567 		    else
568 			pline_The("tip of %s's horn glows!", mon_nam(mtmp));
569 		}
570 		if (!mtmp->mcansee) {
571 		    mtmp->mcansee = 1;
572 		    mtmp->mblinded = 0;
573 		    if (vismon) pline(mcsa, Monnam(mtmp));
574 		} else if (mtmp->mconf || mtmp->mstun) {
575 		    mtmp->mconf = mtmp->mstun = 0;
576 		    if (vismon)
577 			pline("%s seems steadier now.", Monnam(mtmp));
578 		} else warning("No need for unicorn horn?");
579 		return 2;
580 	case MUSE_BUGLE:
581 		if (vismon)
582 			pline("%s plays %s!", Monnam(mtmp), doname(otmp));
583 		else if (flags.soundok)
584 			You_hear("a bugle playing reveille!");
585 		awaken_soldiers();
586 		return 2;
587 	case MUSE_WAN_TELEPORTATION_SELF:
588 		if ((mtmp->isshk && inhishop(mtmp))
589 		       || mtmp->isgd || mtmp->ispriest) return 2;
590 		m_flee(mtmp);
591 		mzapmsg(mtmp, otmp, TRUE);
592 		otmp->spe--;
593 		how = WAN_TELEPORTATION;
594 mon_tele:
595 		if (tele_restrict(mtmp)) {	/* mysterious force... */
596 		    if (vismon && how)		/* mentions 'teleport' */
597 			makeknown(how);
598 		    /* monster learns that teleportation isn't useful here */
599 		    if (level.flags.noteleport)
600 			mtmp->mtrapseen |= (1 << (TELEP_TRAP-1));
601 		    return 2;
602 		}
603 		if ((
604 #if 0
605 			mon_has_amulet(mtmp) ||
606 #endif
607 			On_W_tower_level(&u.uz)) && !rn2(3)) {
608 		    if (vismon)
609 			pline("%s seems disoriented for a moment.",
610 				Monnam(mtmp));
611 		    return 2;
612 		}
613 		if (oseen && how) makeknown(how);
614 		(void) rloc(mtmp, FALSE);
615 		return 2;
616 	case MUSE_WAN_TELEPORTATION:
617 		zap_oseen = oseen;
618 		mzapmsg(mtmp, otmp, FALSE);
619 		otmp->spe--;
620 		m_using = TRUE;
621 		mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp);
622 		/* monster learns that teleportation isn't useful here */
623 		if (level.flags.noteleport)
624 		    mtmp->mtrapseen |= (1 << (TELEP_TRAP-1));
625 		m_using = FALSE;
626 		return 2;
627 	case MUSE_SCR_TELEPORTATION:
628 	    {
629 		int obj_is_cursed = otmp->cursed;
630 
631 		if (mtmp->isshk || mtmp->isgd || mtmp->ispriest) return 2;
632 		m_flee(mtmp);
633 		mreadmsg(mtmp, otmp);
634 		m_useup(mtmp, otmp);	/* otmp might be free'ed */
635 		how = SCR_TELEPORTATION;
636 		if (obj_is_cursed || mtmp->mconf) {
637 			int nlev;
638 			d_level flev;
639 
640 			if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
641 			    if (vismon)
642 				pline("%s seems very disoriented for a moment.",
643 					Monnam(mtmp));
644 			    return 2;
645 			}
646 			nlev = random_teleport_level();
647 			if (nlev == depth(&u.uz)) {
648 			    if (vismon)
649 				pline("%s shudders for a moment.",
650 								Monnam(mtmp));
651 			    return 2;
652 			}
653 			get_level(&flev, nlev);
654 			migrate_to_level(mtmp, ledger_no(&flev), MIGR_RANDOM,
655 				(coord *)0);
656 			if (oseen) makeknown(SCR_TELEPORTATION);
657 		} else goto mon_tele;
658 		return 2;
659 	    }
660 	case MUSE_WAN_DIGGING:
661 	    {	struct trap *ttmp;
662 
663 		m_flee(mtmp);
664 		mzapmsg(mtmp, otmp, FALSE);
665 		otmp->spe--;
666 		if (oseen) makeknown(WAN_DIGGING);
667 		if (IS_FURNITURE(levl[mtmp->mx][mtmp->my].typ) ||
668 		    IS_DRAWBRIDGE(levl[mtmp->mx][mtmp->my].typ) ||
669 		    (is_drawbridge_wall(mtmp->mx, mtmp->my) >= 0) ||
670 		    (sstairs.sx && sstairs.sx == mtmp->mx &&
671 				   sstairs.sy == mtmp->my)) {
672 			pline_The("digging ray is ineffective.");
673 			return 2;
674 		}
675 		if (!Can_dig_down(&u.uz)) {
676 		    if(canseemon(mtmp))
677 			pline_The("%s here is too hard to dig in.",
678 					surface(mtmp->mx, mtmp->my));
679 		    return 2;
680 		}
681 		ttmp = maketrap(mtmp->mx, mtmp->my, HOLE);
682 		if (!ttmp) return 2;
683 		seetrap(ttmp);
684 		if (vis) {
685 		    pline("%s has made a hole in the %s.", Monnam(mtmp),
686 				surface(mtmp->mx, mtmp->my));
687 		    pline("%s %s through...", Monnam(mtmp),
688 			  is_flyer(mtmp->data) ? "dives" : "falls");
689 		} else if (flags.soundok)
690 			You_hear("%s crash through the %s.", something,
691 				surface(mtmp->mx, mtmp->my));
692 		/* we made sure that there is a level for mtmp to go to */
693 		migrate_to_level(mtmp, ledger_no(&u.uz) + 1,
694 				 MIGR_RANDOM, (coord *)0);
695 		return 2;
696 	    }
697 	case MUSE_WAN_CREATE_MONSTER:
698 	    {	coord cc;
699 		    /* pm: 0 => random, eel => aquatic, croc => amphibious */
700 		struct permonst *pm = !is_pool(mtmp->mx, mtmp->my) ? 0 :
701 			     &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE];
702 		struct monst *mon;
703 
704 		if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) return 0;
705 		mzapmsg(mtmp, otmp, FALSE);
706 		otmp->spe--;
707 		mon = makemon((struct permonst *)0, cc.x, cc.y, NO_MM_FLAGS);
708 		if (mon && canspotmon(mon) && oseen)
709 		    makeknown(WAN_CREATE_MONSTER);
710 		return 2;
711 	    }
712 	case MUSE_SCR_CREATE_MONSTER:
713 	    {	coord cc;
714 		struct permonst *pm = 0, *fish = 0;
715 		int cnt = 1;
716 		struct monst *mon;
717 		boolean known = FALSE;
718 
719 		if (!rn2(73)) cnt += rnd(4);
720 		if (mtmp->mconf || otmp->cursed) cnt += 12;
721 		if (mtmp->mconf) pm = fish = &mons[PM_ACID_BLOB];
722 		else if (is_pool(mtmp->mx, mtmp->my))
723 		    fish = &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE];
724 		mreadmsg(mtmp, otmp);
725 		while(cnt--) {
726 		    /* `fish' potentially gives bias towards water locations;
727 		       `pm' is what to actually create (0 => random) */
728 		    if (!enexto(&cc, mtmp->mx, mtmp->my, fish)) break;
729 		    mon = makemon(pm, cc.x, cc.y, NO_MM_FLAGS);
730 		    if (mon && canspotmon(mon)) known = TRUE;
731 		}
732 		/* The only case where we don't use oseen.  For wands, you
733 		 * have to be able to see the monster zap the wand to know
734 		 * what type it is.  For teleport scrolls, you have to see
735 		 * the monster to know it teleported.
736 		 */
737 		if (known)
738 		    makeknown(SCR_CREATE_MONSTER);
739 		else if (!objects[SCR_CREATE_MONSTER].oc_name_known
740 			&& !objects[SCR_CREATE_MONSTER].oc_uname)
741 		    docall(otmp);
742 		m_useup(mtmp, otmp);
743 		return 2;
744 	    }
745 	case MUSE_TRAPDOOR:
746 		/* trap doors on "bottom" levels of dungeons are rock-drop
747 		 * trap doors, not holes in the floor.  We check here for
748 		 * safety.
749 		 */
750 		if (Is_botlevel(&u.uz)) return 0;
751 		m_flee(mtmp);
752 		if (vis) {
753 			struct trap *t;
754 			t = t_at(trapx,trapy);
755 			pline("%s %s into a %s!", Monnam(mtmp),
756 			makeplural(is_weeping(mtmp->data) ? "tips over" : locomotion(mtmp->data, "jump")),
757 			t->ttyp == TRAPDOOR ? "trap door" : "hole");
758 			if (levl[trapx][trapy].typ == SCORR) {
759 			    levl[trapx][trapy].typ = CORR;
760 			    unblock_point(trapx, trapy);
761 			}
762 			seetrap(t_at(trapx,trapy));
763 		}
764 
765 		/*  don't use rloc_to() because worm tails must "move" */
766 		remove_monster(mtmp->mx, mtmp->my);
767 		newsym(mtmp->mx, mtmp->my);	/* update old location */
768 		place_monster(mtmp, trapx, trapy);
769 		if (mtmp->wormno) worm_move(mtmp);
770 		newsym(trapx, trapy);
771 
772 		migrate_to_level(mtmp, ledger_no(&u.uz) + 1,
773 				 MIGR_RANDOM, (coord *)0);
774 		return 2;
775 	case MUSE_UPSTAIRS:
776 		/* Monsters without amulets escape the dungeon and are
777 		 * gone for good when they leave up the up stairs.
778 		 * Monsters with amulets would reach the endlevel,
779 		 * which we cannot allow since that would leave the
780 		 * player stranded.
781 		 */
782 		if (ledger_no(&u.uz) == 1) {
783 			if (mon_has_special(mtmp))
784 				return 0;
785 			if (vismon)
786 			    pline("%s %s the dungeon!", Monnam(mtmp),
787 				is_weeping(mtmp->data) ? "has escaped" : "escapes");
788 			mongone(mtmp);
789 			return 2;
790 		}
791 		m_flee(mtmp);
792 		if (Inhell && mon_has_amulet(mtmp) && !rn2(4) &&
793 			(dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) {
794 		    if (vismon) pline(
795      "As %s climbs the stairs, a mysterious force momentarily surrounds %s...",
796 				     mon_nam(mtmp), mhim(mtmp));
797 		    /* simpler than for the player; this will usually be
798 		       the Wizard and he'll immediately go right to the
799 		       upstairs, so there's not much point in having any
800 		       chance for a random position on the current level */
801 		    migrate_to_level(mtmp, ledger_no(&u.uz) + 1,
802 				     MIGR_RANDOM, (coord *)0);
803 		} else {
804 		    if (vismon) pline("%s %s upstairs!", Monnam(mtmp),
805 			is_weeping(mtmp->data) ? "has escaped" : "escapes");
806 		    migrate_to_level(mtmp, ledger_no(&u.uz) - 1,
807 				     MIGR_STAIRS_DOWN, (coord *)0);
808 		}
809 		return 2;
810 	case MUSE_DOWNSTAIRS:
811 		m_flee(mtmp);
812 		if (vismon) pline("%s %s downstairs!", Monnam(mtmp),
813 			is_weeping(mtmp->data) ? "has escaped" : "escapes");
814 		migrate_to_level(mtmp, ledger_no(&u.uz) + 1,
815 				 MIGR_STAIRS_UP, (coord *)0);
816 		return 2;
817 	case MUSE_UP_LADDER:
818 		m_flee(mtmp);
819 		if (vismon) pline("%s %s up the ladder!", Monnam(mtmp),
820 			is_weeping(mtmp->data) ? "has escaped" : "escapes");
821 		migrate_to_level(mtmp, ledger_no(&u.uz) - 1,
822 				 MIGR_LADDER_DOWN, (coord *)0);
823 		return 2;
824 	case MUSE_DN_LADDER:
825 		m_flee(mtmp);
826 		if (vismon) pline("%s %s down the ladder!", Monnam(mtmp),
827 			is_weeping(mtmp->data) ? "has escaped" : "escapes");
828 		migrate_to_level(mtmp, ledger_no(&u.uz) + 1,
829 				 MIGR_LADDER_UP, (coord *)0);
830 		return 2;
831 	case MUSE_SSTAIRS:
832 		m_flee(mtmp);
833 		/* the stairs leading up from the 1st level are */
834 		/* regular stairs, not sstairs.			*/
835 		if (sstairs.up) {
836 			if (vismon)
837 			    pline("%s %s upstairs!", Monnam(mtmp),
838 				is_weeping(mtmp->data) ? "has escaped" : "escapes");
839 			if(Inhell) {
840 			    migrate_to_level(mtmp, ledger_no(&sstairs.tolev),
841 					     MIGR_RANDOM, (coord *)0);
842 			    return 2;
843 			}
844 		} else	if (vismon)
845 		    pline("%s %s downstairs!", Monnam(mtmp),
846 			is_weeping(mtmp->data) ? "has escaped" : "escapes");
847 		migrate_to_level(mtmp, ledger_no(&sstairs.tolev),
848 				 MIGR_SSTAIRS, (coord *)0);
849 		return 2;
850 	case MUSE_TELEPORT_TRAP:
851 		m_flee(mtmp);
852 		if (vis) {
853 			pline("%s %s onto a teleport trap!", Monnam(mtmp),
854 				is_weeping(mtmp->data) ? "tips over" :
855 				makeplural(locomotion(mtmp->data, "jump")));
856 			if (levl[trapx][trapy].typ == SCORR) {
857 			    levl[trapx][trapy].typ = CORR;
858 			    unblock_point(trapx, trapy);
859 			}
860 			seetrap(t_at(trapx,trapy));
861 		}
862 		/*  don't use rloc_to() because worm tails must "move" */
863 		remove_monster(mtmp->mx, mtmp->my);
864 		newsym(mtmp->mx, mtmp->my);	/* update old location */
865 		place_monster(mtmp, trapx, trapy);
866 		if (mtmp->wormno) worm_move(mtmp);
867 		newsym(trapx, trapy);
868 
869 		goto mon_tele;
870 	case MUSE_POT_HEALING:
871 		mquaffmsg(mtmp, otmp);
872 		i = d(6 + 2 * bcsign(otmp), 4);
873 		mtmp->mhp += i;
874 		if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = ++mtmp->mhpmax;
875 		if (!otmp->cursed && !mtmp->mcansee) {
876 			mtmp->mcansee = 1;
877 			mtmp->mblinded = 0;
878 			if (vismon) pline(mcsa, Monnam(mtmp));
879 		}
880 		if (vismon) pline("%s looks better.", Monnam(mtmp));
881 		if (oseen) makeknown(POT_HEALING);
882 		m_useup(mtmp, otmp);
883 		return 2;
884 	case MUSE_POT_EXTRA_HEALING:
885 		mquaffmsg(mtmp, otmp);
886 		i = d(6 + 2 * bcsign(otmp), 8);
887 		mtmp->mhp += i;
888 		if (mtmp->mhp > mtmp->mhpmax)
889 			mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2));
890 		if (!mtmp->mcansee) {
891 			mtmp->mcansee = 1;
892 			mtmp->mblinded = 0;
893 			if (vismon) pline(mcsa, Monnam(mtmp));
894 		}
895 		if (vismon) pline("%s looks much better.", Monnam(mtmp));
896 		if (oseen) makeknown(POT_EXTRA_HEALING);
897 		m_useup(mtmp, otmp);
898 		return 2;
899 	case MUSE_POT_FULL_HEALING:
900 		mquaffmsg(mtmp, otmp);
901 		if (otmp->otyp == POT_SICKNESS) unbless(otmp); /* Pestilence */
902 		mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 8 : 4));
903 		if (!mtmp->mcansee && otmp->otyp != POT_SICKNESS) {
904 			mtmp->mcansee = 1;
905 			mtmp->mblinded = 0;
906 			if (vismon) pline(mcsa, Monnam(mtmp));
907 		}
908 		if (vismon) pline("%s looks completely healed.", Monnam(mtmp));
909 		if (oseen) makeknown(otmp->otyp);
910 		m_useup(mtmp, otmp);
911 		return 2;
912 	case MUSE_POT_VAMPIRE_BLOOD:
913 		mquaffmsg(mtmp, otmp);
914 		if (!otmp->cursed) {
915 		    i = rnd(8) + rnd(2);
916 		    mtmp->mhp += i;
917 		    mtmp->mhpmax += i;
918 		    if (vismon) pline("%s looks full of life.", Monnam(mtmp));
919 		}
920 		else if (vismon)
921 		    pline("%s discards the congealed blood in disgust.", Monnam(mtmp));
922 		if (oseen) makeknown(POT_VAMPIRE_BLOOD);
923 		m_useup(mtmp, otmp);
924 		return 2;
925 	case MUSE_LIZARD_CORPSE:
926 		/* not actually called for its unstoning effect */
927 		mon_consume_unstone(mtmp, otmp, FALSE, FALSE);
928 		return 2;
929 	case 0: return 0; /* i.e. an exploded wand */
930 	default: warning("%s wanted to perform action %d?", Monnam(mtmp),
931 			m.has_defense);
932 		break;
933 	}
934 	return 0;
935 #undef m_flee
936 }
937 
938 int
rnd_defensive_item(mtmp)939 rnd_defensive_item(mtmp)
940 struct monst *mtmp;
941 {
942 	struct permonst *pm = mtmp->data;
943 	int difficulty = monstr[(monsndx(pm))];
944 	int trycnt = 0;
945 
946 	if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
947 			|| pm->mlet == S_GHOST
948 # ifdef KOPS
949 			|| pm->mlet == S_KOP
950 # endif
951 		) return 0;
952     try_again:
953 	switch (rn2(8 + (difficulty > 3) + (difficulty > 6) +
954 				(difficulty > 8))) {
955 		case 6: case 9:
956 			if (level.flags.noteleport && ++trycnt < 2)
957 			    goto try_again;
958 			if (!rn2(3)) return WAN_TELEPORTATION;
959 			/* else FALLTHRU */
960 		case 0: case 1:
961 			return SCR_TELEPORTATION;
962 		case 8: case 10:
963 			if (!rn2(3)) return WAN_CREATE_MONSTER;
964 			/* else FALLTHRU */
965 		case 2: return SCR_CREATE_MONSTER;
966 		case 3: return POT_HEALING;
967 		case 4: return POT_EXTRA_HEALING;
968 		case 5: return (mtmp->data != &mons[PM_PESTILENCE]) ?
969 				POT_FULL_HEALING : POT_SICKNESS;
970 		case 7: if (is_floater(pm) || mtmp->isshk || mtmp->isgd
971 						|| mtmp->ispriest
972 									)
973 				return 0;
974 			else
975 				return WAN_DIGGING;
976 	}
977 	/*NOTREACHED*/
978 	return 0;
979 }
980 
981 #define MUSE_WAN_DEATH 1
982 #define MUSE_WAN_SLEEP 2
983 #define MUSE_WAN_FIRE 3
984 #define MUSE_WAN_COLD 4
985 #define MUSE_WAN_LIGHTNING 5
986 #define MUSE_WAN_MAGIC_MISSILE 6
987 #define MUSE_WAN_STRIKING 7
988 #define MUSE_SCR_FIRE 8
989 #define MUSE_POT_PARALYSIS 9
990 #define MUSE_POT_BLINDNESS 10
991 #define MUSE_POT_CONFUSION 11
992 #define MUSE_FROST_HORN 12
993 #define MUSE_FIRE_HORN 13
994 #define MUSE_POT_ACID 14
995 /*#define MUSE_WAN_TELEPORTATION 15*/
996 #define MUSE_POT_SLEEPING 16
997 #define MUSE_SCR_EARTH 17
998 #define MUSE_WAN_CANCELLATION 18
999 
1000 /* Select an offensive item/action for a monster.  Returns TRUE iff one is
1001  * found.
1002  */
1003 boolean
find_offensive(mtmp)1004 find_offensive(mtmp)
1005 struct monst *mtmp;
1006 {
1007 	register struct obj *obj;
1008 	boolean ranged_stuff = lined_up(mtmp);
1009 	boolean reflection_skip = (Reflecting && rn2(2));
1010 	struct obj *helmet = which_armor(mtmp, W_ARMH);
1011 
1012 	m.offensive = (struct obj *)0;
1013 	m.has_offense = 0;
1014 	if (mtmp->mpeaceful || is_animal(mtmp->data) ||
1015 				mindless(mtmp->data) || nohands(mtmp->data))
1016 		return FALSE;
1017 	if (u.uswallow) return FALSE;
1018 	if (in_your_sanctuary(mtmp, 0, 0)) return FALSE;
1019 	if (dmgtype(mtmp->data, AD_HEAL) && !uwep
1020 #ifdef TOURIST
1021 	    && !uarmu
1022 #endif
1023 	    && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf)
1024 		return FALSE;
1025 
1026 	if (!ranged_stuff) return FALSE;
1027 #define nomore(x) if(m.has_offense==x) continue;
1028 	for(obj=mtmp->minvent; obj; obj=obj->nobj) {
1029 		/* nomore(MUSE_WAN_DEATH); */
1030 		if (!reflection_skip) {
1031 		    if(obj->otyp == WAN_DEATH && obj->spe > 0) {
1032 			m.offensive = obj;
1033 			m.has_offense = MUSE_WAN_DEATH;
1034 		    }
1035 		    nomore(MUSE_WAN_SLEEP);
1036 		    if(obj->otyp == WAN_SLEEP && obj->spe > 0 && multi >= 0) {
1037 			m.offensive = obj;
1038 			m.has_offense = MUSE_WAN_SLEEP;
1039 		    }
1040 		    nomore(MUSE_WAN_FIRE);
1041 		    if(obj->otyp == WAN_FIRE && obj->spe > 0) {
1042 			m.offensive = obj;
1043 			m.has_offense = MUSE_WAN_FIRE;
1044 		    }
1045 		    nomore(MUSE_FIRE_HORN);
1046 		    if(obj->otyp == FIRE_HORN && obj->spe > 0) {
1047 			m.offensive = obj;
1048 			m.has_offense = MUSE_FIRE_HORN;
1049 		    }
1050 		    nomore(MUSE_WAN_COLD);
1051 		    if(obj->otyp == WAN_COLD && obj->spe > 0) {
1052 			m.offensive = obj;
1053 			m.has_offense = MUSE_WAN_COLD;
1054 		    }
1055 		    nomore(MUSE_FROST_HORN);
1056 		    if(obj->otyp == FROST_HORN && obj->spe > 0) {
1057 			m.offensive = obj;
1058 			m.has_offense = MUSE_FROST_HORN;
1059 		    }
1060 		    nomore(MUSE_WAN_LIGHTNING);
1061 		    if(obj->otyp == WAN_LIGHTNING && obj->spe > 0) {
1062 			m.offensive = obj;
1063 			m.has_offense = MUSE_WAN_LIGHTNING;
1064 		    }
1065 		    nomore(MUSE_WAN_MAGIC_MISSILE);
1066 		    if(obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) {
1067 			m.offensive = obj;
1068 			m.has_offense = MUSE_WAN_MAGIC_MISSILE;
1069 		    }
1070 		}
1071 		nomore(MUSE_WAN_STRIKING);
1072 		if(obj->otyp == WAN_STRIKING && obj->spe > 0) {
1073 			m.offensive = obj;
1074 			m.has_offense = MUSE_WAN_STRIKING;
1075 		}
1076 		nomore(MUSE_WAN_CANCELLATION);
1077 		if(obj->otyp == WAN_CANCELLATION && obj->spe > 0) {
1078 			m.offensive = obj;
1079 			m.has_offense = MUSE_WAN_CANCELLATION;
1080 		}
1081 		nomore(MUSE_POT_PARALYSIS);
1082 		if(obj->otyp == POT_PARALYSIS && multi >= 0) {
1083 			m.offensive = obj;
1084 			m.has_offense = MUSE_POT_PARALYSIS;
1085 		}
1086 		nomore(MUSE_POT_BLINDNESS);
1087 		if(obj->otyp == POT_BLINDNESS && !attacktype(mtmp->data, AT_GAZE)) {
1088 			m.offensive = obj;
1089 			m.has_offense = MUSE_POT_BLINDNESS;
1090 		}
1091 		nomore(MUSE_POT_CONFUSION);
1092 		if(obj->otyp == POT_CONFUSION) {
1093 			m.offensive = obj;
1094 			m.has_offense = MUSE_POT_CONFUSION;
1095 		}
1096 		nomore(MUSE_POT_SLEEPING);
1097 		if(obj->otyp == POT_SLEEPING) {
1098 			m.offensive = obj;
1099 			m.has_offense = MUSE_POT_SLEEPING;
1100 		}
1101 		nomore(MUSE_POT_ACID);
1102 		if(obj->otyp == POT_ACID) {
1103 			m.offensive = obj;
1104 			m.has_offense = MUSE_POT_ACID;
1105 		}
1106 		/* we can safely put this scroll here since the locations that
1107 		 * are in a 1 square radius are a subset of the locations that
1108 		 * are in wand range
1109 		 */
1110 		nomore(MUSE_SCR_EARTH);
1111 		if (obj->otyp == SCR_EARTH
1112 		       && ((helmet && is_metallic(helmet)) ||
1113 				mtmp->mconf || amorphous(mtmp->data) ||
1114 				passes_walls(mtmp->data) ||
1115 				noncorporeal(mtmp->data) ||
1116 				unsolid(mtmp->data) || !rn2(10))
1117 		       && dist2(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy) <= 2
1118 		       && mtmp->mcansee && haseyes(mtmp->data)
1119 #ifdef REINCARNATION
1120 		       && !Is_rogue_level(&u.uz)
1121 #endif
1122 		       && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) {
1123 		    m.offensive = obj;
1124 		    m.has_offense = MUSE_SCR_EARTH;
1125 		}
1126 #if 0
1127 		nomore(MUSE_SCR_FIRE);
1128 		if (obj->otyp == SCR_FIRE && resists_fire(mtmp)
1129 		   && dist2(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy) <= 2
1130 		   && mtmp->mcansee && haseyes(mtmp->data)) {
1131 			m.offensive = obj;
1132 			m.has_offense = MUSE_SCR_FIRE;
1133 		}
1134 #endif
1135 	}
1136 	return((boolean)(!!m.has_offense));
1137 #undef nomore
1138 }
1139 
1140 STATIC_PTR
1141 int
mbhitm(mtmp,otmp)1142 mbhitm(mtmp, otmp)
1143 register struct monst *mtmp;
1144 register struct obj *otmp;
1145 {
1146 	int tmp;
1147 
1148 	boolean reveal_invis = FALSE;
1149 	if (mtmp != &youmonst) {
1150 		mtmp->msleeping = 0;
1151 		if (mtmp->m_ap_type) seemimic(mtmp);
1152 	}
1153 	switch(otmp->otyp) {
1154 	case WAN_STRIKING:
1155 		reveal_invis = TRUE;
1156 		if (mtmp == &youmonst) {
1157 			if (zap_oseen) makeknown(WAN_STRIKING);
1158 			if (Antimagic) {
1159 			    shieldeff(u.ux, u.uy);
1160 			    pline("Boing!");
1161 			} else if (rnd(20) < 10 + u.uac) {
1162 			    pline_The("wand hits you!");
1163 			    tmp = d(2,12);
1164 			    if(Half_spell_damage) tmp = (tmp+1) / 2;
1165 			    losehp(tmp, "wand", KILLED_BY_AN);
1166 			} else pline_The("wand misses you.");
1167 			stop_occupation();
1168 			nomul(0, 0);
1169 		} else if (resists_magm(mtmp)) {
1170 			shieldeff(mtmp->mx, mtmp->my);
1171 			pline("Boing!");
1172 		} else if (rnd(20) < 10+find_mac(mtmp)) {
1173 			tmp = d(2,12);
1174 			hit("wand", mtmp, exclam(tmp));
1175 			(void) resist(mtmp, otmp->oclass, tmp, TELL);
1176 			if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
1177 				makeknown(WAN_STRIKING);
1178 		} else {
1179 			miss("wand", mtmp);
1180 			if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
1181 				makeknown(WAN_STRIKING);
1182 		}
1183 		break;
1184 	case WAN_TELEPORTATION:
1185 		if (mtmp == &youmonst) {
1186 			if (zap_oseen) makeknown(WAN_TELEPORTATION);
1187 			tele();
1188 		} else {
1189 			/* for consistency with zap.c, don't identify */
1190 			if (mtmp->ispriest &&
1191 				*in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
1192 			    if (cansee(mtmp->mx, mtmp->my))
1193 				pline("%s resists the magic!", Monnam(mtmp));
1194 			    mtmp->msleeping = 0;
1195 			    if(mtmp->m_ap_type) seemimic(mtmp);
1196 			} else if (!tele_restrict(mtmp))
1197 			    (void) rloc(mtmp, FALSE);
1198 		}
1199 		break;
1200 	case WAN_CANCELLATION:
1201 	case SPE_CANCELLATION:
1202 		(void) cancel_monst(mtmp, otmp, FALSE, TRUE, FALSE);
1203 		break;
1204 	}
1205 	if (reveal_invis) {
1206 	    if (mtmp->mhp > 0 && cansee(bhitpos.x,bhitpos.y)
1207 							&& !canspotmon(mtmp))
1208 		map_invisible(bhitpos.x, bhitpos.y);
1209 	}
1210 	return 0;
1211 }
1212 
1213 /* A modified bhit() for monsters.  Based on bhit() in zap.c.  Unlike
1214  * buzz(), bhit() doesn't take into account the possibility of a monster
1215  * zapping you, so we need a special function for it.  (Unless someone wants
1216  * to merge the two functions...)
1217  */
1218 STATIC_OVL void
mbhit(mon,range,fhitm,fhito,obj)1219 mbhit(mon,range,fhitm,fhito,obj)
1220 struct monst *mon;			/* monster shooting the wand */
1221 register int range;			/* direction and range */
1222 int FDECL((*fhitm),(MONST_P,OBJ_P));
1223 int FDECL((*fhito),(OBJ_P,OBJ_P));	/* fns called when mon/obj hit */
1224 struct obj *obj;			/* 2nd arg to fhitm/fhito */
1225 {
1226 	register struct monst *mtmp;
1227 	register struct obj *otmp;
1228 	register uchar typ;
1229 	int ddx, ddy;
1230 
1231 	bhitpos.x = mon->mx;
1232 	bhitpos.y = mon->my;
1233 	ddx = sgn(mon->mux - mon->mx);
1234 	ddy = sgn(mon->muy - mon->my);
1235 
1236 	while(range-- > 0) {
1237 		int x,y;
1238 
1239 		bhitpos.x += ddx;
1240 		bhitpos.y += ddy;
1241 		x = bhitpos.x; y = bhitpos.y;
1242 
1243 		if (!isok(x,y)) {
1244 		    bhitpos.x -= ddx;
1245 		    bhitpos.y -= ddy;
1246 		    break;
1247 		}
1248 		if (find_drawbridge(&x,&y))
1249 		    switch (obj->otyp) {
1250 			case WAN_STRIKING:
1251 			    destroy_drawbridge(x,y);
1252 		    }
1253 		if(bhitpos.x==u.ux && bhitpos.y==u.uy) {
1254 			(*fhitm)(&youmonst, obj);
1255 			range -= 3;
1256 		} else if(MON_AT(bhitpos.x, bhitpos.y)){
1257 			mtmp = m_at(bhitpos.x,bhitpos.y);
1258 			if (cansee(bhitpos.x,bhitpos.y) && !canspotmon(mtmp))
1259 			    map_invisible(bhitpos.x, bhitpos.y);
1260 			(*fhitm)(mtmp, obj);
1261 			range -= 3;
1262 		}
1263 		/* modified by GAN to hit all objects */
1264 		if(fhito){
1265 		    int hitanything = 0;
1266 		    register struct obj *next_obj;
1267 
1268 		    for(otmp = level.objects[bhitpos.x][bhitpos.y];
1269 							otmp; otmp = next_obj) {
1270 			/* Fix for polymorph bug, Tim Wright */
1271 			next_obj = otmp->nexthere;
1272 			hitanything += (*fhito)(otmp, obj);
1273 		    }
1274 		    if(hitanything)	range--;
1275 		}
1276 		typ = levl[bhitpos.x][bhitpos.y].typ;
1277 		if(IS_DOOR(typ) || typ == SDOOR) {
1278 		    switch (obj->otyp) {
1279 			/* note: monsters don't use opening or locking magic
1280 			   at present, but keep these as placeholders */
1281 			case WAN_OPENING:
1282 			case WAN_LOCKING:
1283 			case WAN_STRIKING:
1284 			    if (doorlock(obj, bhitpos.x, bhitpos.y)) {
1285 				makeknown(obj->otyp);
1286 				/* if a shop door gets broken, add it to
1287 				   the shk's fix list (no cost to player) */
1288 				if (levl[bhitpos.x][bhitpos.y].doormask ==
1289 					D_BROKEN &&
1290 				    *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE))
1291 				    add_damage(bhitpos.x, bhitpos.y, 0L);
1292 			    }
1293 			    break;
1294 		    }
1295 		}
1296 		if(!ZAP_POS(typ) || (IS_DOOR(typ) &&
1297 		   (levl[bhitpos.x][bhitpos.y].doormask & (D_LOCKED | D_CLOSED)))
1298 		  ) {
1299 			bhitpos.x -= ddx;
1300 			bhitpos.y -= ddy;
1301 			break;
1302 		}
1303 	}
1304 }
1305 
1306 /* Perform an offensive action for a monster.  Must be called immediately
1307  * after find_offensive().  Return values are same as use_defensive().
1308  */
1309 int
use_offensive(mtmp)1310 use_offensive(mtmp)
1311 struct monst *mtmp;
1312 {
1313 	int i;
1314 	struct obj *otmp = m.offensive;
1315 	boolean oseen;
1316 
1317 	/* offensive potions are not drunk, they're thrown */
1318 	if (otmp->oclass != POTION_CLASS && (i = precheck(mtmp, otmp)) != 0)
1319 		return i;
1320 	oseen = otmp && canseemon(mtmp);
1321 
1322 	switch(m.has_offense) {
1323 	case MUSE_WAN_DEATH:
1324 	case MUSE_WAN_SLEEP:
1325 	case MUSE_WAN_FIRE:
1326 	case MUSE_WAN_COLD:
1327 	case MUSE_WAN_LIGHTNING:
1328 	case MUSE_WAN_MAGIC_MISSILE:
1329 		mzapmsg(mtmp, otmp, FALSE);
1330 		otmp->spe--;
1331 		if (oseen) makeknown(otmp->otyp);
1332 		m_using = TRUE;
1333 		buzz((int)(-30 - (otmp->otyp - WAN_MAGIC_MISSILE)),
1334 			(otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6,
1335 			mtmp->mx, mtmp->my,
1336 			sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my));
1337 		m_using = FALSE;
1338 		return (mtmp->mhp <= 0) ? 1 : 2;
1339 	case MUSE_FIRE_HORN:
1340 	case MUSE_FROST_HORN:
1341 		if (oseen) {
1342 			makeknown(otmp->otyp);
1343 			pline("%s plays a %s!", Monnam(mtmp), xname(otmp));
1344 		} else
1345 			You_hear("a horn being played.");
1346 		otmp->spe--;
1347 		m_using = TRUE;
1348 		buzz(-30 - ((otmp->otyp==FROST_HORN) ? AD_COLD-1 : AD_FIRE-1),
1349 			rn1(6,6), mtmp->mx, mtmp->my,
1350 			sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my));
1351 		m_using = FALSE;
1352 		return (mtmp->mhp <= 0) ? 1 : 2;
1353 	case MUSE_WAN_TELEPORTATION:
1354 	case MUSE_WAN_STRIKING:
1355 	case MUSE_WAN_CANCELLATION:
1356 		zap_oseen = oseen;
1357 		mzapmsg(mtmp, otmp, FALSE);
1358 		otmp->spe--;
1359 		m_using = TRUE;
1360 		mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp);
1361 		m_using = FALSE;
1362 		return 2;
1363 	case MUSE_SCR_EARTH:
1364 	    {
1365 		/* TODO: handle steeds */
1366 	    	register int x, y;
1367 		/* don't use monster fields after killing it */
1368 		boolean confused = (mtmp->mconf ? TRUE : FALSE);
1369 		int mmx = mtmp->mx, mmy = mtmp->my;
1370 
1371 		mreadmsg(mtmp, otmp);
1372 	    	/* Identify the scroll */
1373 		if (canspotmon(mtmp)) {
1374 		    pline_The("%s rumbles %s %s!", ceiling(mtmp->mx, mtmp->my),
1375 	    			otmp->blessed ? "around" : "above",
1376 				mon_nam(mtmp));
1377 		    if (oseen) makeknown(otmp->otyp);
1378 		} else if (cansee(mtmp->mx, mtmp->my)) {
1379 		    pline_The("%s rumbles in the middle of nowhere!",
1380 			ceiling(mtmp->mx, mtmp->my));
1381 		    if (mtmp->minvis)
1382 			map_invisible(mtmp->mx, mtmp->my);
1383 		    if (oseen) makeknown(otmp->otyp);
1384 		}
1385 
1386 	    	/* Loop through the surrounding squares */
1387 	    	for (x = mmx-1; x <= mmx+1; x++) {
1388 	    	    for (y = mmy-1; y <= mmy+1; y++) {
1389 	    	    	/* Is this a suitable spot? */
1390 	    	    	if (isok(x, y) && !closed_door(x, y) &&
1391 	    	    			!IS_ROCK(levl[x][y].typ) &&
1392 	    	    			!IS_AIR(levl[x][y].typ) &&
1393 #ifdef BLACKMARKET
1394 	    	    			!(Is_blackmarket(&u.uz) && rn2(2)) &&
1395 #endif
1396 	    	    			(((x == mmx) && (y == mmy)) ?
1397 	    	    			    !otmp->blessed : !otmp->cursed) &&
1398 					(x != u.ux || y != u.uy)) {
1399 				drop_boulder_on_monster(x, y, confused, FALSE);
1400 	    	    	}
1401 		    }
1402 		}
1403 		m_useup(mtmp, otmp);
1404 		/* Attack the player */
1405 		if (distmin(mmx, mmy, u.ux, u.uy) == 1 && !otmp->cursed) {
1406 		    drop_boulder_on_player(confused, !otmp->cursed, FALSE, TRUE);
1407 		}
1408 
1409 		return (mtmp->mhp <= 0) ? 1 : 2;
1410 	    }
1411 #if 0
1412 	case MUSE_SCR_FIRE:
1413 	      {
1414 		boolean vis = cansee(mtmp->mx, mtmp->my);
1415 
1416 		mreadmsg(mtmp, otmp);
1417 		if (mtmp->mconf) {
1418 			if (vis)
1419 			    pline("Oh, what a pretty fire!");
1420 		} else {
1421 			struct monst *mtmp2;
1422 			int num;
1423 
1424 			if (vis)
1425 			    pline_The("scroll erupts in a tower of flame!");
1426 			shieldeff(mtmp->mx, mtmp->my);
1427 			pline("%s is uninjured.", Monnam(mtmp));
1428 			(void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
1429 			(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
1430 			(void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
1431 			num = (2*(rn1(3, 3) + 2 * bcsign(otmp)) + 1)/3;
1432 			if (Fire_resistance)
1433 			    You("are not harmed.");
1434 			burn_away_slime();
1435 			if (Half_spell_damage) num = (num+1) / 2;
1436 			else losehp(num, "scroll of fire", KILLED_BY_AN);
1437 			for(mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) {
1438 			   if(DEADMONSTER(mtmp2)) continue;
1439 			   if(mtmp == mtmp2) continue;
1440 			   if(dist2(mtmp2->mx,mtmp2->my,mtmp->mx,mtmp->my) < 3){
1441 				if (resists_fire(mtmp2)) continue;
1442 				mtmp2->mhp -= num;
1443 				if (resists_cold(mtmp2))
1444 				    mtmp2->mhp -= 3*num;
1445 				if(mtmp2->mhp < 1) {
1446 				    mondied(mtmp2);
1447 				    break;
1448 				}
1449 			    }
1450 			}
1451 		}
1452 		return 2;
1453 	      }
1454 #endif	/* 0 */
1455 	case MUSE_POT_PARALYSIS:
1456 	case MUSE_POT_BLINDNESS:
1457 	case MUSE_POT_CONFUSION:
1458 	case MUSE_POT_SLEEPING:
1459 	case MUSE_POT_ACID:
1460 		/* Note: this setting of dknown doesn't suffice.  A monster
1461 		 * which is out of sight might throw and it hits something _in_
1462 		 * sight, a problem not existing with wands because wand rays
1463 		 * are not objects.  Also set dknown in mthrowu.c.
1464 		 */
1465 		if (cansee(mtmp->mx, mtmp->my)) {
1466 			otmp->dknown = 1;
1467 			pline("%s hurls %s!", Monnam(mtmp),
1468 						singular(otmp, doname));
1469 		}
1470 		m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux-mtmp->mx),
1471 			sgn(mtmp->muy-mtmp->my),
1472 			distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy), otmp);
1473 		return 2;
1474 	case 0: return 0; /* i.e. an exploded wand */
1475 	default: warning("%s wanted to perform action %d?", Monnam(mtmp),
1476 			m.has_offense);
1477 		break;
1478 	}
1479 	return 0;
1480 }
1481 
1482 int
rnd_offensive_item(mtmp)1483 rnd_offensive_item(mtmp)
1484 struct monst *mtmp;
1485 {
1486 	struct permonst *pm = mtmp->data;
1487 	int difficulty = monstr[(monsndx(pm))];
1488 
1489 	if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1490 			|| pm->mlet == S_GHOST
1491 # ifdef KOPS
1492 			|| pm->mlet == S_KOP
1493 # endif
1494 		) return 0;
1495 	if (difficulty > 7 && !rn2(35)) return WAN_DEATH;
1496 	switch (rn2(9 - (difficulty < 4) + 4 * (difficulty > 6))) {
1497 		case 0: {
1498 		    struct obj *helmet = which_armor(mtmp, W_ARMH);
1499 
1500 		    if ((helmet && is_metallic(helmet)) || amorphous(pm) || passes_walls(pm) || noncorporeal(pm) || unsolid(pm))
1501 			return SCR_EARTH;
1502 		} /* fall through */
1503 		case 1: return WAN_STRIKING;
1504 		case 2: return POT_ACID;
1505 		case 3: return POT_CONFUSION;
1506 		case 4: return POT_BLINDNESS;
1507 		case 5: return POT_SLEEPING;
1508 		case 6: return POT_PARALYSIS;
1509 		case 7: case 8:
1510 			return WAN_MAGIC_MISSILE;
1511 		case 9: return WAN_SLEEP;
1512 		case 10: return WAN_FIRE;
1513 		case 11: return WAN_COLD;
1514 		case 12: return WAN_LIGHTNING;
1515 	}
1516 	/*NOTREACHED*/
1517 	return 0;
1518 }
1519 
1520 #define MUSE_POT_GAIN_LEVEL 1
1521 #define MUSE_WAN_MAKE_INVISIBLE 2
1522 #define MUSE_POT_INVISIBILITY 3
1523 #define MUSE_POLY_TRAP 4
1524 #define MUSE_WAN_POLYMORPH 5
1525 #define MUSE_POT_SPEED 6
1526 #define MUSE_WAN_SPEED_MONSTER 7
1527 #define MUSE_BULLWHIP 8
1528 #define MUSE_POT_POLYMORPH 9
1529 
1530 boolean
find_misc(mtmp)1531 find_misc(mtmp)
1532 struct monst *mtmp;
1533 {
1534 	register struct obj *obj;
1535 	struct permonst *mdat = mtmp->data;
1536 	int x = mtmp->mx, y = mtmp->my;
1537 	struct trap *t;
1538 	int xx, yy;
1539 	boolean immobile = (mdat->mmove == 0);
1540 	boolean stuck = (mtmp == u.ustuck);
1541 
1542 	m.misc = (struct obj *)0;
1543 	m.has_misc = 0;
1544 	if (is_animal(mdat) || mindless(mdat))
1545 		return 0;
1546 	if (u.uswallow && stuck) return FALSE;
1547 
1548 	/* We arbitrarily limit to times when a player is nearby for the
1549 	 * same reason as Junior Pac-Man doesn't have energizers eaten until
1550 	 * you can see them...
1551 	 */
1552 	if(dist2(x, y, mtmp->mux, mtmp->muy) > 36)
1553 		return FALSE;
1554 
1555 	if (!stuck && !immobile && !mtmp->cham && monstr[monsndx(mdat)] < 6) {
1556 	  boolean ignore_boulders = (verysmall(mdat) ||
1557 				     throws_rocks(mdat) ||
1558 				     passes_walls(mdat));
1559 	  for(xx = x-1; xx <= x+1; xx++)
1560 	    for(yy = y-1; yy <= y+1; yy++)
1561 		if (isok(xx,yy) && (xx != u.ux || yy != u.uy))
1562 		    if (mdat != &mons[PM_GRID_BUG] || xx == x || yy == y)
1563 			if (/* (xx==x && yy==y) || */ !level.monsters[xx][yy])
1564 			    if ((t = t_at(xx, yy)) != 0 &&
1565 			      (ignore_boulders || !sobj_at(BOULDER, xx, yy))
1566 			      && !onscary(xx, yy, mtmp)) {
1567 				if (t->ttyp == POLY_TRAP) {
1568 				    trapx = xx;
1569 				    trapy = yy;
1570 				    m.has_misc = MUSE_POLY_TRAP;
1571 				    return TRUE;
1572 				}
1573 			    }
1574 	}
1575 	if (nohands(mdat))
1576 		return 0;
1577 
1578 #define nomore(x) if(m.has_misc==x) continue;
1579 	for(obj=mtmp->minvent; obj; obj=obj->nobj) {
1580 		/* Monsters shouldn't recognize cursed items; this kludge is */
1581 		/* necessary to prevent serious problems though... */
1582 		if(obj->otyp == POT_GAIN_LEVEL && (!obj->cursed ||
1583 			    (!mtmp->isgd && !mtmp->isshk && !mtmp->ispriest))) {
1584 			m.misc = obj;
1585 			m.has_misc = MUSE_POT_GAIN_LEVEL;
1586 		}
1587 		nomore(MUSE_BULLWHIP);
1588 		if(obj->otyp == BULLWHIP && (MON_WEP(mtmp) == obj) &&
1589 		   distu(mtmp->mx,mtmp->my)==1 && uwep && !mtmp->mpeaceful) {
1590 			m.misc = obj;
1591 			m.has_misc = MUSE_BULLWHIP;
1592 		}
1593 		/* Note: peaceful/tame monsters won't make themselves
1594 		 * invisible unless you can see them.  Not really right, but...
1595 		 */
1596 		nomore(MUSE_WAN_MAKE_INVISIBLE);
1597 		if(obj->otyp == WAN_MAKE_INVISIBLE && obj->spe > 0 &&
1598 		    !mtmp->minvis && !mtmp->invis_blkd &&
1599 		    (!mtmp->mpeaceful || See_invisible) &&
1600 		    (!attacktype(mtmp->data, AT_GAZE) || mtmp->mcan)) {
1601 			m.misc = obj;
1602 			m.has_misc = MUSE_WAN_MAKE_INVISIBLE;
1603 		}
1604 		nomore(MUSE_POT_INVISIBILITY);
1605 		if(obj->otyp == POT_INVISIBILITY &&
1606 		    !mtmp->minvis && !mtmp->invis_blkd &&
1607 		    (!mtmp->mpeaceful || See_invisible) &&
1608 		    (!attacktype(mtmp->data, AT_GAZE) || mtmp->mcan)) {
1609 			m.misc = obj;
1610 			m.has_misc = MUSE_POT_INVISIBILITY;
1611 		}
1612 		nomore(MUSE_WAN_SPEED_MONSTER);
1613 		if(obj->otyp == WAN_SPEED_MONSTER && obj->spe > 0
1614 				&& mtmp->mspeed != MFAST && !mtmp->isgd) {
1615 			m.misc = obj;
1616 			m.has_misc = MUSE_WAN_SPEED_MONSTER;
1617 		}
1618 		nomore(MUSE_POT_SPEED);
1619 		if(obj->otyp == POT_SPEED && mtmp->mspeed != MFAST
1620 							&& !mtmp->isgd) {
1621 			m.misc = obj;
1622 			m.has_misc = MUSE_POT_SPEED;
1623 		}
1624 		nomore(MUSE_WAN_POLYMORPH);
1625 		if(obj->otyp == WAN_POLYMORPH && obj->spe > 0 && !mtmp->cham
1626 				&& monstr[monsndx(mdat)] < 6) {
1627 			m.misc = obj;
1628 			m.has_misc = MUSE_WAN_POLYMORPH;
1629 		}
1630 		nomore(MUSE_POT_POLYMORPH);
1631 		if(obj->otyp == POT_POLYMORPH && !mtmp->cham
1632 				&& monstr[monsndx(mdat)] < 6) {
1633 			m.misc = obj;
1634 			m.has_misc = MUSE_POT_POLYMORPH;
1635 		}
1636 	}
1637 	return((boolean)(!!m.has_misc));
1638 #undef nomore
1639 }
1640 
1641 /* type of monster to polymorph into; defaults to one suitable for the
1642    current level rather than the totally arbitrary choice of newcham() */
1643 static struct permonst *
muse_newcham_mon(mon)1644 muse_newcham_mon(mon)
1645 struct monst *mon;
1646 {
1647 	struct obj *m_armr;
1648 
1649 	if ((m_armr = which_armor(mon, W_ARM)) != 0) {
1650 	    if (Is_dragon_scales(m_armr->otyp))
1651 		return Dragon_scales_to_pm(m_armr);
1652 	    else if (Is_dragon_mail(m_armr->otyp))
1653 		return Dragon_mail_to_pm(m_armr);
1654 	}
1655 	return rndmonst();
1656 }
1657 
1658 int
use_misc(mtmp)1659 use_misc(mtmp)
1660 struct monst *mtmp;
1661 {
1662 	int i;
1663 	struct obj *otmp = m.misc;
1664 	boolean vis, vismon, oseen;
1665 	char nambuf[BUFSZ];
1666 
1667 	if ((i = precheck(mtmp, otmp)) != 0) return i;
1668 	vis = cansee(mtmp->mx, mtmp->my);
1669 	vismon = canseemon(mtmp);
1670 	oseen = otmp && vismon;
1671 
1672 	switch(m.has_misc) {
1673 	case MUSE_POT_GAIN_LEVEL:
1674 		mquaffmsg(mtmp, otmp);
1675 		if (otmp->cursed) {
1676 		    if (Can_rise_up(mtmp->mx, mtmp->my, &u.uz)) {
1677 			register int tolev = depth(&u.uz)-1;
1678 			d_level tolevel;
1679 
1680 			get_level(&tolevel, tolev);
1681 			/* insurance against future changes... */
1682 			if(on_level(&tolevel, &u.uz)) goto skipmsg;
1683 			if (vismon) {
1684 			    pline("%s rises up, through the %s!",
1685 				  Monnam(mtmp), ceiling(mtmp->mx, mtmp->my));
1686 			    if(!objects[POT_GAIN_LEVEL].oc_name_known
1687 			      && !objects[POT_GAIN_LEVEL].oc_uname)
1688 				docall(otmp);
1689 			}
1690 			m_useup(mtmp, otmp);
1691 			migrate_to_level(mtmp, ledger_no(&tolevel),
1692 					 MIGR_RANDOM, (coord *)0);
1693 			return 2;
1694 		    } else {
1695 skipmsg:
1696 			if (vismon) {
1697 			    pline("%s looks uneasy.", Monnam(mtmp));
1698 			    if(!objects[POT_GAIN_LEVEL].oc_name_known
1699 			      && !objects[POT_GAIN_LEVEL].oc_uname)
1700 				docall(otmp);
1701 			}
1702 			m_useup(mtmp, otmp);
1703 			return 2;
1704 		    }
1705 		}
1706 		if (vismon) pline("%s seems more experienced.", Monnam(mtmp));
1707 		if (oseen) makeknown(POT_GAIN_LEVEL);
1708 		m_useup(mtmp, otmp);
1709 		if (!grow_up(mtmp,(struct monst *)0)) return 1;
1710 			/* grew into genocided monster */
1711 		return 2;
1712 	case MUSE_WAN_MAKE_INVISIBLE:
1713 	case MUSE_POT_INVISIBILITY:
1714 		if (otmp->otyp == WAN_MAKE_INVISIBLE) {
1715 		    mzapmsg(mtmp, otmp, TRUE);
1716 		    otmp->spe--;
1717 		} else
1718 		    mquaffmsg(mtmp, otmp);
1719 		/* format monster's name before altering its visibility */
1720 		Strcpy(nambuf, See_invisible ? Monnam(mtmp) : mon_nam(mtmp));
1721 		mon_set_minvis(mtmp);
1722 		if (vismon && mtmp->minvis) {	/* was seen, now invisible */
1723 		    if (See_invisible)
1724 			pline("%s body takes on a %s transparency.",
1725 			      s_suffix(nambuf),
1726 			      Hallucination ? "normal" : "strange");
1727 		    else
1728 			pline("Suddenly you cannot see %s.", nambuf);
1729 		    if (oseen) makeknown(otmp->otyp);
1730 		}
1731 		if (otmp->otyp == POT_INVISIBILITY) {
1732 		    if (otmp->cursed) you_aggravate(mtmp);
1733 		    m_useup(mtmp, otmp);
1734 		}
1735 		return 2;
1736 	case MUSE_WAN_SPEED_MONSTER:
1737 		mzapmsg(mtmp, otmp, TRUE);
1738 		otmp->spe--;
1739 		mon_adjust_speed(mtmp, 1, otmp);
1740 		return 2;
1741 	case MUSE_POT_SPEED:
1742 		mquaffmsg(mtmp, otmp);
1743 		/* note difference in potion effect due to substantially
1744 		   different methods of maintaining speed ratings:
1745 		   player's character becomes "very fast" temporarily;
1746 		   monster becomes "one stage faster" permanently */
1747 		mon_adjust_speed(mtmp, 1, otmp);
1748 		m_useup(mtmp, otmp);
1749 		return 2;
1750 	case MUSE_WAN_POLYMORPH:
1751 		mzapmsg(mtmp, otmp, TRUE);
1752 		otmp->spe--;
1753 		(void) newcham(mtmp, muse_newcham_mon(mtmp), TRUE, FALSE);
1754 		if (oseen) makeknown(WAN_POLYMORPH);
1755 		return 2;
1756 	case MUSE_POT_POLYMORPH:
1757 		mquaffmsg(mtmp, otmp);
1758 		if (vismon) pline("%s suddenly mutates!", Monnam(mtmp));
1759 		(void) newcham(mtmp, muse_newcham_mon(mtmp), FALSE, FALSE);
1760 		if (oseen) makeknown(POT_POLYMORPH);
1761 		m_useup(mtmp, otmp);
1762 		return 2;
1763 	case MUSE_POLY_TRAP:
1764 		if (vismon)
1765 		    pline("%s deliberately %s onto a polymorph trap!",
1766 			Monnam(mtmp),
1767 			makeplural(locomotion(mtmp->data, "jump")));
1768 		if (vis) seetrap(t_at(trapx,trapy));
1769 
1770 		/*  don't use rloc() due to worms */
1771 		remove_monster(mtmp->mx, mtmp->my);
1772 		newsym(mtmp->mx, mtmp->my);
1773 		place_monster(mtmp, trapx, trapy);
1774 		if (mtmp->wormno) worm_move(mtmp);
1775 		newsym(trapx, trapy);
1776 
1777 		(void) newcham(mtmp, (struct permonst *)0, FALSE, FALSE);
1778 		return 2;
1779 	case MUSE_BULLWHIP:
1780 		/* attempt to disarm hero */
1781 		if (uwep && !rn2(5)) {
1782 		    const char *The_whip = vismon ? "The bullwhip" : "A whip";
1783 		    int where_to = rn2(4);
1784 		    struct obj *obj = uwep;
1785 		    const char *hand;
1786 		    char the_weapon[BUFSZ];
1787 
1788 		    Strcpy(the_weapon, the(xname(obj)));
1789 		    hand = body_part(HAND);
1790 		    if (bimanual(obj)) hand = makeplural(hand);
1791 
1792 		    if (vismon)
1793 			pline("%s flicks a bullwhip towards your %s!",
1794 			      Monnam(mtmp), hand);
1795 		    if (obj->otyp == HEAVY_IRON_BALL) {
1796 			pline("%s fails to wrap around %s.",
1797 			      The_whip, the_weapon);
1798 			return 1;
1799 		    }
1800 		    pline("%s wraps around %s you're wielding!",
1801 			  The_whip, the_weapon);
1802 		    if (welded(obj)) {
1803 			pline("%s welded to your %s%c",
1804 			      !is_plural(obj) ? "It is" : "They are",
1805 			      hand, !obj->bknown ? '!' : '.');
1806 			/* obj->bknown = 1; */ /* welded() takes care of this */
1807 			where_to = 0;
1808 		    }
1809 		    if (!where_to) {
1810 			pline_The("whip slips free.");  /* not `The_whip' */
1811 			return 1;
1812 		    } else if (where_to == 3 && hates_silver(mtmp->data) &&
1813 			    objects[obj->otyp].oc_material == SILVER) {
1814 			/* this monster won't want to catch a silver
1815 			   weapon; drop it at hero's feet instead */
1816 			where_to = 2;
1817 		    }
1818 		    freeinv(obj);
1819 		    uwepgone();
1820 		    switch (where_to) {
1821 			case 1:		/* onto floor beneath mon */
1822 			    pline("%s yanks %s from your %s!", Monnam(mtmp),
1823 				  the_weapon, hand);
1824 			    place_object(obj, mtmp->mx, mtmp->my);
1825 			    break;
1826 			case 2:		/* onto floor beneath you */
1827 			    pline("%s yanks %s to the %s!", Monnam(mtmp),
1828 				  the_weapon, surface(u.ux, u.uy));
1829 			    dropy(obj);
1830 			    break;
1831 			case 3:		/* into mon's inventory */
1832 			    pline("%s snatches %s!", Monnam(mtmp),
1833 				  the_weapon);
1834 			    (void) mpickobj(mtmp,obj);
1835 			    break;
1836 		    }
1837 		    return 1;
1838 		}
1839 		return 0;
1840 	case 0: return 0; /* i.e. an exploded wand */
1841 	default: warning("%s wanted to perform action %d?", Monnam(mtmp),
1842 			m.has_misc);
1843 		break;
1844 	}
1845 	return 0;
1846 }
1847 
1848 STATIC_OVL void
you_aggravate(mtmp)1849 you_aggravate(mtmp)
1850 struct monst *mtmp;
1851 {
1852 	pline("For some reason, %s presence is known to you.",
1853 		s_suffix(noit_mon_nam(mtmp)));
1854 	cls();
1855 #ifdef CLIPPING
1856 	cliparound(mtmp->mx, mtmp->my);
1857 #endif
1858 	show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp));
1859 	display_self();
1860 	You_feel("aggravated at %s.", noit_mon_nam(mtmp));
1861 	display_nhwindow(WIN_MAP, TRUE);
1862 	docrt();
1863 	if (unconscious()) {
1864 		multi = -1;
1865 		nomovemsg =
1866 		      "Aggravated, you are jolted into full consciousness.";
1867 	}
1868 	newsym(mtmp->mx,mtmp->my);
1869 	if (!canspotmon(mtmp))
1870 	    map_invisible(mtmp->mx, mtmp->my);
1871 }
1872 
1873 int
rnd_misc_item(mtmp)1874 rnd_misc_item(mtmp)
1875 struct monst *mtmp;
1876 {
1877 	struct permonst *pm = mtmp->data;
1878 	int difficulty = monstr[(monsndx(pm))];
1879 
1880 	if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1881 			|| pm->mlet == S_GHOST
1882 # ifdef KOPS
1883 			|| pm->mlet == S_KOP
1884 # endif
1885 		) return 0;
1886 	/* Unlike other rnd_item functions, we only allow _weak_ monsters
1887 	 * to have this item; after all, the item will be used to strengthen
1888 	 * the monster and strong monsters won't use it at all...
1889 	 */
1890 	if (difficulty < 6 && !rn2(30))
1891 	    return rn2(6) ? POT_POLYMORPH : WAN_POLYMORPH;
1892 
1893 	if (!rn2(40) && !nonliving(pm)) return AMULET_OF_LIFE_SAVING;
1894 
1895 	switch (rn2(3)) {
1896 		case 0:
1897 			if (mtmp->isgd) return 0;
1898 			return rn2(6) ? POT_SPEED : WAN_SPEED_MONSTER;
1899 		case 1:
1900 			if (mtmp->mpeaceful && !See_invisible) return 0;
1901 			return rn2(6) ? POT_INVISIBILITY : WAN_MAKE_INVISIBLE;
1902 		case 2:
1903 			return POT_GAIN_LEVEL;
1904 	}
1905 	/*NOTREACHED*/
1906 	return 0;
1907 }
1908 
1909 boolean
searches_for_item(mon,obj)1910 searches_for_item(mon, obj)
1911 struct monst *mon;
1912 struct obj *obj;
1913 {
1914 	int typ = obj->otyp;
1915 
1916 	if (is_animal(mon->data) ||
1917 		mindless(mon->data) ||
1918 		mon->data == &mons[PM_GHOST])	/* don't loot bones piles */
1919 	    return FALSE;
1920 
1921 	if (typ == WAN_MAKE_INVISIBLE || typ == POT_INVISIBILITY)
1922 	    return (boolean)(!mon->minvis && !mon->invis_blkd && !attacktype(mon->data, AT_GAZE));
1923 	if (typ == WAN_SPEED_MONSTER || typ == POT_SPEED)
1924 	    return (boolean)(mon->mspeed != MFAST);
1925 
1926 	switch (obj->oclass) {
1927 	case WAND_CLASS:
1928 	    if (obj->spe <= 0)
1929 		return FALSE;
1930 	    if (typ == WAN_DIGGING)
1931 		return (boolean)(!is_floater(mon->data));
1932 	    if (typ == WAN_POLYMORPH)
1933 		return (boolean)(monstr[monsndx(mon->data)] < 6);
1934 	    if (objects[typ].oc_dir == RAY ||
1935 		    typ == WAN_STRIKING ||
1936 		    typ == WAN_TELEPORTATION ||
1937 		    typ == WAN_CREATE_MONSTER)
1938 		return TRUE;
1939 	    break;
1940 	case POTION_CLASS:
1941 	    if (typ == POT_VAMPIRE_BLOOD)
1942 		return is_vampire(mon->data);
1943 	    if (typ == POT_HEALING ||
1944 		    typ == POT_EXTRA_HEALING ||
1945 		    typ == POT_FULL_HEALING ||
1946 		    typ == POT_POLYMORPH ||
1947 		    typ == POT_GAIN_LEVEL ||
1948 		    typ == POT_PARALYSIS ||
1949 		    typ == POT_SLEEPING ||
1950 		    typ == POT_ACID ||
1951 		    typ == POT_CONFUSION)
1952 		return TRUE;
1953 	    if (typ == POT_BLINDNESS && !attacktype(mon->data, AT_GAZE))
1954 		return TRUE;
1955 	    break;
1956 	case SCROLL_CLASS:
1957 	    if (typ == SCR_TELEPORTATION || typ == SCR_CREATE_MONSTER
1958 		    || typ == SCR_EARTH)
1959 		return TRUE;
1960 	    break;
1961 	case AMULET_CLASS:
1962 	    if (typ == AMULET_OF_LIFE_SAVING)
1963 		return (boolean)(!nonliving(mon->data));
1964 	    if (typ == AMULET_OF_REFLECTION)
1965 		return TRUE;
1966 	    break;
1967 	case TOOL_CLASS:
1968 	    if (typ == PICK_AXE)
1969 		return (boolean)needspick(mon->data);
1970 	    if (typ == UNICORN_HORN)
1971 		return (boolean)(!obj->cursed && !is_unicorn(mon->data));
1972 	    if (typ == FROST_HORN || typ == FIRE_HORN)
1973 		return (obj->spe > 0);
1974 	    if ((typ == SKELETON_KEY) || (typ == CREDIT_CARD) || (typ == LOCK_PICK)) {
1975 		return (!nohands(mon->data) && !verysmall(mon->data) && !mindless(mon->data));
1976 	    }
1977 
1978 	    break;
1979 	case FOOD_CLASS:
1980 	    if (typ == CORPSE)
1981 		return (boolean)(((mon->misc_worn_check & W_ARMG) &&
1982 				    touch_petrifies(&mons[obj->corpsenm])) ||
1983 				(!resists_ston(mon) &&
1984 				    (obj->corpsenm == PM_LIZARD ||
1985 					(acidic(&mons[obj->corpsenm]) &&
1986 					 obj->corpsenm != PM_GREEN_SLIME))));
1987 	    if (typ == EGG)
1988 		return (boolean)(touch_petrifies(&mons[obj->corpsenm]));
1989 	    break;
1990 	default:
1991 	    break;
1992 	}
1993 
1994 	return FALSE;
1995 }
1996 
1997 boolean
mon_reflects(mon,str)1998 mon_reflects(mon,str)
1999 struct monst *mon;
2000 const char *str;
2001 {
2002 	struct obj *orefl = which_armor(mon, W_ARMS);
2003 
2004 	if (orefl && orefl->otyp == SHIELD_OF_REFLECTION) {
2005 	    if (str) {
2006 		pline(str, s_suffix(mon_nam(mon)), "shield");
2007 		makeknown(SHIELD_OF_REFLECTION);
2008 	    }
2009 	    return TRUE;
2010 	} else if (arti_reflects(MON_WEP(mon))) {
2011 	    /* due to wielded artifact weapon */
2012 	    if (str)
2013 		pline(str, s_suffix(mon_nam(mon)), "weapon");
2014 	    return TRUE;
2015 	} else if ((orefl = which_armor(mon, W_AMUL)) &&
2016 				orefl->otyp == AMULET_OF_REFLECTION) {
2017 	    if (str) {
2018 		pline(str, s_suffix(mon_nam(mon)), "amulet");
2019 		makeknown(AMULET_OF_REFLECTION);
2020 	    }
2021 	    return TRUE;
2022 	} else if ((orefl = which_armor(mon, W_ARM)) &&
2023 		(orefl->otyp == CHROMATIC_DRAGON_SCALES || orefl->otyp == CHROMATIC_DRAGON_SCALE_MAIL ||
2024 		 orefl->otyp == SILVER_DRAGON_SCALES || orefl->otyp == SILVER_DRAGON_SCALE_MAIL)) {
2025 	    if (str) {
2026 		pline(str, s_suffix(mon_nam(mon)), "armor");
2027 		if (orefl->otyp == SILVER_DRAGON_SCALES)
2028 		    identify_dragon(orefl->otyp - GRAY_DRAGON_SCALES);
2029 		if (orefl->otyp == SILVER_DRAGON_SCALE_MAIL)
2030 		    identify_dragon(orefl->otyp - GRAY_DRAGON_SCALE_MAIL);
2031 	    }
2032 	    return TRUE;
2033 	} else if (mon->data == &mons[PM_SILVER_DRAGON] ||
2034 		mon->data == &mons[PM_TIAMAT] ||
2035 		mon->data == &mons[PM_CHROMATIC_DRAGON]) {
2036 	    /* Silver dragons only reflect when mature; babies do not */
2037 	    if (str) {
2038 		pline(str, s_suffix(mon_nam(mon)), "scales");
2039 		if (mon->data == &mons[PM_SILVER_DRAGON])
2040 		    identify_dragon(monsndx(mon->data) - PM_GRAY_DRAGON);
2041 	    }
2042 	    return TRUE;
2043 	}
2044 	return FALSE;
2045 }
2046 
2047 boolean
ureflects(fmt,str)2048 ureflects (fmt, str)
2049 const char *fmt, *str;
2050 {
2051 	/* Check from outermost to innermost objects */
2052 	if (EReflecting & W_ARMS) {
2053 	    if (fmt && str) {
2054 	    	pline(fmt, str, "shield");
2055 	    	makeknown(SHIELD_OF_REFLECTION);
2056 	    }
2057 	    return TRUE;
2058 	} else if (EReflecting & W_WEP) {
2059 	    /* Due to wielded artifact weapon */
2060 	    if (fmt && str)
2061 	    	pline(fmt, str, "weapon");
2062 	    return TRUE;
2063 	} else if (EReflecting & W_AMUL) {
2064 	    if (fmt && str) {
2065 	    	pline(fmt, str, "medallion");
2066 	    	makeknown(AMULET_OF_REFLECTION);
2067 	    }
2068 	    return TRUE;
2069 	} else if (EReflecting & W_ARM) {
2070 	    if (fmt && str) {
2071 	    	pline(fmt, str, "armor");
2072 		makeknown(uarm->otyp);
2073 	    }
2074 	    return TRUE;
2075 	} else if ((youmonst.data == &mons[PM_SILVER_DRAGON]) ||
2076 		   (youmonst.data == &mons[PM_CHROMATIC_DRAGON])) {
2077 	    if (fmt && str) {
2078 	    	pline(fmt, str, "scales");
2079 		if (youmonst.data == &mons[PM_SILVER_DRAGON])
2080 		    identify_dragon(monsndx(youmonst.data) - PM_GRAY_DRAGON);
2081 	    }
2082 	    return TRUE;
2083 	}
2084 	return FALSE;
2085 }
2086 
2087 
2088 /* TRUE if the monster ate something */
2089 boolean
munstone(mon,by_you)2090 munstone(mon, by_you)
2091 struct monst *mon;
2092 boolean by_you;
2093 {
2094 	struct obj *obj;
2095 
2096 	if (resists_ston(mon)) return FALSE;
2097 	if (mon->meating || !mon->mcanmove || mon->msleeping) return FALSE;
2098 
2099 	for(obj = mon->minvent; obj; obj = obj->nobj) {
2100 	    /* Monsters can also use potions of acid */
2101 	    if ((obj->otyp == POT_ACID) || (obj->otyp == CORPSE &&
2102 	    		(obj->corpsenm == PM_LIZARD || (acidic(&mons[obj->corpsenm]) && obj->corpsenm != PM_GREEN_SLIME)))) {
2103 		mon_consume_unstone(mon, obj, by_you, TRUE);
2104 		return TRUE;
2105 	    }
2106 	}
2107 	return FALSE;
2108 }
2109 
2110 STATIC_OVL void
mon_consume_unstone(mon,obj,by_you,stoning)2111 mon_consume_unstone(mon, obj, by_you, stoning)
2112 struct monst *mon;
2113 struct obj *obj;
2114 boolean by_you;
2115 boolean stoning;
2116 {
2117     int nutrit = (obj->otyp == CORPSE) ? dog_nutrition(mon, obj) : 0;
2118     /* also sets meating */
2119 
2120     /* give a "<mon> is slowing down" message and also remove
2121        intrinsic speed (comparable to similar effect on the hero) */
2122     mon_adjust_speed(mon, -3, (struct obj *)0);
2123 
2124     if (canseemon(mon)) {
2125 	long save_quan = obj->quan;
2126 
2127 	obj->quan = 1L;
2128 	pline("%s %ss %s.", Monnam(mon),
2129 		    (obj->otyp == POT_ACID) ? "quaff" : "eat",
2130 		    distant_name(obj,doname));
2131 	obj->quan = save_quan;
2132     } else if (flags.soundok)
2133 	You_hear("%s.", (obj->otyp == POT_ACID) ? "drinking" : "chewing");
2134     m_useup(mon, obj);
2135     if (((obj->otyp == POT_ACID) || acidic(&mons[obj->corpsenm])) &&
2136 		    !resists_acid(mon)) {
2137 	mon->mhp -= rnd(15);
2138 	pline("%s has a very bad case of stomach acid.",
2139 	    Monnam(mon));
2140     }
2141     if (mon->mhp <= 0) {
2142 	pline("%s dies!", Monnam(mon));
2143 	if (by_you) xkilled(mon, 0);
2144 	else mondead(mon);
2145 	return;
2146     }
2147     if (stoning && canseemon(mon)) {
2148 	if (Hallucination)
2149     pline("What a pity - %s just ruined a future piece of art!",
2150 	    mon_nam(mon));
2151 	else
2152 	    pline("%s seems limber!", Monnam(mon));
2153     }
2154     if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD && mon->mconf) {
2155 	mon->mconf = 0;
2156 	if (canseemon(mon))
2157 	    pline("%s seems steadier now.", Monnam(mon));
2158     }
2159     if (mon->mtame && !mon->isminion && nutrit > 0) {
2160 	struct edog *edog = EDOG(mon);
2161 
2162 	if (edog->hungrytime < monstermoves) edog->hungrytime = monstermoves;
2163 	edog->hungrytime += nutrit;
2164 	mon->mconf = 0;
2165     }
2166     mon->mlstmv = monstermoves; /* it takes a turn */
2167 }
2168 
2169 /*muse.c*/
2170