Fandom

Wikihack

Source:NetHack 3.1.0/muse.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 muse.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/muse.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: @(#)muse.c	3.1	93/01/03	*/
2.    /* Monster item usage routine.  Copyright (C) 1990 by Ken Arromdee */
3.    /* NetHack may be freely redistributed.  See license for details.  */
4.    
5.    #include "hack.h"
6.    
7.    #ifdef MUSE
8.    
9.    extern int monstr[];
10.   
11.   boolean m_using = FALSE;
12.   
13.   /* Let monsters use magic items.  Arbitrary assumptions: Monsters only use
14.    * scrolls when they can see, monsters know when wands have 0 charges, monsters
15.    * cannot recognize if items are cursed are not, monsters which are confused
16.    * don't know not to read scrolls, etc....
17.    */
18.   
19.   static int FDECL(precheck, (struct monst *,struct obj *));
20.   static void FDECL(mzapmsg, (struct monst *,struct obj *,BOOLEAN_P));
21.   static void FDECL(mreadmsg, (struct monst *,struct obj *));
22.   static void FDECL(mquaffmsg, (struct monst *,struct obj *));
23.   static int FDECL(mbhitm, (struct monst *,struct obj *));
24.   static void FDECL(mbhit,
25.   	(struct monst *,int,int FDECL((*),(MONST_P,OBJ_P)),
26.   	int FDECL((*),(OBJ_P,OBJ_P)),struct obj *));
27.   static void FDECL(you_aggravate, (struct monst *));
28.   
29.   static struct musable {
30.   	struct obj *offensive;
31.   	struct obj *defensive;
32.   	struct obj *misc;
33.   	int has_offense, has_defense, has_misc;
34.   	/* =0, no capability; otherwise, different numbers.
35.   	 * If it's an object, the object is also set (it's 0 otherwise).
36.   	 */
37.   } m;
38.   static int trapx, trapy;
39.   static boolean zap_oseen;
40.   	/* for wands which use mbhitm and are zapped at players.  We usually
41.   	 * want an oseen local to the function, but this is impossible since the
42.   	 * function mbhitm has to be compatible with the normal zap routines,
43.   	 * and those routines don't remember who zapped the wand.
44.   	 */
45.   
46.   /* Any preliminary checks which may result in the monster being unable to use
47.    * the item.  Returns 0 if nothing happened, 2 if the monster can't do anything
48.    * (i.e. it teleported) and 1 if it's dead.
49.    */
50.   static int
51.   precheck(mon, obj)
52.   struct monst *mon;
53.   struct obj *obj;
54.   {
55.   	boolean vis = cansee(mon->mx, mon->my);
56.   
57.   	if (!obj) return 0;
58.   	if (obj->oclass == POTION_CLASS) {
59.   	    coord cc;
60.   	    static const char *empty = "The potion turns out to be empty.";
61.   	    const char * potion_descr ;
62.   	    struct monst *mtmp;
63.   
64.   	    potion_descr = OBJ_DESCR(objects[obj->otyp]);
65.   	    if (!strcmp(potion_descr, "milky") && !rn2(13)) {
66.   		if (!enexto(&cc, mon->mx, mon->my, &mons[PM_GHOST])) return 0;
67.   		mquaffmsg(mon, obj);
68.   		m_useup(mon, obj);
69.   		mtmp = makemon(&mons[PM_GHOST], cc.x, cc.y);
70.   		if (!mtmp) {
71.   		    if (vis) pline(empty);
72.   		} else {
73.   		    if (vis) {
74.   			pline("As %s opens the bottle, an enormous %s emerges!",
75.   			   mon_nam(mon),
76.   			   Hallucination ? rndmonnam() : (const char *)"ghost");
77.   			pline("%s is frightened to death, and unable to move.",
78.   				Monnam(mon));
79.   		    }
80.   		    mon->mcanmove = 0;
81.   		    mon->mfrozen = 3;
82.   		}
83.   		return 2;
84.   	    }
85.   	    if (!strcmp(potion_descr, "smoky") && !rn2(13)) {
86.   		if (!enexto(&cc, mon->mx, mon->my, &mons[PM_DJINNI])) return 0;
87.   		mquaffmsg(mon, obj);
88.   		m_useup(mon, obj);
89.   		mtmp = makemon(&mons[PM_DJINNI], cc.x, cc.y);
90.   		if (!mtmp) {
91.   		    if (vis) pline(empty);
92.   		} else {
93.   		    if (vis)
94.   			pline("In a cloud of smoke, %s emerges!",
95.   							a_monnam(mtmp));
96.   		    pline("%s speaks.", vis ? Monnam(mtmp) : "Something");
97.   		/* I suspect few players will be upset that monsters */
98.   		/* can't wish for wands of death here.... */
99.   		    if (rn2(2)) {
100.  			verbalize("You freed me!");
101.  			mtmp->mpeaceful = 1;
102.  			set_malign(mtmp);
103.  		    } else {
104.  			verbalize("It is about time.");
105.  			if (vis) pline("%s vanishes.", Monnam(mtmp));
106.  			mongone(mtmp);
107.  		    }
108.  		}
109.  		return 2;
110.  	    }
111.  	}
112.  	if (obj->oclass == WAND_CLASS && obj->cursed && !rn2(100)) {
113.  	    int dam = d(obj->spe+2, 6);
114.  
115.  #ifdef SOUNDS
116.  	    if (flags.soundok)
117.  #endif
118.  				{
119.  		if (vis) pline("%s zaps %s, which suddenly explodes!",
120.  			Monnam(mon), an(xname(obj)));
121.  		else You("hear a zap and an explosion in the distance.");
122.  	    }
123.  	    m_useup(mon, obj);
124.  	    if (mon->mhp <= dam) {
125.  		monkilled(mon, "", AD_RBRE);
126.  		return 1;
127.  	    }
128.  	    else mon->mhp -= dam;
129.  	    m.has_defense = m.has_offense = m.has_misc = 0;
130.  	    /* Only one needed to be set to 0 but the others are harmless */
131.  	}
132.  	return 0;
133.  }
134.  
135.  static void
136.  mzapmsg(mtmp, otmp, self)
137.  struct monst *mtmp;
138.  struct obj *otmp;
139.  boolean self;
140.  {
141.  	if (!cansee(mtmp->mx, mtmp->my)) {
142.  #ifdef SOUNDS
143.  		if (flags.soundok)
144.  #endif
145.  			You("hear a distant zap.");
146.  	} else if (self)
147.  		pline("%s zaps %sself with %s!",
148.  			Monnam(mtmp),
149.  			gender(mtmp)==2 ? "it" : gender(mtmp) ? "her" : "him",
150.  			doname(otmp));
151.  	else {
152.  		pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp)));
153.  		stop_occupation();
154.  	}
155.  }
156.  
157.  static void
158.  mreadmsg(mtmp, otmp)
159.  struct monst *mtmp;
160.  struct obj *otmp;
161.  {
162.  	boolean vis = (cansee(mtmp->mx, mtmp->my));
163.  #ifdef SOUNDS
164.  	if (flags.soundok)
165.  #endif
166.  		otmp->dknown = 1;
167.  	if (!vis) {
168.  #ifdef SOUNDS
169.  		if (flags.soundok)
170.  #endif
171.  		    You("hear %s reading %s.",
172.  			an(Hallucination ? rndmonnam() : mtmp->data->mname),
173.  			singular(otmp, doname));
174.  	} else pline("%s reads %s!", Monnam(mtmp), singular(otmp,doname));
175.  	if (mtmp->mconf
176.  #ifdef SOUNDS
177.  		&& (vis || flags.soundok)
178.  #endif
179.  					)
180.  		pline("Being confused, %s mispronounces the magic words...",
181.  			vis ? mon_nam(mtmp) : gender(mtmp)==2 ? "it" :
182.  			gender(mtmp) ? "he" : "she");
183.  }
184.  
185.  static void
186.  mquaffmsg(mtmp, otmp)
187.  struct monst *mtmp;
188.  struct obj *otmp;
189.  {
190.  	if (cansee(mtmp->mx, mtmp->my)) {
191.  		otmp->dknown = 1;
192.  		pline("%s drinks %s!", Monnam(mtmp), singular(otmp, doname));
193.  	} else
194.  #ifdef SOUNDS
195.  		if (flags.soundok)
196.  #endif
197.  			You("hear a chugging sound.");
198.  }
199.  
200.  /* Defines for various types of stuff.  The order in which monsters prefer
201.   * to use them is determined by the order of the code logic, not the
202.   * numerical order in which they are defined.
203.   */
204.  #define MUSE_SCR_TELEPORTATION 1
205.  #define MUSE_WAN_TELEPORTATION_SELF 2
206.  #define MUSE_POT_HEALING 3
207.  #define MUSE_POT_EXTRA_HEALING 4
208.  #define MUSE_WAN_DIGGING 5
209.  #define MUSE_TRAPDOOR 6
210.  #define MUSE_TELEPORT_TRAP 7
211.  #define MUSE_UPSTAIRS 8
212.  #define MUSE_DOWNSTAIRS 9
213.  #define MUSE_WAN_CREATE_MONSTER 10
214.  #define MUSE_SCR_CREATE_MONSTER 11
215.  #define MUSE_UP_LADDER 12
216.  #define MUSE_DN_LADDER 13
217.  #define MUSE_SSTAIRS 14
218.  #define MUSE_WAN_TELEPORTATION 15
219.  #ifdef ARMY
220.  # define MUSE_BUGLE 16
221.  #endif
222.  /*
223.  #define MUSE_INNATE_TPT 9999
224.   * We cannot use this.  Since monsters get unlimited teleportation, if they
225.   * were allowed to teleport at will you could never catch them.  Instead,
226.   * assume they only teleport at random times, despite the inconsistency that if
227.   * you polymorph into one you teleport at will.
228.   */
229.  
230.  /* Select a defensive item/action for a monster.  Returns TRUE iff one is
231.   * found.
232.   */
233.  boolean
234.  find_defensive(mtmp)
235.  struct monst *mtmp;
236.  {
237.  	register struct obj *obj;
238.  	struct trap *t;
239.  	int x=mtmp->mx, y=mtmp->my;
240.  	boolean stuck = (mtmp == u.ustuck);
241.  	boolean immobile = (mtmp->data->mmove == 0);
242.  
243.  	if (mtmp->mpeaceful || is_animal(mtmp->data) || mindless(mtmp->data))
244.  		return 0;
245.  	if (u.uswallow && stuck) return 0;
246.  	if(dist2(x, y, mtmp->mux, mtmp->muy) > 25)
247.  		return 0;
248.  	if(mtmp->mhp >= mtmp->mhpmax ||
249.  			(mtmp->mhp >= 10 && mtmp->mhp*5 >= mtmp->mhpmax))
250.  		return 0;
251.  
252.  	m.defensive = (struct obj *)0;
253.  	m.has_defense = 0;
254.  
255.  	if (levl[x][y].typ == STAIRS && !stuck && !immobile) {
256.  		if (x == xdnstair && y == ydnstair)
257.  			m.has_defense = MUSE_DOWNSTAIRS;
258.  		if (x == xupstair && y == yupstair && ledger_no(&u.uz) != 1)
259.  	/* Unfair to let the monsters leave the dungeon with the Amulet */
260.  	/* (or go to the endlevel since you also need it, to get there) */
261.  			m.has_defense = MUSE_UPSTAIRS;
262.  	} else if (levl[x][y].typ == LADDER && !stuck && !immobile) {
263.  		if (x == xupladder && y == yupladder)
264.  			m.has_defense = MUSE_UP_LADDER;
265.  		if (x == xdnladder && y == ydnladder)
266.  			m.has_defense = MUSE_DN_LADDER;
267.  	} else if (sstairs.sx &&
268.  		   sstairs.sx == mtmp->mx && sstairs.sy == mtmp->my) {
269.  		m.has_defense = MUSE_SSTAIRS;
270.  	} else if (!stuck && !immobile) {
271.  	/* Note: trapdoors take precedence over teleport traps. */
272.  		int xx, yy;
273.  
274.  		for(xx = x-1; xx <= x+1; xx++) for(yy = y-1; yy <= y+1; yy++)
275.  		if (isok(xx,yy))
276.  		if (xx != u.ux && yy != u.uy)
277.  		if (mtmp->data != &mons[PM_GRID_BUG] || xx == x || yy == y)
278.  		if ((xx==x && yy==y) || !level.monsters[xx][yy])
279.  		if ((t = t_at(xx,yy)) != 0) {
280.  			if (t->ttyp == TRAPDOOR
281.  				&& !is_floater(mtmp->data)
282.  				&& !mtmp->isshk && !mtmp->isgd
283.  				&& !mtmp->ispriest
284.  				&& Can_fall_thru(&u.uz)
285.  						) {
286.  				trapx = xx;
287.  				trapy = yy;
288.  				m.has_defense = MUSE_TRAPDOOR;
289.  			} else if (t->ttyp == TELEP_TRAP && m.has_defense != MUSE_TRAPDOOR) {
290.  				trapx = xx;
291.  				trapy = yy;
292.  				m.has_defense = MUSE_TELEPORT_TRAP;
293.  			}
294.  		}
295.  	}
296.  
297.  	if (nohands(mtmp->data))	/* can't use objects */
298.  		goto botm;
299.  
300.  #ifdef ARMY
301.  	if (is_mercenary(mtmp->data) && (obj = m_carrying(mtmp, BUGLE))) {
302.  		int xx, yy;
303.  		struct monst *mon;
304.  
305.  		/* Distance is arbitrary.  What we really want to do is
306.  		 * have the soldier play the bugle when it sees or
307.  		 * remembers soldiers nearby...
308.  		 */
309.  		for(xx = x-3; xx <= x+3; xx++) for(yy = y-3; yy <= y+3; yy++)
310.  		if (isok(xx,yy))
311.  		if ((mon = m_at(xx,yy)) && is_mercenary(mon->data) &&
312.  				mon->data != &mons[PM_GUARD] &&
313.  				(mon->msleep || (!mon->mcanmove))) {
314.  			m.defensive = obj;
315.  			m.has_defense = MUSE_BUGLE;
316.  		}
317.  	}
318.  #endif
319.  	if (m.has_defense == MUSE_UPSTAIRS ||
320.  			m.has_defense == MUSE_DOWNSTAIRS ||
321.  			m.has_defense == MUSE_UP_LADDER ||
322.  			m.has_defense == MUSE_DN_LADDER ||
323.  			m.has_defense == MUSE_SSTAIRS ||
324.  #ifdef ARMY
325.  			m.has_defense == MUSE_BUGLE ||
326.  #endif
327.  			m.has_defense == MUSE_TRAPDOOR)
328.  		goto botm;
329.  #define nomore(x) if(m.has_defense==x) continue;
330.  	for (obj = mtmp->minvent; obj; obj = obj->nobj) {
331.  		/* nomore(MUSE_WAN_DIGGING); */
332.  		if (m.has_defense == MUSE_WAN_DIGGING) break;
333.  		if (obj->otyp == WAN_DIGGING && obj->spe > 0 && !stuck
334.  		    && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest
335.  		    && !is_floater(mtmp->data)
336.  #ifdef MULDGN
337.  		    && !Is_knox(&u.uz)
338.  #endif
339.  		    && !In_endgame(&u.uz)) {
340.  			m.defensive = obj;
341.  			m.has_defense = MUSE_WAN_DIGGING;
342.  		}
343.  		nomore(MUSE_TELEPORT_TRAP);
344.  		nomore(MUSE_WAN_TELEPORTATION_SELF);
345.  		nomore(MUSE_WAN_TELEPORTATION);
346.  		if(obj->otyp == WAN_TELEPORTATION && obj->spe > 0) {
347.  			m.defensive = obj;
348.  			m.has_defense = (mon_has_amulet(mtmp))
349.  				? MUSE_WAN_TELEPORTATION
350.  				: MUSE_WAN_TELEPORTATION_SELF;
351.  		}
352.  		nomore(MUSE_SCR_TELEPORTATION);
353.  		if(obj->otyp == SCR_TELEPORTATION && mtmp->mcansee
354.  		   && haseyes(mtmp->data)
355.  		   && (!obj->cursed ||
356.  		       (!mtmp->isshk && !mtmp->isgd && !mtmp->ispriest))) {
357.  			m.defensive = obj;
358.  			m.has_defense = MUSE_SCR_TELEPORTATION;
359.  		}
360.  		nomore(MUSE_POT_EXTRA_HEALING);
361.  		if(obj->otyp == POT_EXTRA_HEALING) {
362.  			m.defensive = obj;
363.  			m.has_defense = MUSE_POT_EXTRA_HEALING;
364.  		}
365.  		nomore(MUSE_WAN_CREATE_MONSTER);
366.  		if(obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
367.  			m.defensive = obj;
368.  			m.has_defense = MUSE_WAN_CREATE_MONSTER;
369.  		}
370.  		nomore(MUSE_POT_HEALING);
371.  		if(obj->otyp == POT_HEALING) {
372.  			m.defensive = obj;
373.  			m.has_defense = MUSE_POT_HEALING;
374.  		}
375.  		nomore(MUSE_SCR_CREATE_MONSTER);
376.  		if(obj->otyp == SCR_CREATE_MONSTER) {
377.  			m.defensive = obj;
378.  			m.has_defense = MUSE_SCR_CREATE_MONSTER;
379.  		}
380.  	}
381.  botm:	return !!m.has_defense;
382.  #undef nomore
383.  }
384.  
385.  /* Perform a defensive action for a monster.  Must be called immediately
386.   * after find_defensive().  Return values are 0: did something, 1: died,
387.   * 2: did something and can't attack again (i.e. teleported).
388.   */
389.  int
390.  use_defensive(mtmp)
391.  struct monst *mtmp;
392.  {
393.  	int i;
394.  	struct obj *otmp = m.defensive;
395.  	boolean vis = cansee(mtmp->mx, mtmp->my);
396.  	boolean vismon = canseemon(mtmp);
397.  	boolean oseen = otmp && (otmp->oclass == SCROLL_CLASS || vis);
398.  
399.  	if ((i = precheck(mtmp, otmp)) != 0) return i;
400.  	switch(m.has_defense) {
401.  #ifdef ARMY
402.  	case MUSE_BUGLE:
403.  		if (canseemon(mtmp))
404.  			pline("%s plays %s!", Monnam(mtmp), doname(otmp));
405.  		else if (flags.soundok)
406.  			You("hear the sound of a bugle!");
407.  		awaken_soldiers();
408.  		return 2;
409.  #endif
410.  	case MUSE_WAN_TELEPORTATION_SELF:
411.  		mzapmsg(mtmp, otmp, TRUE);
412.  		otmp->spe--;
413.  		if (oseen) makeknown(WAN_TELEPORTATION);
414.  mon_tele:
415.  		if(level.flags.noteleport) {
416.  		    if (vismon)
417.  		      pline("A mysterious force prevents %s from teleporting!",
418.  			mon_nam(mtmp));
419.  		    return 2;
420.  		}
421.  		if((/*mon_has_amulet(mtmp)||*/ Is_wiz1_level(&u.uz) ||
422.  		      Is_wiz2_level(&u.uz) || Is_wiz3_level(&u.uz))
423.  								&& !rn2(3)) {
424.  		    if (vismon)
425.  			pline("%s seems disoriented for a moment.",
426.  				Monnam(mtmp));
427.  		    return 2;
428.  		}
429.  		rloc(mtmp);
430.  		return 2;
431.  	case MUSE_WAN_TELEPORTATION:
432.  		zap_oseen = oseen;
433.  		mzapmsg(mtmp, otmp, FALSE);
434.  		otmp->spe--;
435.  		m_using = TRUE;
436.  		mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp);
437.  		m_using = FALSE;
438.  		return 2;
439.  	case MUSE_SCR_TELEPORTATION:
440.  	    {
441.  		int obj_is_cursed = otmp->cursed;
442.  
443.  		mreadmsg(mtmp, otmp);
444.  		m_useup(mtmp, otmp);	/* otmp might be free'ed */
445.  		if (oseen) makeknown(SCR_TELEPORTATION);
446.  		if (obj_is_cursed) {
447.  			if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
448.  			    if (vismon)
449.  				pline("%s seems very disoriented for a moment.",
450.  					Monnam(mtmp));
451.  			    return 2;
452.  			}
453.  			if (Is_botlevel(&u.uz)) goto mon_tele;
454.  			else {
455.  			    int nlev;
456.  			    d_level flev;
457.  
458.  			    if (rn2(5)) nlev = rnd((int)depth(&u.uz) + 3);
459.  			    else {
460.  				pline("%s shudders for a moment.",
461.  							Monnam(mtmp));
462.  				return 2; 
463.  			    }
464.  			    if (nlev == depth(&u.uz)) {
465.  				if (u.uz.dlevel == 1) nlev++;
466.  				else if (In_hell(&u.uz)) nlev--;
467.  				else nlev++;
468.  			    }
469.  			    get_level(&flev, nlev);
470.  			    migrate_to_level(mtmp, ledger_no(&flev), 0);
471.  			}
472.  		} else goto mon_tele;
473.  		return 2;
474.  	    }
475.  	case MUSE_WAN_DIGGING:
476.  		mzapmsg(mtmp, otmp, FALSE);
477.  		otmp->spe--;
478.  		if (oseen) makeknown(WAN_DIGGING);
479.  		if(IS_FURNITURE(levl[mtmp->mx][mtmp->my].typ)
480.  		   || (sstairs.sx && sstairs.sx == mtmp->mx &&
481.  				sstairs.sy == mtmp->my)) {
482.  			pline("The digging ray is ineffective.");
483.  			return 2;
484.  		}
485.  		if (!Can_dig_down(&u.uz)) {
486.  		    if(canseemon(mtmp))
487.  			pline("The floor here is too hard to dig in.");
488.  		    return 2;
489.  		}
490.  		seetrap(maketrap(mtmp->mx, mtmp->my, TRAPDOOR));
491.  		if (vis) {
492.  			pline("%s's made a hole in the floor.", Monnam(mtmp));
493.  			pline("%s falls through...", Monnam(mtmp));
494.  		} else
495.  # ifdef SOUNDS
496.  			if (flags.soundok)
497.  # endif
498.  			You("hear something crash through the floor.");
499.  		/* we made sure that there is a level for mtmp to go to */
500.  		migrate_to_level(mtmp, ledger_no(&u.uz)+1, 0);
501.  		return 2;
502.  	case MUSE_WAN_CREATE_MONSTER:
503.  	    {	coord cc;
504.  		struct permonst *pm=rndmonst();
505.  
506.  		if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) return 0;
507.  		mzapmsg(mtmp, otmp, FALSE);
508.  		otmp->spe--;
509.  		if (oseen) makeknown(WAN_CREATE_MONSTER);
510.  		(void) makemon(pm, cc.x, cc.y);
511.  		return 2;
512.  	    }
513.  	case MUSE_SCR_CREATE_MONSTER:
514.  	    {	coord cc;
515.  		struct permonst *pm=rndmonst();
516.  		int cnt = 1;
517.  
518.  		if (!rn2(73)) cnt += rnd(4);
519.  		if (mtmp->mconf || otmp->cursed) cnt += 12;
520.  		mreadmsg(mtmp, otmp);
521.  		while(cnt--) {
522.  			struct monst *mon;
523.  
524.  			if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) continue;
525.  			mon = makemon(mtmp->mconf ? &mons[PM_ACID_BLOB]
526.  				: rndmonst(), cc.x, cc.y);
527.  			if (mon) newsym(mon->mx,mon->my);
528.  		}
529.  		if (oseen && !objects[SCR_CREATE_MONSTER].oc_name_known
530.  			  && !objects[SCR_CREATE_MONSTER].oc_uname)
531.  			docall(otmp); /* not makeknown(); be consistent */
532.  		m_useup(mtmp, otmp);
533.  		return 2;
534.  	    }
535.  	case MUSE_TRAPDOOR:
536.  		/* trapdoors on "bottom" levels of dungeons are rock-drop
537.  		 * trapdoors, not holes in the floor.  We check here for
538.  		 * safety.
539.  		 */
540.  		if (Is_botlevel(&u.uz)) return 0;
541.  		if (vis) pline("%s %s into a trapdoor!", Monnam(mtmp),
542.  			makeplural(locomotion(mtmp->data, "jump")));
543.  		seetrap(t_at(trapx,trapy));
544.  
545.  		/*  don't use rloc_to() because worm tails must "move" */
546.  		remove_monster(mtmp->mx, mtmp->my);
547.  		newsym(mtmp->mx, mtmp->my);	/* update old location */
548.  		place_monster(mtmp, trapx, trapy);
549.  		if (mtmp->wormno) worm_move(mtmp);
550.  		newsym(trapx, trapy);
551.  
552.  		migrate_to_level(mtmp, ledger_no(&u.uz)+1, 0);
553.  		return 2;
554.  	case MUSE_UPSTAIRS:
555.  		/* Monsters without amulets escape the dungeon and are
556.  		 * gone for good when they leave up the up stairs.
557.  		 * Monsters with amulets would reach the endlevel,
558.  		 * which we cannot allow since that would leave the
559.  		 * player stranded.
560.  		 */
561.  		if (ledger_no(&u.uz) == 1) {
562.  			if (mon_has_special(mtmp))
563.  				return 0;
564.  			if (vismon) pline("%s escapes the dungeon!",
565.  				Monnam(mtmp));
566.  			mongone(mtmp);
567.  			return 2;
568.  		}
569.  		if (vismon) pline("%s escapes upstairs!", Monnam(mtmp));
570.  		migrate_to_level(mtmp, ledger_no(&u.uz)-1, 2);
571.  		return 2;
572.  	case MUSE_DOWNSTAIRS:
573.  		if (vismon) pline("%s escapes downstairs!", Monnam(mtmp));
574.  		migrate_to_level(mtmp, ledger_no(&u.uz)+1, 1);
575.  		return 2;
576.  	case MUSE_UP_LADDER:
577.  		if (vismon) pline("%s escapes up the ladder!", Monnam(mtmp));
578.  		migrate_to_level(mtmp, ledger_no(&u.uz)-1, 4);
579.  		return 2;
580.  	case MUSE_DN_LADDER:
581.  		if (vismon) pline("%s escapes down the ladder!", Monnam(mtmp));
582.  		migrate_to_level(mtmp, ledger_no(&u.uz)+1, 3);
583.  		return 2;
584.  	case MUSE_SSTAIRS:
585.  		/* the stairs leading up from the 1st level are */
586.  		/* regular stairs, not sstairs.			*/
587.  		if (sstairs.up) {
588.  			if (vismon)
589.  			    pline("%s escapes upstairs!", Monnam(mtmp));
590.  			if(Inhell) {
591.  			    migrate_to_level(mtmp,
592.  					 ledger_no(&sstairs.tolev), 0);
593.  			    return 2;
594.  			}
595.  		} else	if (vismon)
596.  		    pline("%s escapes downstairs!", Monnam(mtmp));
597.  		migrate_to_level(mtmp, ledger_no(&sstairs.tolev), 5);
598.  		return 2;
599.  	case MUSE_TELEPORT_TRAP:
600.  		if (vis) pline("%s %s onto a teleport trap!", Monnam(mtmp),
601.  			makeplural(locomotion(mtmp->data, "jump")));
602.  		seetrap(t_at(trapx,trapy));
603.  
604.  		/*  don't use rloc_to() because worm tails must "move" */
605.  		remove_monster(mtmp->mx, mtmp->my);
606.  		newsym(mtmp->mx, mtmp->my);	/* update old location */
607.  		place_monster(mtmp, trapx, trapy);
608.  		if (mtmp->wormno) worm_move(mtmp);
609.  		newsym(trapx, trapy);
610.  
611.  		goto mon_tele;
612.  	case MUSE_POT_HEALING:
613.  		mquaffmsg(mtmp, otmp);
614.  		i = d(5,2) + 5 * !!bcsign(otmp);
615.  		mtmp->mhp += i;
616.  		if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = ++mtmp->mhpmax;
617.  		if (!otmp->cursed) mtmp->mcansee = 1;
618.  		if (vismon) pline("%s begins to look better.", Monnam(mtmp));
619.  		if (oseen) makeknown(POT_HEALING);
620.  		m_useup(mtmp, otmp);
621.  		return 2;
622.  	case MUSE_POT_EXTRA_HEALING:
623.  		mquaffmsg(mtmp, otmp);
624.  		i = d(5,4) + 5 * !!bcsign(otmp);
625.  		mtmp->mhp += i;
626.  		if (mtmp->mhp > mtmp->mhpmax)
627.  			mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2));
628.  		mtmp->mcansee = 1;
629.  		if (vismon) pline("%s looks much better.", Monnam(mtmp));
630.  		if (oseen) makeknown(POT_EXTRA_HEALING);
631.  		m_useup(mtmp, otmp);
632.  		return 2;
633.  	case 0: return 0; /* i.e. an exploded wand */
634.  	default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
635.  			m.has_defense);
636.  		break;
637.  	}
638.  	return 0;
639.  }
640.  
641.  int
642.  rnd_defensive_item(mtmp)
643.  struct monst *mtmp;
644.  {
645.  	struct permonst *pm = mtmp->data;
646.  	int difficulty = monstr[(monsndx(pm))];
647.  
648.  	if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
649.  			|| pm->mlet == S_GHOST
650.  # ifdef KOPS
651.  			|| pm->mlet == S_KOP
652.  # endif
653.  		) return 0;
654.  	switch (rn2(8 + (difficulty > 3) + (difficulty > 6) +
655.  				(difficulty > 8))) {
656.  		case 0: case 1:
657.  			return SCR_TELEPORTATION;
658.  		case 2: return SCR_CREATE_MONSTER;
659.  		case 3: case 4:
660.  			return POT_HEALING;
661.  		case 5: return POT_EXTRA_HEALING;
662.  		case 6: case 9:
663.  			return WAN_TELEPORTATION;
664.  		case 7: if (is_floater(pm) || mtmp->isshk || mtmp->isgd
665.  						|| mtmp->ispriest
666.  									)
667.  				return 0;
668.  			else
669.  				return WAN_DIGGING;
670.  		case 8: case 10:
671.  			return WAN_CREATE_MONSTER;
672.  	}
673.  	/*NOTREACHED*/
674.  	return 0;
675.  }
676.  
677.  #define MUSE_WAN_DEATH 1
678.  #define MUSE_WAN_SLEEP 2
679.  #define MUSE_WAN_FIRE 3
680.  #define MUSE_WAN_COLD 4
681.  #define MUSE_WAN_LIGHTNING 5
682.  #define MUSE_WAN_MAGIC_MISSILE 6
683.  #define MUSE_WAN_STRIKING 7
684.  #define MUSE_SCR_FIRE 8
685.  #define MUSE_POT_PARALYSIS 9
686.  #define MUSE_POT_BLINDNESS 10
687.  #define MUSE_POT_CONFUSION 11
688.  
689.  /* Select an offensive item/action for a monster.  Returns TRUE iff one is
690.   * found.
691.   */
692.  boolean
693.  find_offensive(mtmp)
694.  struct monst *mtmp;
695.  {
696.  	register struct obj *obj;
697.  	boolean ranged_stuff = lined_up(mtmp);
698.  
699.  	m.offensive = (struct obj *)0;
700.  	m.has_offense = 0;
701.  	if (mtmp->mpeaceful || is_animal(mtmp->data) ||
702.  				mindless(mtmp->data) || nohands(mtmp->data))
703.  		return 0;
704.  	if (u.uswallow) return 0;
705.  	if (in_your_sanctuary(mtmp->mx, mtmp->my)) return 0;
706.  
707.  	if (!ranged_stuff) return 0;
708.  #define nomore(x) if(m.has_offense==x) continue;
709.  	for(obj=mtmp->minvent; obj; obj=obj->nobj) {
710.  		/* nomore(MUSE_WAN_DEATH); */
711.  		if (m.has_defense == WAN_DEATH) break;
712.  		if(obj->otyp == WAN_DEATH && obj->spe > 0) {
713.  			m.offensive = obj;
714.  			m.has_offense = MUSE_WAN_DEATH;
715.  		}
716.  		nomore(MUSE_WAN_SLEEP);
717.  		if(obj->otyp == WAN_SLEEP && obj->spe > 0 && multi >= 0) {
718.  			m.offensive = obj;
719.  			m.has_offense = MUSE_WAN_SLEEP;
720.  		}
721.  		nomore(MUSE_WAN_FIRE);
722.  		if(obj->otyp == WAN_FIRE && obj->spe > 0) {
723.  			m.offensive = obj;
724.  			m.has_offense = MUSE_WAN_FIRE;
725.  		}
726.  		nomore(MUSE_WAN_COLD);
727.  		if(obj->otyp == WAN_COLD && obj->spe > 0) {
728.  			m.offensive = obj;
729.  			m.has_offense = MUSE_WAN_COLD;
730.  		}
731.  		nomore(MUSE_WAN_LIGHTNING);
732.  		if(obj->otyp == WAN_LIGHTNING && obj->spe > 0) {
733.  			m.offensive = obj;
734.  			m.has_offense = MUSE_WAN_LIGHTNING;
735.  		}
736.  		nomore(MUSE_WAN_MAGIC_MISSILE);
737.  		if(obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) {
738.  			m.offensive = obj;
739.  			m.has_offense = MUSE_WAN_MAGIC_MISSILE;
740.  		}
741.  		nomore(MUSE_WAN_STRIKING);
742.  		if(obj->otyp == WAN_STRIKING && obj->spe > 0) {
743.  			m.offensive = obj;
744.  			m.has_offense = MUSE_WAN_STRIKING;
745.  		}
746.  		nomore(MUSE_POT_PARALYSIS);
747.  		if(obj->otyp == POT_PARALYSIS && multi >= 0) {
748.  			m.offensive = obj;
749.  			m.has_offense = MUSE_POT_PARALYSIS;
750.  		}
751.  		nomore(MUSE_POT_BLINDNESS);
752.  		if(obj->otyp == POT_BLINDNESS) {
753.  			m.offensive = obj;
754.  			m.has_offense = MUSE_POT_BLINDNESS;
755.  		}
756.  		nomore(MUSE_POT_CONFUSION);
757.  		if(obj->otyp == POT_CONFUSION) {
758.  			m.offensive = obj;
759.  			m.has_offense = MUSE_POT_CONFUSION;
760.  		}
761.  #if 0
762.  		nomore(MUSE_SCR_FIRE);
763.  		/* even more restrictive than ranged_stuff */
764.  		if(obj->otyp == SCR_FIRE && resists_fire(mtmp->data)
765.  		   && distu(mtmp->mx,mtmp->my)==1
766.  		   && mtmp->mcansee && haseyes(mtmp->data)) {
767.  			m.offensive = obj;
768.  			m.has_offense = MUSE_SCR_FIRE;
769.  		}
770.  #endif
771.  	}
772.  	return !!m.has_offense;
773.  #undef nomore
774.  }
775.  
776.  static int
777.  mbhitm(mtmp, otmp)
778.  register struct monst *mtmp;
779.  register struct obj *otmp;
780.  {
781.  	int tmp;
782.  
783.  	if (mtmp != &youmonst) {
784.  		mtmp->msleep = 0;
785.  		if (mtmp->m_ap_type) seemimic(mtmp);
786.  	}
787.  	switch(otmp->otyp) {
788.  	case WAN_STRIKING:
789.  		if (mtmp == &youmonst) {
790.  			if (zap_oseen) makeknown(WAN_STRIKING);
791.  			if (rnd(20) < 10 + u.uac) {
792.  				pline("The wand hits you!");
793.  				tmp = d(2,12);
794.  				if(Half_spell_damage) tmp = (tmp+1) / 2;
795.  				losehp(tmp, "wand", KILLED_BY_AN);
796.  			} else pline("The wand misses you.");
797.  			stop_occupation();
798.  			nomul(0);
799.  		} else if (rnd(20) < 10+find_mac(mtmp)) {
800.  			tmp = d(2,12);
801.  			if(Half_spell_damage) tmp = (tmp+1) / 2;
802.  			hit("wand", mtmp, exclam(tmp));
803.  			(void) resist(mtmp, otmp->oclass, tmp, TELL);
804.  			if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
805.  				makeknown(WAN_STRIKING);
806.  		} else {
807.  			miss("wand", mtmp);
808.  			if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
809.  				makeknown(WAN_STRIKING);
810.  		}
811.  		break;
812.  	case WAN_TELEPORTATION:
813.  		if (mtmp == &youmonst) {
814.  			if (zap_oseen) makeknown(WAN_TELEPORTATION);
815.  			tele();
816.  		} else {
817.  			/* for consistency with zap.c, don't identify */
818.  			if (mtmp->ispriest &&
819.  				*in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
820.  			    if (cansee(mtmp->mx, mtmp->my))
821.  				pline("%s resists the magic!", Monnam(mtmp));
822.  			    mtmp->msleep = 0;
823.  			    if(mtmp->m_ap_type) seemimic(mtmp);
824.  			} else
825.  			    rloc(mtmp);
826.  		}
827.  		break;
828.  	case WAN_CANCELLATION:
829.  	case SPE_CANCELLATION:
830.  		cancel_monst(mtmp, otmp, FALSE, TRUE, FALSE);
831.  		break;
832.  	}
833.  	return 0;
834.  }
835.  
836.  /* A modified bhit() for monsters.  Based on bhit() in zap.c.  Unlike
837.   * buzz(), bhit() doesn't take into account the possibility of a monster
838.   * zapping you, so we need a special function for it.  (Unless someone wants
839.   * to merge the two functions...)
840.   */
841.  static void
842.  mbhit(mon,range,fhitm,fhito,obj)
843.  struct monst *mon;			/* monster shooting the wand */
844.  register int range;			/* direction and range */
845.  int FDECL((*fhitm),(MONST_P,OBJ_P));
846.  int FDECL((*fhito),(OBJ_P,OBJ_P));	/* fns called when mon/obj hit */
847.  struct obj *obj;			/* 2nd arg to fhitm/fhito */
848.  {
849.  	register struct monst *mtmp;
850.  	register struct obj *otmp;
851.  	register uchar typ;
852.  	int ddx, ddy;
853.  
854.  	bhitpos.x = mon->mx;
855.  	bhitpos.y = mon->my;
856.  	ddx = sgn(mon->mux - mon->mx);
857.  	ddy = sgn(mon->muy - mon->my);
858.  
859.  	while(range-- > 0) {
860.  		int x,y;
861.  
862.  		bhitpos.x += ddx;
863.  		bhitpos.y += ddy;
864.  		x = bhitpos.x; y = bhitpos.y;
865.  		if (find_drawbridge(&x,&y))
866.  		    switch (obj->otyp) {
867.  			case WAN_STRIKING:
868.  			    destroy_drawbridge(x,y);
869.  		    }
870.  		if(bhitpos.x==u.ux && bhitpos.y==u.uy) {
871.  			(*fhitm)(&youmonst, obj);
872.  			range -= 3;
873.  		} else if(MON_AT(bhitpos.x, bhitpos.y)){
874.  			mtmp = m_at(bhitpos.x,bhitpos.y);
875.  			(*fhitm)(mtmp, obj);
876.  			range -= 3;
877.  		}
878.  		/* modified by GAN to hit all objects */
879.  		if(fhito){
880.  		    int hitanything = 0;
881.  		    register struct obj *next_obj;
882.  
883.  		    for(otmp = level.objects[bhitpos.x][bhitpos.y];
884.  							otmp; otmp = next_obj) {
885.  			/* Fix for polymorph bug, Tim Wright */
886.  			next_obj = otmp->nexthere;
887.  			hitanything += (*fhito)(otmp, obj);
888.  		    }
889.  		    if(hitanything)	range--;
890.  		}
891.  		typ = levl[bhitpos.x][bhitpos.y].typ;
892.  		if(IS_DOOR(typ) || typ == SDOOR) {
893.  		    switch (obj->otyp) {
894.  			case WAN_STRIKING:
895.  			    if (doorlock(obj, bhitpos.x, bhitpos.y))
896.  				makeknown(obj->otyp);
897.  			    break;
898.  		    }
899.  		}
900.  		if(!ZAP_POS(typ) || (IS_DOOR(typ) &&
901.  		   (levl[bhitpos.x][bhitpos.y].doormask & (D_LOCKED | D_CLOSED)))
902.  		  ) {
903.  			bhitpos.x -= ddx;
904.  			bhitpos.y -= ddy;
905.  			break;
906.  		}
907.  	}
908.  }
909.  
910.  /* Perform an offensive action for a monster.  Must be called immediately
911.   * after find_offensive().  Return values are same as use_defensive().
912.   */
913.  int
914.  use_offensive(mtmp)
915.  struct monst *mtmp;
916.  {
917.  	int i;
918.  	struct obj *otmp = m.offensive;
919.  	boolean vis = cansee(mtmp->mx, mtmp->my);
920.  	boolean oseen = otmp && (otmp->oclass == SCROLL_CLASS || vis);
921.  
922.  	if ((i = precheck(mtmp, otmp)) != 0) return i;
923.  	switch(m.has_offense) {
924.  	case MUSE_WAN_DEATH:
925.  	case MUSE_WAN_SLEEP:
926.  	case MUSE_WAN_FIRE:
927.  	case MUSE_WAN_COLD:
928.  	case MUSE_WAN_LIGHTNING:
929.  	case MUSE_WAN_MAGIC_MISSILE:
930.  		mzapmsg(mtmp, otmp, FALSE);
931.  		otmp->spe--;
932.  		if (oseen) makeknown(otmp->otyp);
933.  		m_using = TRUE;
934.  		buzz((int)(-30 - (otmp->otyp - WAN_MAGIC_MISSILE)),
935.  			(otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6,
936.  			mtmp->mx, mtmp->my,
937.  			sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my));
938.  		m_using = FALSE;
939.  		return (mtmp->mhp <= 0) ? 1 : 2;
940.  	case MUSE_WAN_TELEPORTATION:
941.  	case MUSE_WAN_STRIKING:
942.  		zap_oseen = oseen;
943.  		mzapmsg(mtmp, otmp, FALSE);
944.  		otmp->spe--;
945.  		m_using = TRUE;
946.  		mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp);
947.  		m_using = FALSE;
948.  		return 2;
949.  #if 0
950.  	case MUSE_SCR_FIRE:
951.  		mreadmsg(mtmp, otmp);
952.  		if (mtmp->mconf) {
953.  			if (vis)
954.  			    pline("Oh, what a pretty fire!");
955.  		} else {
956.  			struct monst *mtmp2;
957.  			int num;
958.  
959.  			if (vis)
960.  			    pline("The scroll erupts in a tower of flame!");
961.  			shieldeff(mtmp->mx, mtmp->my);
962.  			pline("%s is uninjured.", Monnam(mtmp));
963.  			(void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
964.  			(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
965.  			(void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
966.  			num = (2*(rn1(3, 3) + 2 * bcsign(otmp)) + 1)/3;
967.  			if (Fire_resistance)
968.  			    You("are not affected.");
969.  			if (Half_spell_damage) num = (num+1) / 2;
970.  			else losehp(num, "scroll of fire", KILLED_BY_AN);
971.  			for(mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) {
972.  			   if(mtmp == mtmp2) continue;
973.  			   if(dist2(mtmp2->mx,mtmp2->my,mtmp->mx,mtmp->my) < 3){
974.  				if (resists_fire(mtmp2->data)) continue;
975.  				mtmp2->mhp -= num;
976.  				if(resists_cold(mtmp2->data))
977.  				    mtmp2->mhp -= 3*num;
978.  				if(mtmp2->mhp < 1) {
979.  				    mondied(mtmp2);
980.  				    break;
981.  				}
982.  			    }
983.  			}
984.  		}
985.  		return 2;
986.  #endif
987.  	case MUSE_POT_PARALYSIS:
988.  	case MUSE_POT_BLINDNESS:
989.  	case MUSE_POT_CONFUSION:
990.  		/* Note: this setting of dknown doesn't suffice.  A monster
991.  		 * which is out of sight might throw and it hits something _in_
992.  		 * sight, a problem not existing with wands because wand rays
993.  		 * are not objects.  Also set dknown in mthrowu.c.
994.  		 */
995.  		if (cansee(mtmp->mx, mtmp->my)) {
996.  			otmp->dknown = 1;
997.  			pline("%s hurls %s!", Monnam(mtmp),
998.  						singular(otmp, doname));
999.  		}
1000. 		m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux-mtmp->mx),
1001. 			sgn(mtmp->muy-mtmp->my),
1002. 			distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy), otmp);
1003. 		return 2;
1004. 	case 0: return 0; /* i.e. an exploded wand */
1005. 	default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
1006. 			m.has_offense);
1007. 		break;
1008. 	}
1009. 	return 0;
1010. }
1011. 
1012. int
1013. rnd_offensive_item(mtmp)
1014. struct monst *mtmp;
1015. {
1016. 	struct permonst *pm = mtmp->data;
1017. 	int difficulty = monstr[(monsndx(pm))];
1018. 
1019. 	if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1020. 			|| pm->mlet == S_GHOST
1021. # ifdef KOPS
1022. 			|| pm->mlet == S_KOP
1023. # endif
1024. 		) return 0;
1025. 	if (difficulty > 7 && !rn2(35)) return WAN_DEATH;
1026. 	switch (rn2(7 - (difficulty < 4) + 4 * (difficulty > 6))) {
1027. 		case 0: case 1:
1028. 			return WAN_STRIKING;
1029. 		case 2: return POT_CONFUSION;
1030. 		case 3: return POT_BLINDNESS;
1031. 		case 4: return POT_PARALYSIS;
1032. 		case 5: case 6:
1033. 			return WAN_MAGIC_MISSILE;
1034. 		case 7: return WAN_SLEEP;
1035. 		case 8: return WAN_FIRE;
1036. 		case 9: return WAN_COLD;
1037. 		case 10: return WAN_LIGHTNING;
1038. 	}
1039. 	/*NOTREACHED*/
1040. 	return 0;
1041. }
1042. 
1043. #define MUSE_POT_GAIN_LEVEL 1
1044. #define MUSE_WAN_MAKE_INVISIBLE 2
1045. #define MUSE_POT_INVISIBILITY 3
1046. #define MUSE_POLY_TRAP 4
1047. #define MUSE_WAN_POLYMORPH 5
1048. #define MUSE_POT_SPEED 6
1049. #define MUSE_WAN_SPEED_MONSTER 7
1050. boolean
1051. find_misc(mtmp)
1052. struct monst *mtmp;
1053. {
1054. 	register struct obj *obj;
1055. 	int x=mtmp->mx, y=mtmp->my;
1056. #ifdef POLYSELF
1057. 	struct trap *t;
1058. 	int xx, yy;
1059. 	boolean immobile = (mtmp->data->mmove == 0);
1060. #endif
1061. 	boolean stuck = (mtmp == u.ustuck);
1062. 
1063. 	m.misc = (struct obj *)0;
1064. 	m.has_misc = 0;
1065. 	if (is_animal(mtmp->data) || mindless(mtmp->data))
1066. 		return 0;
1067. 	if (u.uswallow && stuck) return 0;
1068. 
1069. 	/* We arbitrarily limit to times when a player is nearby for the
1070. 	 * same reason as Junior Pac-Man doesn't have energizers eaten until
1071. 	 * you can see them...
1072. 	 */
1073. 	if(dist2(x, y, mtmp->mux, mtmp->muy) > 36)
1074. 		return 0;
1075. 
1076. #ifdef POLYSELF
1077. 	if (!stuck && !immobile &&
1078. 			!mtmp->cham && monstr[(monsndx(mtmp->data))] < 6)
1079. 	  for(xx = x-1; xx <= x+1; xx++)
1080. 	    for(yy = y-1; yy <= y+1; yy++)
1081. 		if (isok(xx,yy) && (xx != u.ux || yy != u.uy))
1082. 		    if (mtmp->data != &mons[PM_GRID_BUG] || xx == x || yy == y)
1083. 			if (/* (xx==x && yy==y) || */ !level.monsters[xx][yy])
1084. 			    if ((t = t_at(xx,yy)) != 0) {
1085. 				if (t->ttyp == POLY_TRAP) {
1086. 				    trapx = xx;
1087. 				    trapy = yy;
1088. 				    m.has_misc = MUSE_POLY_TRAP;
1089. 				    return TRUE;
1090. 				}
1091. 			    }
1092. #endif
1093. 	if (nohands(mtmp->data))
1094. 		return 0;
1095. 
1096. #define nomore(x) if(m.has_misc==x) continue;
1097. 	for(obj=mtmp->minvent; obj; obj=obj->nobj) {
1098. 		/* Monsters shouldn't recognize cursed items; this kludge is */
1099. 		/* necessary to prevent serious problems though... */
1100. 		if(obj->otyp == POT_GAIN_LEVEL && (!obj->cursed ||
1101. 			    (!mtmp->isgd && !mtmp->isshk && !mtmp->ispriest))) {
1102. 			m.misc = obj;
1103. 			m.has_misc = MUSE_POT_GAIN_LEVEL;
1104. 		}
1105. 		/* Note: peaceful/tame monsters won't make themselves
1106. 		 * invisible unless you can see them.  Not really right, but...
1107. 		 */
1108. 		nomore(MUSE_WAN_MAKE_INVISIBLE);
1109. 		if(obj->otyp == WAN_MAKE_INVISIBLE && obj->spe > 0 &&
1110. 		     !mtmp->minvis && (!mtmp->mpeaceful || See_invisible)
1111. 			&& (mtmp->data != &mons[PM_MEDUSA] || mtmp->mcan)) {
1112. 			m.misc = obj;
1113. 			m.has_misc = MUSE_WAN_MAKE_INVISIBLE;
1114. 		}
1115. 		nomore(MUSE_POT_INVISIBILITY);
1116. 		if(obj->otyp == POT_INVISIBILITY &&
1117. 		     !mtmp->minvis && (!mtmp->mpeaceful || See_invisible)) {
1118. 			m.misc = obj;
1119. 			m.has_misc = MUSE_POT_INVISIBILITY;
1120. 		}
1121. 		nomore(MUSE_WAN_SPEED_MONSTER);
1122. 		if(obj->otyp == WAN_SPEED_MONSTER && obj->spe > 0
1123. 				&& mtmp->mspeed != MFAST && !mtmp->isgd) {
1124. 			m.misc = obj;
1125. 			m.has_misc = MUSE_WAN_SPEED_MONSTER;
1126. 		}
1127. 		nomore(MUSE_POT_SPEED);
1128. 		if(obj->otyp == POT_SPEED && mtmp->mspeed != MFAST
1129. 							&& !mtmp->isgd) {
1130. 			m.misc = obj;
1131. 			m.has_misc = MUSE_POT_SPEED;
1132. 		}
1133. 		nomore(MUSE_WAN_POLYMORPH);
1134. 		if(obj->otyp == WAN_POLYMORPH && !mtmp->cham
1135. 				&& monstr[(monsndx(mtmp->data))] < 6) {
1136. 			m.misc = obj;
1137. 			m.has_misc = MUSE_WAN_POLYMORPH;
1138. 		}
1139. 	}
1140. 	return !!m.has_misc;
1141. #undef nomore
1142. }
1143. 
1144. int
1145. use_misc(mtmp)
1146. struct monst *mtmp;
1147. {
1148. 	int i;
1149. 	struct obj *otmp = m.misc;
1150. 	boolean vis = cansee(mtmp->mx, mtmp->my);
1151. 	boolean vismon = canseemon(mtmp);
1152. 	boolean oseen = otmp && (otmp->oclass == SCROLL_CLASS || vis);
1153. 
1154. 	if ((i = precheck(mtmp, otmp)) != 0) return i;
1155. 	switch(m.has_misc) {
1156. 	case MUSE_POT_GAIN_LEVEL:
1157. 		mquaffmsg(mtmp, otmp);
1158. 		if (otmp->cursed) {
1159. 		    if (Can_rise_up(&u.uz)) {
1160. 			register int tolev = depth(&u.uz)-1;
1161. 			d_level tolevel;
1162. 
1163. 			get_level(&tolevel, tolev);
1164. 			/* insurance against future changes... */
1165. 			if(on_level(&tolevel, &u.uz)) goto skipmsg;
1166. 			if (vismon) {
1167. 			    pline("%s rises up, through the ceiling!",
1168. 				Monnam(mtmp));
1169. 			    if(!objects[POT_GAIN_LEVEL].oc_name_known
1170. 			      && !objects[POT_GAIN_LEVEL].oc_uname)
1171. 				docall(otmp);
1172. 			}
1173. 			m_useup(mtmp, otmp);
1174. 			migrate_to_level(mtmp, ledger_no(&tolevel), 0);
1175. 			return 2;
1176. 		    } else {
1177. skipmsg:
1178. 			if (vismon) {
1179. 			    pline("%s looks uneasy.", Monnam(mtmp));
1180. 			    if(!objects[POT_GAIN_LEVEL].oc_name_known
1181. 			      && !objects[POT_GAIN_LEVEL].oc_uname)
1182. 				docall(otmp);
1183. 			}
1184. 			m_useup(mtmp, otmp);
1185. 			return 2;
1186. 		    }
1187. 		}
1188. 		if (vismon) pline("%s seems more experienced.", Monnam(mtmp));
1189. 		i = rnd(8);
1190. 		if (oseen) makeknown(POT_GAIN_LEVEL);
1191. 		m_useup(mtmp, otmp);
1192. 		if (!grow_up(mtmp,(struct monst *)0)) return 1;
1193. 			/* grew into genocided monster */
1194. 		mtmp->mhp += i;
1195. 		mtmp->mhpmax += i;
1196. 		return 2;
1197. 	case MUSE_WAN_MAKE_INVISIBLE:
1198. 		mzapmsg(mtmp, otmp, TRUE);
1199. 		otmp->spe--;
1200. 		mtmp->minvis = 1;
1201. 		newsym(mtmp->mx,mtmp->my);
1202. 		if (mtmp->wormno) see_wsegs(mtmp);
1203. 		return 2;
1204. 	case MUSE_POT_INVISIBILITY:
1205. 		mquaffmsg(mtmp, otmp);
1206. 		if (vis) pline("Gee, all of a sudden %s can't see %sself.",
1207. 			mon_nam(mtmp),
1208. 			humanoid(mtmp->data) ? (mtmp->female ? "her" : "him")
1209. 					     : "it");
1210. 		if (oseen) makeknown(POT_INVISIBILITY);
1211. 		mtmp->minvis = 1;
1212. 		newsym(mtmp->mx,mtmp->my);
1213. 		if (mtmp->wormno) see_wsegs(mtmp);
1214. 		if (otmp->cursed) {
1215. 			mtmp->minvis = 0;
1216. 			pline("For some reason, %s presence is known to you.",
1217. 				s_suffix(mon_nam(mtmp)));
1218. 			you_aggravate(mtmp);
1219. 			mtmp->minvis = 1;
1220. 			newsym(mtmp->mx,mtmp->my);
1221. 		}
1222. 		m_useup(mtmp, otmp);
1223. 		return 2;
1224. 	case MUSE_WAN_SPEED_MONSTER:
1225. 		mzapmsg(mtmp, otmp, TRUE);
1226. 		otmp->spe--;
1227. 		if (mtmp->mspeed == MSLOW) mtmp->mspeed = 0;
1228. 		else mtmp->mspeed = MFAST;
1229. 		return 2;
1230. 	case MUSE_POT_SPEED:
1231. 		mquaffmsg(mtmp, otmp);
1232. 		if (vismon) pline("%s is suddenly moving much faster.",
1233. 			Monnam(mtmp));
1234. 		if (oseen) makeknown(POT_SPEED);
1235. 		if (mtmp->mspeed == MSLOW) mtmp->mspeed = 0;
1236. 		else mtmp->mspeed = MFAST;
1237. 		m_useup(mtmp, otmp);
1238. 		return 2;
1239. 	case MUSE_WAN_POLYMORPH:
1240. 		mzapmsg(mtmp, otmp, TRUE);
1241. 		otmp->spe--;
1242. 		(void) newcham(mtmp, rndmonst());
1243. 		if (oseen) makeknown(WAN_POLYMORPH);
1244. 		return 2;
1245. #ifdef POLYSELF
1246. 	case MUSE_POLY_TRAP:
1247. 		if (vismon)
1248. 		    pline("%s deliberately goes onto a polymorph trap!",
1249. 			  Monnam(mtmp));
1250. 		seetrap(t_at(trapx,trapy));
1251. 
1252. 		/*  don't use rloc() due to worms */
1253. 		remove_monster(mtmp->mx, mtmp->my);
1254. 		newsym(mtmp->mx, mtmp->my);
1255. 		place_monster(mtmp, trapx, trapy);
1256. 		if (mtmp->wormno) worm_move(mtmp);
1257. 		newsym(trapx, trapy);
1258. 
1259. 		(void) newcham(mtmp, (struct permonst *)0);
1260. 		return 2;
1261. #endif
1262. 	case 0: return 0; /* i.e. an exploded wand */
1263. 	default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
1264. 			m.has_misc);
1265. 		break;
1266. 	}
1267. 	return 0;
1268. }
1269. 
1270. static void
1271. you_aggravate(mtmp)
1272. struct monst *mtmp;
1273. {
1274. 	cls();
1275. 	show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp));
1276. 	display_self();
1277. 	You("feel aggravated at %s.", mon_nam(mtmp));
1278. 	display_nhwindow(WIN_MAP, TRUE);
1279. 	docrt();
1280. 	if (unconscious()) {
1281. 		multi = -1;
1282. 		nomovemsg =
1283. 		      "Aggravated, you are jolted into full consciousness.";
1284. 	}
1285. }
1286. 
1287. int
1288. rnd_misc_item(mtmp)
1289. struct monst *mtmp;
1290. {
1291. 	struct permonst *pm = mtmp->data;
1292. 	int difficulty = monstr[(monsndx(pm))];
1293. 
1294. 	if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1295. 			|| pm->mlet == S_GHOST
1296. # ifdef KOPS
1297. 			|| pm->mlet == S_KOP
1298. # endif
1299. 		) return 0;
1300. 	/* Unlike other rnd_item functions, we only allow _weak_ monsters
1301. 	 * to have this item; after all, the item will be used to strengthen
1302. 	 * the monster and strong monsters won't use it at all...
1303. 	 */
1304. 	if (difficulty < 6 && !rn2(30)) return WAN_POLYMORPH;
1305. 
1306. 	switch (rn2(7)) {
1307. 		case 0: case 1:
1308. 			if (mtmp->isgd) return 0;
1309. 			return POT_SPEED;
1310. 		case 2:
1311. 			if (mtmp->mpeaceful && !See_invisible) return 0;
1312. 			return WAN_MAKE_INVISIBLE;
1313. 		case 3:
1314. 			if (mtmp->mpeaceful && !See_invisible) return 0;
1315. 			return POT_INVISIBILITY;
1316. 		case 4:
1317. 			if (mtmp->isgd) return 0;
1318. 			return WAN_SPEED_MONSTER;
1319. 		case 5: case 6:
1320. 			return POT_GAIN_LEVEL;
1321. 	}
1322. 	/*NOTREACHED*/
1323. 	return 0;
1324. }
1325. 
1326. boolean
1327. searches_for_item(mon, obj)
1328. struct monst *mon;
1329. struct obj *obj;
1330. {
1331. 	int typ = obj->otyp;
1332. 
1333. 	if (is_animal(mon->data) || mindless(mon->data)) return FALSE;
1334. 	return((obj->oclass == WAND_CLASS && objects[typ].oc_dir == RAY)
1335. 		|| typ == WAN_STRIKING
1336. 		|| (!mon->minvis &&
1337. 			(typ == WAN_MAKE_INVISIBLE || typ == POT_INVISIBILITY))
1338. 		|| (mon->mspeed != MFAST &&
1339. 			(typ == WAN_SPEED_MONSTER || typ == POT_SPEED))
1340. 		|| typ == POT_HEALING
1341. 		|| typ == POT_EXTRA_HEALING
1342. 		|| typ == POT_GAIN_LEVEL
1343. 		|| (monstr[monsndx(mon->data)] < 6 && typ == WAN_POLYMORPH)
1344. 		|| (!is_floater(mon->data) && typ == WAN_DIGGING)
1345. 		|| typ == WAN_TELEPORTATION
1346. 		|| typ == SCR_TELEPORTATION
1347. 		|| typ == WAN_CREATE_MONSTER
1348. 		|| typ == SCR_CREATE_MONSTER
1349. 		|| typ == POT_PARALYSIS
1350. 		|| typ == POT_BLINDNESS
1351. 		|| typ == POT_CONFUSION
1352. 		|| (typ == PICK_AXE && needspick(mon->data))
1353. 	);
1354. }
1355. #endif
1356. 
1357. /*muse.c*/

Also on Fandom

Random Wiki