Wikia

Wikihack

Source:Muse.c

2,032pages on
this wiki
Talk0

Below is the full text to src/muse.c from NetHack 3.4.3. To link to a particular line, write [[muse.c#line123]], for example.

Top of file Edit

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.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
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.   

precheck Edit

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
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(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(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.  	if (obj->oclass == WAND_CLASS && obj->cursed && !rn2(100)) {
127.  	    int dam = d(obj->spe+2, 6);
128.  
129.  	    if (flags.soundok) {
130.  		if (vis) pline("%s zaps %s, which suddenly explodes!",
131.  			Monnam(mon), an(xname(obj)));
132.  		else You_hear("a zap and an explosion in the distance.");
133.  	    }
134.  	    m_useup(mon, obj);
135.  	    if (mon->mhp <= dam) {
136.  		monkilled(mon, "", AD_RBRE);
137.  		return 1;
138.  	    }
139.  	    else mon->mhp -= dam;
140.  	    m.has_defense = m.has_offense = m.has_misc = 0;
141.  	    /* Only one needed to be set to 0 but the others are harmless */
142.  	}
143.  	return 0;
144.  }
145.  

mzapmsg Edit

146.  STATIC_OVL void
147.  mzapmsg(mtmp, otmp, self)
148.  struct monst *mtmp;
149.  struct obj *otmp;
150.  boolean self;
151.  {
152.  	if (!canseemon(mtmp)) {
153.  		if (flags.soundok)
154.  			You_hear("a %s zap.",
155.  					(distu(mtmp->mx,mtmp->my) <= (BOLT_LIM+1)*(BOLT_LIM+1)) ?
156.  					"nearby" : "distant");
157.  	} else if (self)
158.  		pline("%s zaps %sself with %s!",
159.  		      Monnam(mtmp), mhim(mtmp), doname(otmp));
160.  	else {
161.  		pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp)));
162.  		stop_occupation();
163.  	}
164.  }
165.  

mreadmsg Edit

166.  STATIC_OVL void
167.  mreadmsg(mtmp, otmp)
168.  struct monst *mtmp;
169.  struct obj *otmp;
170.  {
171.  	boolean vismon = canseemon(mtmp);
172.  	char onambuf[BUFSZ];
173.  	short saverole;
174.  	unsigned savebknown;
175.  
176.  	if (!vismon && !flags.soundok)
177.  	    return;		/* no feedback */
178.  
179.  	otmp->dknown = 1;  /* seeing or hearing it read reveals its label */
180.  	/* shouldn't be able to hear curse/bless status of unseen scrolls;
181.  	   for priest characters, bknown will always be set during naming */
182.  	savebknown = otmp->bknown;
183.  	saverole = Role_switch;
184.  	if (!vismon) {
185.  	    otmp->bknown = 0;
186.  	    if (Role_if(PM_PRIEST)) Role_switch = 0;
187.  	}
188.  	Strcpy(onambuf, singular(otmp, doname));
189.  	Role_switch = saverole;
190.  	otmp->bknown = savebknown;
191.  
192.  	if (vismon)
193.  	    pline("%s reads %s!", Monnam(mtmp), onambuf);
194.  	else
195.  	    You_hear("%s reading %s.",
196.  		x_monnam(mtmp, ARTICLE_A, (char *)0,
197.  		    (SUPPRESS_IT|SUPPRESS_INVISIBLE|SUPPRESS_SADDLE), FALSE),
198.  		onambuf);
199.  
200.  	if (mtmp->mconf)
201.  	    pline("Being confused, %s mispronounces the magic words...",
202.  		  vismon ? mon_nam(mtmp) : mhe(mtmp));
203.  }
204.  

mquaffmsg Edit

205.  STATIC_OVL void
206.  mquaffmsg(mtmp, otmp)
207.  struct monst *mtmp;
208.  struct obj *otmp;
209.  {
210.  	if (canseemon(mtmp)) {
211.  		otmp->dknown = 1;
212.  		pline("%s drinks %s!", Monnam(mtmp), singular(otmp, doname));
213.  	} else
214.  		if (flags.soundok)
215.  			You_hear("a chugging sound.");
216.  }
217.  
218.  /* Defines for various types of stuff.  The order in which monsters prefer
219.   * to use them is determined by the order of the code logic, not the
220.   * numerical order in which they are defined.
221.   */
222.  #define MUSE_SCR_TELEPORTATION 1
223.  #define MUSE_WAN_TELEPORTATION_SELF 2
224.  #define MUSE_POT_HEALING 3
225.  #define MUSE_POT_EXTRA_HEALING 4
226.  #define MUSE_WAN_DIGGING 5
227.  #define MUSE_TRAPDOOR 6
228.  #define MUSE_TELEPORT_TRAP 7
229.  #define MUSE_UPSTAIRS 8
230.  #define MUSE_DOWNSTAIRS 9
231.  #define MUSE_WAN_CREATE_MONSTER 10
232.  #define MUSE_SCR_CREATE_MONSTER 11
233.  #define MUSE_UP_LADDER 12
234.  #define MUSE_DN_LADDER 13
235.  #define MUSE_SSTAIRS 14
236.  #define MUSE_WAN_TELEPORTATION 15
237.  #define MUSE_BUGLE 16
238.  #define MUSE_UNICORN_HORN 17
239.  #define MUSE_POT_FULL_HEALING 18
240.  #define MUSE_LIZARD_CORPSE 19
241.  /*
242.  #define MUSE_INNATE_TPT 9999
243.   * We cannot use this.  Since monsters get unlimited teleportation, if they
244.   * were allowed to teleport at will you could never catch them.  Instead,
245.   * assume they only teleport at random times, despite the inconsistency that if
246.   * you polymorph into one you teleport at will.
247.   */
248.  

find_defensive Edit

249.  /* Select a defensive item/action for a monster.  Returns TRUE iff one is
250.   * found.
251.   */
252.  boolean
253.  find_defensive(mtmp)
254.  struct monst *mtmp;
255.  {
256.  	register struct obj *obj = 0;
257.  	struct trap *t;
258.  	int x=mtmp->mx, y=mtmp->my;
259.  	boolean stuck = (mtmp == u.ustuck);
260.  	boolean immobile = (mtmp->data->mmove == 0);
261.  	int fraction;
262.  
263.  	if (is_animal(mtmp->data) || mindless(mtmp->data))
264.  		return FALSE;
265.  	if(dist2(x, y, mtmp->mux, mtmp->muy) > 25)
266.  		return FALSE;
267.  	if (u.uswallow && stuck) return FALSE;
268.  
269.  	m.defensive = (struct obj *)0;
270.  	m.has_defense = 0;
271.  
272.  	/* since unicorn horns don't get used up, the monster would look
273.  	 * silly trying to use the same cursed horn round after round
274.  	 */
275.  	if (mtmp->mconf || mtmp->mstun || !mtmp->mcansee) {
276.  	    if (!is_unicorn(mtmp->data) && !nohands(mtmp->data)) {
277.  		for(obj = mtmp->minvent; obj; obj = obj->nobj)
278.  		    if (obj->otyp == UNICORN_HORN && !obj->cursed)
279.  			break;
280.  	    }
281.  	    if (obj || is_unicorn(mtmp->data)) {
282.  		m.defensive = obj;
283.  		m.has_defense = MUSE_UNICORN_HORN;
284.  		return TRUE;
285.  	    }
286.  	}
287.  
288.  	if (mtmp->mconf) {
289.  	    for(obj = mtmp->minvent; obj; obj = obj->nobj) {
290.  		if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD) {
291.  		    m.defensive = obj;
292.  		    m.has_defense = MUSE_LIZARD_CORPSE;
293.  		    return TRUE;
294.  		}
295.  	    }
296.  	}
297.  
298.  	/* It so happens there are two unrelated cases when we might want to
299.  	 * check specifically for healing alone.  The first is when the monster
300.  	 * is blind (healing cures blindness).  The second is when the monster
301.  	 * is peaceful; then we don't want to flee the player, and by
302.  	 * coincidence healing is all there is that doesn't involve fleeing.
303.  	 * These would be hard to combine because of the control flow.
304.  	 * Pestilence won't use healing even when blind.
305.  	 */
306.  	if (!mtmp->mcansee && !nohands(mtmp->data) &&
307.  		mtmp->data != &mons[PM_PESTILENCE]) {
308.  	    if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) {
309.  		m.defensive = obj;
310.  		m.has_defense = MUSE_POT_FULL_HEALING;
311.  		return TRUE;
312.  	    }
313.  	    if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) {
314.  		m.defensive = obj;
315.  		m.has_defense = MUSE_POT_EXTRA_HEALING;
316.  		return TRUE;
317.  	    }
318.  	    if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) {
319.  		m.defensive = obj;
320.  		m.has_defense = MUSE_POT_HEALING;
321.  		return TRUE;
322.  	    }
323.  	}
324.  
325.  	fraction = u.ulevel < 10 ? 5 : u.ulevel < 14 ? 4 : 3;
326.  	if(mtmp->mhp >= mtmp->mhpmax ||
327.  			(mtmp->mhp >= 10 && mtmp->mhp*fraction >= mtmp->mhpmax))
328.  		return FALSE;
329.  
330.  	if (mtmp->mpeaceful) {
331.  	    if (!nohands(mtmp->data)) {
332.  		if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) {
333.  		    m.defensive = obj;
334.  		    m.has_defense = MUSE_POT_FULL_HEALING;
335.  		    return TRUE;
336.  		}
337.  		if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) {
338.  		    m.defensive = obj;
339.  		    m.has_defense = MUSE_POT_EXTRA_HEALING;
340.  		    return TRUE;
341.  		}
342.  		if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) {
343.  		    m.defensive = obj;
344.  		    m.has_defense = MUSE_POT_HEALING;
345.  		    return TRUE;
346.  		}
347.  	    }
348.  	    return FALSE;
349.  	}
350.  
351.  	if (levl[x][y].typ == STAIRS && !stuck && !immobile) {
352.  		if (x == xdnstair && y == ydnstair && !is_floater(mtmp->data))
353.  			m.has_defense = MUSE_DOWNSTAIRS;
354.  		if (x == xupstair && y == yupstair && ledger_no(&u.uz) != 1)
355.  	/* Unfair to let the monsters leave the dungeon with the Amulet */
356.  	/* (or go to the endlevel since you also need it, to get there) */
357.  			m.has_defense = MUSE_UPSTAIRS;
358.  	} else if (levl[x][y].typ == LADDER && !stuck && !immobile) {
359.  		if (x == xupladder && y == yupladder)
360.  			m.has_defense = MUSE_UP_LADDER;
361.  		if (x == xdnladder && y == ydnladder && !is_floater(mtmp->data))
362.  			m.has_defense = MUSE_DN_LADDER;
363.  	} else if (sstairs.sx && sstairs.sx == x && sstairs.sy == y) {
364.  		m.has_defense = MUSE_SSTAIRS;
365.  	} else if (!stuck && !immobile) {
366.  	/* Note: trap doors take precedence over teleport traps. */
367.  		int xx, yy;
368.  
369.  		for(xx = x-1; xx <= x+1; xx++) for(yy = y-1; yy <= y+1; yy++)
370.  		if (isok(xx,yy))
371.  		if (xx != u.ux && yy != u.uy)
372.  		if (mtmp->data != &mons[PM_GRID_BUG] || xx == x || yy == y)
373.  		if ((xx==x && yy==y) || !level.monsters[xx][yy])
374.  		if ((t = t_at(xx,yy)) != 0)
375.  		if ((verysmall(mtmp->data) || throws_rocks(mtmp->data) ||
376.  		     passes_walls(mtmp->data)) || !sobj_at(BOULDER, xx, yy))
377.  		if (!onscary(xx,yy,mtmp)) {
378.  			if ((t->ttyp == TRAPDOOR || t->ttyp == HOLE)
379.  				&& !is_floater(mtmp->data)
380.  				&& !mtmp->isshk && !mtmp->isgd
381.  				&& !mtmp->ispriest
382.  				&& Can_fall_thru(&u.uz)
383.  						) {
384.  				trapx = xx;
385.  				trapy = yy;
386.  				m.has_defense = MUSE_TRAPDOOR;
387.  			} else if (t->ttyp == TELEP_TRAP && m.has_defense != MUSE_TRAPDOOR) {
388.  				trapx = xx;
389.  				trapy = yy;
390.  				m.has_defense = MUSE_TELEPORT_TRAP;
391.  			}
392.  		}
393.  	}
394.  
395.  	if (nohands(mtmp->data))	/* can't use objects */
396.  		goto botm;
397.  
398.  	if (is_mercenary(mtmp->data) && (obj = m_carrying(mtmp, BUGLE))) {
399.  		int xx, yy;
400.  		struct monst *mon;
401.  
402.  		/* Distance is arbitrary.  What we really want to do is
403.  		 * have the soldier play the bugle when it sees or
404.  		 * remembers soldiers nearby...
405.  		 */
406.  		for(xx = x-3; xx <= x+3; xx++) for(yy = y-3; yy <= y+3; yy++)
407.  		if (isok(xx,yy))
408.  		if ((mon = m_at(xx,yy)) && is_mercenary(mon->data) &&
409.  				mon->data != &mons[PM_GUARD] &&
410.  				(mon->msleeping || (!mon->mcanmove))) {
411.  			m.defensive = obj;
412.  			m.has_defense = MUSE_BUGLE;
413.  		}
414.  	}
415.  
416.  	/* use immediate physical escape prior to attempting magic */
417.  	if (m.has_defense)    /* stairs, trap door or tele-trap, bugle alert */
418.  		goto botm;
419.  
420.  	/* kludge to cut down on trap destruction (particularly portals) */
421.  	t = t_at(x,y);
422.  	if (t && (t->ttyp == PIT || t->ttyp == SPIKED_PIT ||
423.  		  t->ttyp == WEB || t->ttyp == BEAR_TRAP))
424.  		t = 0;		/* ok for monster to dig here */
425.  
426.  #define nomore(x) if(m.has_defense==x) continue;
427.  	for (obj = mtmp->minvent; obj; obj = obj->nobj) {
428.  		/* don't always use the same selection pattern */
429.  		if (m.has_defense && !rn2(3)) break;
430.  
431.  		/* nomore(MUSE_WAN_DIGGING); */
432.  		if (m.has_defense == MUSE_WAN_DIGGING) break;
433.  		if (obj->otyp == WAN_DIGGING && obj->spe > 0 && !stuck && !t
434.  		    && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest
435.  		    && !is_floater(mtmp->data)
436.  		    /* monsters digging in Sokoban can ruin things */
437.  		    && !In_sokoban(&u.uz)
438.  		    /* digging wouldn't be effective; assume they know that */
439.  		    && !(levl[x][y].wall_info & W_NONDIGGABLE)
440.  		    && !(Is_botlevel(&u.uz) || In_endgame(&u.uz))
441.  		    && !(is_ice(x,y) || is_pool(x,y) || is_lava(x,y))
442.  		    && !(mtmp->data == &mons[PM_VLAD_THE_IMPALER]
443.  			 && In_V_tower(&u.uz))) {
444.  			m.defensive = obj;
445.  			m.has_defense = MUSE_WAN_DIGGING;
446.  		}
447.  		nomore(MUSE_WAN_TELEPORTATION_SELF);
448.  		nomore(MUSE_WAN_TELEPORTATION);
449.  		if(obj->otyp == WAN_TELEPORTATION && obj->spe > 0) {
450.  		    /* use the TELEP_TRAP bit to determine if they know
451.  		     * about noteleport on this level or not.  Avoids
452.  		     * ineffective re-use of teleportation.  This does
453.  		     * mean if the monster leaves the level, they'll know
454.  		     * about teleport traps.
455.  		     */
456.  		    if (!level.flags.noteleport ||
457.  			!(mtmp->mtrapseen & (1 << (TELEP_TRAP-1)))) {
458.  			m.defensive = obj;
459.  			m.has_defense = (mon_has_amulet(mtmp))
460.  				? MUSE_WAN_TELEPORTATION
461.  				: MUSE_WAN_TELEPORTATION_SELF;
462.  		    }
463.  		}
464.  		nomore(MUSE_SCR_TELEPORTATION);
465.  		if(obj->otyp == SCR_TELEPORTATION && mtmp->mcansee
466.  		   && haseyes(mtmp->data)
467.  		   && (!obj->cursed ||
468.  		       (!(mtmp->isshk && inhishop(mtmp))
469.  			    && !mtmp->isgd && !mtmp->ispriest))) {
470.  		    /* see WAN_TELEPORTATION case above */
471.  		    if (!level.flags.noteleport ||
472.  			!(mtmp->mtrapseen & (1 << (TELEP_TRAP-1)))) {
473.  			m.defensive = obj;
474.  			m.has_defense = MUSE_SCR_TELEPORTATION;
475.  		    }
476.  		}
477.  
478.  	    if (mtmp->data != &mons[PM_PESTILENCE]) {
479.  		nomore(MUSE_POT_FULL_HEALING);
480.  		if(obj->otyp == POT_FULL_HEALING) {
481.  			m.defensive = obj;
482.  			m.has_defense = MUSE_POT_FULL_HEALING;
483.  		}
484.  		nomore(MUSE_POT_EXTRA_HEALING);
485.  		if(obj->otyp == POT_EXTRA_HEALING) {
486.  			m.defensive = obj;
487.  			m.has_defense = MUSE_POT_EXTRA_HEALING;
488.  		}
489.  		nomore(MUSE_WAN_CREATE_MONSTER);
490.  		if(obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
491.  			m.defensive = obj;
492.  			m.has_defense = MUSE_WAN_CREATE_MONSTER;
493.  		}
494.  		nomore(MUSE_POT_HEALING);
495.  		if(obj->otyp == POT_HEALING) {
496.  			m.defensive = obj;
497.  			m.has_defense = MUSE_POT_HEALING;
498.  		}
499.  	    } else {	/* Pestilence */
500.  		nomore(MUSE_POT_FULL_HEALING);
501.  		if (obj->otyp == POT_SICKNESS) {
502.  			m.defensive = obj;
503.  			m.has_defense = MUSE_POT_FULL_HEALING;
504.  		}
505.  		nomore(MUSE_WAN_CREATE_MONSTER);
506.  		if (obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
507.  			m.defensive = obj;
508.  			m.has_defense = MUSE_WAN_CREATE_MONSTER;
509.  		}
510.  	    }
511.  		nomore(MUSE_SCR_CREATE_MONSTER);
512.  		if(obj->otyp == SCR_CREATE_MONSTER) {
513.  			m.defensive = obj;
514.  			m.has_defense = MUSE_SCR_CREATE_MONSTER;
515.  		}
516.  	}
517.  botm:	return((boolean)(!!m.has_defense));
518.  #undef nomore
519.  }
520.  

use_defensive Edit

521.  /* Perform a defensive action for a monster.  Must be called immediately
522.   * after find_defensive().  Return values are 0: did something, 1: died,
523.   * 2: did something and can't attack again (i.e. teleported).
524.   */
525.  int
526.  use_defensive(mtmp)
527.  struct monst *mtmp;
528.  {
529.  	int i, fleetim, how = 0;
530.  	struct obj *otmp = m.defensive;
531.  	boolean vis, vismon, oseen;
532.  	const char *mcsa = "%s can see again.";
533.  
534.  	if ((i = precheck(mtmp, otmp)) != 0) return i;
535.  	vis = cansee(mtmp->mx, mtmp->my);
536.  	vismon = canseemon(mtmp);
537.  	oseen = otmp && vismon;
538.  
539.  	/* when using defensive choice to run away, we want monster to avoid
540.  	   rushing right straight back; don't override if already scared */
541.  	fleetim = !mtmp->mflee ? (33 - (30 * mtmp->mhp / mtmp->mhpmax)) : 0;
542.  #define m_flee(m)	if (fleetim && !m->iswiz) \
543.  			{ monflee(m, fleetim, FALSE, FALSE); }
544.  
545.  	switch(m.has_defense) {
546.  	case MUSE_UNICORN_HORN:
547.  		if (vismon) {
548.  		    if (otmp)
549.  			pline("%s uses a unicorn horn!", Monnam(mtmp));
550.  		    else
551.  			pline_The("tip of %s's horn glows!", mon_nam(mtmp));
552.  		}
553.  		if (!mtmp->mcansee) {
554.  		    mtmp->mcansee = 1;
555.  		    mtmp->mblinded = 0;
556.  		    if (vismon) pline(mcsa, Monnam(mtmp));
557.  		} else if (mtmp->mconf || mtmp->mstun) {
558.  		    mtmp->mconf = mtmp->mstun = 0;
559.  		    if (vismon)
560.  			pline("%s seems steadier now.", Monnam(mtmp));
561.  		} else impossible("No need for unicorn horn?");
562.  		return 2;
563.  	case MUSE_BUGLE:
564.  		if (vismon)
565.  			pline("%s plays %s!", Monnam(mtmp), doname(otmp));
566.  		else if (flags.soundok)
567.  			You_hear("a bugle playing reveille!");
568.  		awaken_soldiers();
569.  		return 2;
570.  	case MUSE_WAN_TELEPORTATION_SELF:
571.  		if ((mtmp->isshk && inhishop(mtmp))
572.  		       || mtmp->isgd || mtmp->ispriest) return 2;
573.  		m_flee(mtmp);
574.  		mzapmsg(mtmp, otmp, TRUE);
575.  		otmp->spe--;
576.  		how = WAN_TELEPORTATION;
577.  mon_tele:
578.  		if (tele_restrict(mtmp)) {	/* mysterious force... */
579.  		    if (vismon && how)		/* mentions 'teleport' */
580.  			makeknown(how);
581.  		    /* monster learns that teleportation isn't useful here */
582.  		    if (level.flags.noteleport)
583.  			mtmp->mtrapseen |= (1 << (TELEP_TRAP-1));
584.  		    return 2;
585.  		}
586.  		if ((
587.  #if 0
588.  			mon_has_amulet(mtmp) ||
589.  #endif
590.  			On_W_tower_level(&u.uz)) && !rn2(3)) {
591.  		    if (vismon)
592.  			pline("%s seems disoriented for a moment.",
593.  				Monnam(mtmp));
594.  		    return 2;
595.  		}
596.  		if (oseen && how) makeknown(how);
597.  		(void) rloc(mtmp, FALSE);
598.  		return 2;
599.  	case MUSE_WAN_TELEPORTATION:
600.  		zap_oseen = oseen;
601.  		mzapmsg(mtmp, otmp, FALSE);
602.  		otmp->spe--;
603.  		m_using = TRUE;
604.  		mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp);
605.  		/* monster learns that teleportation isn't useful here */
606.  		if (level.flags.noteleport)
607.  		    mtmp->mtrapseen |= (1 << (TELEP_TRAP-1));
608.  		m_using = FALSE;
609.  		return 2;
610.  	case MUSE_SCR_TELEPORTATION:
611.  	    {
612.  		int obj_is_cursed = otmp->cursed;
613.  
614.  		if (mtmp->isshk || mtmp->isgd || mtmp->ispriest) return 2;
615.  		m_flee(mtmp);
616.  		mreadmsg(mtmp, otmp);
617.  		m_useup(mtmp, otmp);	/* otmp might be free'ed */
618.  		how = SCR_TELEPORTATION;
619.  		if (obj_is_cursed || mtmp->mconf) {
620.  			int nlev;
621.  			d_level flev;
622.  
623.  			if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
624.  			    if (vismon)
625.  				pline("%s seems very disoriented for a moment.",
626.  					Monnam(mtmp));
627.  			    return 2;
628.  			}
629.  			nlev = random_teleport_level();
630.  			if (nlev == depth(&u.uz)) {
631.  			    if (vismon)
632.  				pline("%s shudders for a moment.",
633.  								Monnam(mtmp));
634.  			    return 2;
635.  			}
636.  			get_level(&flev, nlev);
637.  			migrate_to_level(mtmp, ledger_no(&flev), MIGR_RANDOM,
638.  				(coord *)0);
639.  			if (oseen) makeknown(SCR_TELEPORTATION);
640.  		} else goto mon_tele;
641.  		return 2;
642.  	    }
643.  	case MUSE_WAN_DIGGING:
644.  	    {	struct trap *ttmp;
645.  
646.  		m_flee(mtmp);
647.  		mzapmsg(mtmp, otmp, FALSE);
648.  		otmp->spe--;
649.  		if (oseen) makeknown(WAN_DIGGING);
650.  		if (IS_FURNITURE(levl[mtmp->mx][mtmp->my].typ) ||
651.  		    IS_DRAWBRIDGE(levl[mtmp->mx][mtmp->my].typ) ||
652.  		    (is_drawbridge_wall(mtmp->mx, mtmp->my) >= 0) ||
653.  		    (sstairs.sx && sstairs.sx == mtmp->mx &&
654.  				   sstairs.sy == mtmp->my)) {
655.  			pline_The("digging ray is ineffective.");
656.  			return 2;
657.  		}
658.  		if (!Can_dig_down(&u.uz)) {
659.  		    if(canseemon(mtmp))
660.  			pline_The("%s here is too hard to dig in.",
661.  					surface(mtmp->mx, mtmp->my));
662.  		    return 2;
663.  		}
664.  		ttmp = maketrap(mtmp->mx, mtmp->my, HOLE);
665.  		if (!ttmp) return 2;
666.  		seetrap(ttmp);
667.  		if (vis) {
668.  		    pline("%s has made a hole in the %s.", Monnam(mtmp),
669.  				surface(mtmp->mx, mtmp->my));
670.  		    pline("%s %s through...", Monnam(mtmp),
671.  			  is_flyer(mtmp->data) ? "dives" : "falls");
672.  		} else if (flags.soundok)
673.  			You_hear("%s crash through the %s.", something,
674.  				surface(mtmp->mx, mtmp->my));
675.  		/* we made sure that there is a level for mtmp to go to */
676.  		migrate_to_level(mtmp, ledger_no(&u.uz) + 1,
677.  				 MIGR_RANDOM, (coord *)0);
678.  		return 2;
679.  	    }
680.  	case MUSE_WAN_CREATE_MONSTER:
681.  	    {	coord cc;
682.  		    /* pm: 0 => random, eel => aquatic, croc => amphibious */
683.  		struct permonst *pm = !is_pool(mtmp->mx, mtmp->my) ? 0 :
684.  			     &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE];
685.  		struct monst *mon;
686.  
687.  		if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) return 0;
688.  		mzapmsg(mtmp, otmp, FALSE);
689.  		otmp->spe--;
690.  		mon = makemon((struct permonst *)0, cc.x, cc.y, NO_MM_FLAGS);
691.  		if (mon && canspotmon(mon) && oseen)
692.  		    makeknown(WAN_CREATE_MONSTER);
693.  		return 2;
694.  	    }
695.  	case MUSE_SCR_CREATE_MONSTER:
696.  	    {	coord cc;
697.  		struct permonst *pm = 0, *fish = 0;
698.  		int cnt = 1;
699.  		struct monst *mon;
700.  		boolean known = FALSE;
701.  
702.  		if (!rn2(73)) cnt += rnd(4);
703.  		if (mtmp->mconf || otmp->cursed) cnt += 12;
704.  		if (mtmp->mconf) pm = fish = &mons[PM_ACID_BLOB];
705.  		else if (is_pool(mtmp->mx, mtmp->my))
706.  		    fish = &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE];
707.  		mreadmsg(mtmp, otmp);
708.  		while(cnt--) {
709.  		    /* `fish' potentially gives bias towards water locations;
710.  		       `pm' is what to actually create (0 => random) */
711.  		    if (!enexto(&cc, mtmp->mx, mtmp->my, fish)) break;
712.  		    mon = makemon(pm, cc.x, cc.y, NO_MM_FLAGS);
713.  		    if (mon && canspotmon(mon)) known = TRUE;
714.  		}
715.  		/* The only case where we don't use oseen.  For wands, you
716.  		 * have to be able to see the monster zap the wand to know
717.  		 * what type it is.  For teleport scrolls, you have to see
718.  		 * the monster to know it teleported.
719.  		 */
720.  		if (known)
721.  		    makeknown(SCR_CREATE_MONSTER);
722.  		else if (!objects[SCR_CREATE_MONSTER].oc_name_known
723.  			&& !objects[SCR_CREATE_MONSTER].oc_uname)
724.  		    docall(otmp);
725.  		m_useup(mtmp, otmp);
726.  		return 2;
727.  	    }
728.  	case MUSE_TRAPDOOR:
729.  		/* trap doors on "bottom" levels of dungeons are rock-drop
730.  		 * trap doors, not holes in the floor.  We check here for
731.  		 * safety.
732.  		 */
733.  		if (Is_botlevel(&u.uz)) return 0;
734.  		m_flee(mtmp);
735.  		if (vis) {
736.  			struct trap *t;
737.  			t = t_at(trapx,trapy);
738.  			pline("%s %s into a %s!", Monnam(mtmp),
739.  			makeplural(locomotion(mtmp->data, "jump")),
740.  			t->ttyp == TRAPDOOR ? "trap door" : "hole");
741.  			if (levl[trapx][trapy].typ == SCORR) {
742.  			    levl[trapx][trapy].typ = CORR;
743.  			    unblock_point(trapx, trapy);
744.  			}
745.  			seetrap(t_at(trapx,trapy));
746.  		}
747.  
748.  		/*  don't use rloc_to() because worm tails must "move" */
749.  		remove_monster(mtmp->mx, mtmp->my);
750.  		newsym(mtmp->mx, mtmp->my);	/* update old location */
751.  		place_monster(mtmp, trapx, trapy);
752.  		if (mtmp->wormno) worm_move(mtmp);
753.  		newsym(trapx, trapy);
754.  
755.  		migrate_to_level(mtmp, ledger_no(&u.uz) + 1,
756.  				 MIGR_RANDOM, (coord *)0);
757.  		return 2;
758.  	case MUSE_UPSTAIRS:
759.  		/* Monsters without amulets escape the dungeon and are
760.  		 * gone for good when they leave up the up stairs.
761.  		 * Monsters with amulets would reach the endlevel,
762.  		 * which we cannot allow since that would leave the
763.  		 * player stranded.
764.  		 */
765.  		if (ledger_no(&u.uz) == 1) {
766.  			if (mon_has_special(mtmp))
767.  				return 0;
768.  			if (vismon)
769.  			    pline("%s escapes the dungeon!", Monnam(mtmp));
770.  			mongone(mtmp);
771.  			return 2;
772.  		}
773.  		m_flee(mtmp);
774.  		if (Inhell && mon_has_amulet(mtmp) && !rn2(4) &&
775.  			(dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) {
776.  		    if (vismon) pline(
777.       "As %s climbs the stairs, a mysterious force momentarily surrounds %s...",
778.  				     mon_nam(mtmp), mhim(mtmp));
779.  		    /* simpler than for the player; this will usually be
780.  		       the Wizard and he'll immediately go right to the
781.  		       upstairs, so there's not much point in having any
782.  		       chance for a random position on the current level */
783.  		    migrate_to_level(mtmp, ledger_no(&u.uz) + 1,
784.  				     MIGR_RANDOM, (coord *)0);
785.  		} else {
786.  		    if (vismon) pline("%s escapes upstairs!", Monnam(mtmp));
787.  		    migrate_to_level(mtmp, ledger_no(&u.uz) - 1,
788.  				     MIGR_STAIRS_DOWN, (coord *)0);
789.  		}
790.  		return 2;
791.  	case MUSE_DOWNSTAIRS:
792.  		m_flee(mtmp);
793.  		if (vismon) pline("%s escapes downstairs!", Monnam(mtmp));
794.  		migrate_to_level(mtmp, ledger_no(&u.uz) + 1,
795.  				 MIGR_STAIRS_UP, (coord *)0);
796.  		return 2;
797.  	case MUSE_UP_LADDER:
798.  		m_flee(mtmp);
799.  		if (vismon) pline("%s escapes up the ladder!", Monnam(mtmp));
800.  		migrate_to_level(mtmp, ledger_no(&u.uz) - 1,
801.  				 MIGR_LADDER_DOWN, (coord *)0);
802.  		return 2;
803.  	case MUSE_DN_LADDER:
804.  		m_flee(mtmp);
805.  		if (vismon) pline("%s escapes down the ladder!", Monnam(mtmp));
806.  		migrate_to_level(mtmp, ledger_no(&u.uz) + 1,
807.  				 MIGR_LADDER_UP, (coord *)0);
808.  		return 2;
809.  	case MUSE_SSTAIRS:
810.  		m_flee(mtmp);
811.  		/* the stairs leading up from the 1st level are */
812.  		/* regular stairs, not sstairs.			*/
813.  		if (sstairs.up) {
814.  			if (vismon)
815.  			    pline("%s escapes upstairs!", Monnam(mtmp));
816.  			if(Inhell) {
817.  			    migrate_to_level(mtmp, ledger_no(&sstairs.tolev),
818.  					     MIGR_RANDOM, (coord *)0);
819.  			    return 2;
820.  			}
821.  		} else	if (vismon)
822.  		    pline("%s escapes downstairs!", Monnam(mtmp));
823.  		migrate_to_level(mtmp, ledger_no(&sstairs.tolev),
824.  				 MIGR_SSTAIRS, (coord *)0);
825.  		return 2;
826.  	case MUSE_TELEPORT_TRAP:
827.  		m_flee(mtmp);
828.  		if (vis) {
829.  			pline("%s %s onto a teleport trap!", Monnam(mtmp),
830.  				makeplural(locomotion(mtmp->data, "jump")));
831.  			if (levl[trapx][trapy].typ == SCORR) {
832.  			    levl[trapx][trapy].typ = CORR;
833.  			    unblock_point(trapx, trapy);
834.  			}
835.  			seetrap(t_at(trapx,trapy));
836.  		}
837.  		/*  don't use rloc_to() because worm tails must "move" */
838.  		remove_monster(mtmp->mx, mtmp->my);
839.  		newsym(mtmp->mx, mtmp->my);	/* update old location */
840.  		place_monster(mtmp, trapx, trapy);
841.  		if (mtmp->wormno) worm_move(mtmp);
842.  		newsym(trapx, trapy);
843.  
844.  		goto mon_tele;
845.  	case MUSE_POT_HEALING:
846.  		mquaffmsg(mtmp, otmp);
847.  		i = d(6 + 2 * bcsign(otmp), 4);
848.  		mtmp->mhp += i;
849.  		if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = ++mtmp->mhpmax;
850.  		if (!otmp->cursed && !mtmp->mcansee) {
851.  			mtmp->mcansee = 1;
852.  			mtmp->mblinded = 0;
853.  			if (vismon) pline(mcsa, Monnam(mtmp));
854.  		}
855.  		if (vismon) pline("%s looks better.", Monnam(mtmp));
856.  		if (oseen) makeknown(POT_HEALING);
857.  		m_useup(mtmp, otmp);
858.  		return 2;
859.  	case MUSE_POT_EXTRA_HEALING:
860.  		mquaffmsg(mtmp, otmp);
861.  		i = d(6 + 2 * bcsign(otmp), 8);
862.  		mtmp->mhp += i;
863.  		if (mtmp->mhp > mtmp->mhpmax)
864.  			mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2));
865.  		if (!mtmp->mcansee) {
866.  			mtmp->mcansee = 1;
867.  			mtmp->mblinded = 0;
868.  			if (vismon) pline(mcsa, Monnam(mtmp));
869.  		}
870.  		if (vismon) pline("%s looks much better.", Monnam(mtmp));
871.  		if (oseen) makeknown(POT_EXTRA_HEALING);
872.  		m_useup(mtmp, otmp);
873.  		return 2;
874.  	case MUSE_POT_FULL_HEALING:
875.  		mquaffmsg(mtmp, otmp);
876.  		if (otmp->otyp == POT_SICKNESS) unbless(otmp); /* Pestilence */
877.  		mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 8 : 4));
878.  		if (!mtmp->mcansee && otmp->otyp != POT_SICKNESS) {
879.  			mtmp->mcansee = 1;
880.  			mtmp->mblinded = 0;
881.  			if (vismon) pline(mcsa, Monnam(mtmp));
882.  		}
883.  		if (vismon) pline("%s looks completely healed.", Monnam(mtmp));
884.  		if (oseen) makeknown(otmp->otyp);
885.  		m_useup(mtmp, otmp);
886.  		return 2;
887.  	case MUSE_LIZARD_CORPSE:
888.  		/* not actually called for its unstoning effect */
889.  		mon_consume_unstone(mtmp, otmp, FALSE, FALSE);
890.  		return 2;
891.  	case 0: return 0; /* i.e. an exploded wand */
892.  	default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
893.  			m.has_defense);
894.  		break;
895.  	}
896.  	return 0;
897.  #undef m_flee
898.  }
899.  

rnd_defensive_item Edit

900.  int
901.  rnd_defensive_item(mtmp)
902.  struct monst *mtmp;
903.  {
904.  	struct permonst *pm = mtmp->data;
905.  	int difficulty = monstr[(monsndx(pm))];
906.  	int trycnt = 0;
907.  
908.  	if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
909.  			|| pm->mlet == S_GHOST
910.  # ifdef KOPS
911.  			|| pm->mlet == S_KOP
912.  # endif
913.  		) return 0;
914.      try_again:
915.  	switch (rn2(8 + (difficulty > 3) + (difficulty > 6) +
916.  				(difficulty > 8))) {
917.  		case 6: case 9:
918.  			if (level.flags.noteleport && ++trycnt < 2)
919.  			    goto try_again;
920.  			if (!rn2(3)) return WAN_TELEPORTATION;
921.  			/* else FALLTHRU */
922.  		case 0: case 1:
923.  			return SCR_TELEPORTATION;
924.  		case 8: case 10:
925.  			if (!rn2(3)) return WAN_CREATE_MONSTER;
926.  			/* else FALLTHRU */
927.  		case 2: return SCR_CREATE_MONSTER;
928.  		case 3: return POT_HEALING;
929.  		case 4: return POT_EXTRA_HEALING;
930.  		case 5: return (mtmp->data != &mons[PM_PESTILENCE]) ?
931.  				POT_FULL_HEALING : POT_SICKNESS;
932.  		case 7: if (is_floater(pm) || mtmp->isshk || mtmp->isgd
933.  						|| mtmp->ispriest
934.  									)
935.  				return 0;
936.  			else
937.  				return WAN_DIGGING;
938.  	}
939.  	/*NOTREACHED*/
940.  	return 0;
941.  }
942.  
943.  #define MUSE_WAN_DEATH 1
944.  #define MUSE_WAN_SLEEP 2
945.  #define MUSE_WAN_FIRE 3
946.  #define MUSE_WAN_COLD 4
947.  #define MUSE_WAN_LIGHTNING 5
948.  #define MUSE_WAN_MAGIC_MISSILE 6
949.  #define MUSE_WAN_STRIKING 7
950.  #define MUSE_SCR_FIRE 8
951.  #define MUSE_POT_PARALYSIS 9
952.  #define MUSE_POT_BLINDNESS 10
953.  #define MUSE_POT_CONFUSION 11
954.  #define MUSE_FROST_HORN 12
955.  #define MUSE_FIRE_HORN 13
956.  #define MUSE_POT_ACID 14
957.  /*#define MUSE_WAN_TELEPORTATION 15*/
958.  #define MUSE_POT_SLEEPING 16
959.  #define MUSE_SCR_EARTH 17
960.  

find_offensive Edit

961.  /* Select an offensive item/action for a monster.  Returns TRUE iff one is
962.   * found.
963.   */
964.  boolean
965.  find_offensive(mtmp)
966.  struct monst *mtmp;
967.  {
968.  	register struct obj *obj;
969.  	boolean ranged_stuff = lined_up(mtmp);
970.  	boolean reflection_skip = (Reflecting && rn2(2));
971.  	struct obj *helmet = which_armor(mtmp, W_ARMH);
972.  
973.  	m.offensive = (struct obj *)0;
974.  	m.has_offense = 0;
975.  	if (mtmp->mpeaceful || is_animal(mtmp->data) ||
976.  				mindless(mtmp->data) || nohands(mtmp->data))
977.  		return FALSE;
978.  	if (u.uswallow) return FALSE;
979.  	if (in_your_sanctuary(mtmp, 0, 0)) return FALSE;
980.  	if (dmgtype(mtmp->data, AD_HEAL) && !uwep
981.  #ifdef TOURIST
982.  	    && !uarmu
983.  #endif
984.  	    && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf)
985.  		return FALSE;
986.  
987.  	if (!ranged_stuff) return FALSE;
988.  #define nomore(x) if(m.has_offense==x) continue;
989.  	for(obj=mtmp->minvent; obj; obj=obj->nobj) {
990.  		/* nomore(MUSE_WAN_DEATH); */
991.  		if (!reflection_skip) {
992.  		    if(obj->otyp == WAN_DEATH && obj->spe > 0) {
993.  			m.offensive = obj;
994.  			m.has_offense = MUSE_WAN_DEATH;
995.  		    }
996.  		    nomore(MUSE_WAN_SLEEP);
997.  		    if(obj->otyp == WAN_SLEEP && obj->spe > 0 && multi >= 0) {
998.  			m.offensive = obj;
999.  			m.has_offense = MUSE_WAN_SLEEP;
1000. 		    }
1001. 		    nomore(MUSE_WAN_FIRE);
1002. 		    if(obj->otyp == WAN_FIRE && obj->spe > 0) {
1003. 			m.offensive = obj;
1004. 			m.has_offense = MUSE_WAN_FIRE;
1005. 		    }
1006. 		    nomore(MUSE_FIRE_HORN);
1007. 		    if(obj->otyp == FIRE_HORN && obj->spe > 0) {
1008. 			m.offensive = obj;
1009. 			m.has_offense = MUSE_FIRE_HORN;
1010. 		    }
1011. 		    nomore(MUSE_WAN_COLD);
1012. 		    if(obj->otyp == WAN_COLD && obj->spe > 0) {
1013. 			m.offensive = obj;
1014. 			m.has_offense = MUSE_WAN_COLD;
1015. 		    }
1016. 		    nomore(MUSE_FROST_HORN);
1017. 		    if(obj->otyp == FROST_HORN && obj->spe > 0) {
1018. 			m.offensive = obj;
1019. 			m.has_offense = MUSE_FROST_HORN;
1020. 		    }
1021. 		    nomore(MUSE_WAN_LIGHTNING);
1022. 		    if(obj->otyp == WAN_LIGHTNING && obj->spe > 0) {
1023. 			m.offensive = obj;
1024. 			m.has_offense = MUSE_WAN_LIGHTNING;
1025. 		    }
1026. 		    nomore(MUSE_WAN_MAGIC_MISSILE);
1027. 		    if(obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) {
1028. 			m.offensive = obj;
1029. 			m.has_offense = MUSE_WAN_MAGIC_MISSILE;
1030. 		    }
1031. 		}
1032. 		nomore(MUSE_WAN_STRIKING);
1033. 		if(obj->otyp == WAN_STRIKING && obj->spe > 0) {
1034. 			m.offensive = obj;
1035. 			m.has_offense = MUSE_WAN_STRIKING;
1036. 		}
1037. 		nomore(MUSE_POT_PARALYSIS);
1038. 		if(obj->otyp == POT_PARALYSIS && multi >= 0) {
1039. 			m.offensive = obj;
1040. 			m.has_offense = MUSE_POT_PARALYSIS;
1041. 		}
1042. 		nomore(MUSE_POT_BLINDNESS);
1043. 		if(obj->otyp == POT_BLINDNESS && !attacktype(mtmp->data, AT_GAZE)) {
1044. 			m.offensive = obj;
1045. 			m.has_offense = MUSE_POT_BLINDNESS;
1046. 		}
1047. 		nomore(MUSE_POT_CONFUSION);
1048. 		if(obj->otyp == POT_CONFUSION) {
1049. 			m.offensive = obj;
1050. 			m.has_offense = MUSE_POT_CONFUSION;
1051. 		}
1052. 		nomore(MUSE_POT_SLEEPING);
1053. 		if(obj->otyp == POT_SLEEPING) {
1054. 			m.offensive = obj;
1055. 			m.has_offense = MUSE_POT_SLEEPING;
1056. 		}
1057. 		nomore(MUSE_POT_ACID);
1058. 		if(obj->otyp == POT_ACID) {
1059. 			m.offensive = obj;
1060. 			m.has_offense = MUSE_POT_ACID;
1061. 		}
1062. 		/* we can safely put this scroll here since the locations that
1063. 		 * are in a 1 square radius are a subset of the locations that
1064. 		 * are in wand range
1065. 		 */
1066. 		nomore(MUSE_SCR_EARTH);
1067. 		if (obj->otyp == SCR_EARTH
1068. 		       && ((helmet && is_metallic(helmet)) ||
1069. 				mtmp->mconf || amorphous(mtmp->data) ||
1070. 				passes_walls(mtmp->data) ||
1071. 				noncorporeal(mtmp->data) ||
1072. 				unsolid(mtmp->data) || !rn2(10))
1073. 		       && dist2(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy) <= 2
1074. 		       && mtmp->mcansee && haseyes(mtmp->data)
1075. #ifdef REINCARNATION
1076. 		       && !Is_rogue_level(&u.uz)
1077. #endif
1078. 		       && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) {
1079. 		    m.offensive = obj;
1080. 		    m.has_offense = MUSE_SCR_EARTH;
1081. 		}
1082. #if 0
1083. 		nomore(MUSE_SCR_FIRE);
1084. 		if (obj->otyp == SCR_FIRE && resists_fire(mtmp)
1085. 		   && dist2(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy) <= 2
1086. 		   && mtmp->mcansee && haseyes(mtmp->data)) {
1087. 			m.offensive = obj;
1088. 			m.has_offense = MUSE_SCR_FIRE;
1089. 		}
1090. #endif
1091. 	}
1092. 	return((boolean)(!!m.has_offense));
1093. #undef nomore
1094. }
1095. 

mbhitm Edit

1096. STATIC_PTR
1097. int
1098. mbhitm(mtmp, otmp)
1099. register struct monst *mtmp;
1100. register struct obj *otmp;
1101. {
1102. 	int tmp;
1103. 
1104. 	boolean reveal_invis = FALSE;
1105. 	if (mtmp != &youmonst) {
1106. 		mtmp->msleeping = 0;
1107. 		if (mtmp->m_ap_type) seemimic(mtmp);
1108. 	}
1109. 	switch(otmp->otyp) {
1110. 	case WAN_STRIKING:
1111. 		reveal_invis = TRUE;
1112. 		if (mtmp == &youmonst) {
1113. 			if (zap_oseen) makeknown(WAN_STRIKING);
1114. 			if (Antimagic) {
1115. 			    shieldeff(u.ux, u.uy);
1116. 			    pline("Boing!");
1117. 			} else if (rnd(20) < 10 + u.uac) {
1118. 			    pline_The("wand hits you!");
1119. 			    tmp = d(2,12);
1120. 			    if(Half_spell_damage) tmp = (tmp+1) / 2;
1121. 			    losehp(tmp, "wand", KILLED_BY_AN);
1122. 			} else pline_The("wand misses you.");
1123. 			stop_occupation();
1124. 			nomul(0);
1125. 		} else if (resists_magm(mtmp)) {
1126. 			shieldeff(mtmp->mx, mtmp->my);
1127. 			pline("Boing!");
1128. 		} else if (rnd(20) < 10+find_mac(mtmp)) {
1129. 			tmp = d(2,12);
1130. 			hit("wand", mtmp, exclam(tmp));
1131. 			(void) resist(mtmp, otmp->oclass, tmp, TELL);
1132. 			if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
1133. 				makeknown(WAN_STRIKING);
1134. 		} else {
1135. 			miss("wand", mtmp);
1136. 			if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
1137. 				makeknown(WAN_STRIKING);
1138. 		}
1139. 		break;
1140. 	case WAN_TELEPORTATION:
1141. 		if (mtmp == &youmonst) {
1142. 			if (zap_oseen) makeknown(WAN_TELEPORTATION);
1143. 			tele();
1144. 		} else {
1145. 			/* for consistency with zap.c, don't identify */
1146. 			if (mtmp->ispriest &&
1147. 				*in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
1148. 			    if (cansee(mtmp->mx, mtmp->my))
1149. 				pline("%s resists the magic!", Monnam(mtmp));
1150. 			    mtmp->msleeping = 0;
1151. 			    if(mtmp->m_ap_type) seemimic(mtmp);
1152. 			} else if (!tele_restrict(mtmp))
1153. 			    (void) rloc(mtmp, FALSE);
1154. 		}
1155. 		break;
1156. 	case WAN_CANCELLATION:
1157. 	case SPE_CANCELLATION:
1158. 		(void) cancel_monst(mtmp, otmp, FALSE, TRUE, FALSE);
1159. 		break;
1160. 	}
1161. 	if (reveal_invis) {
1162. 	    if (mtmp->mhp > 0 && cansee(bhitpos.x,bhitpos.y)
1163. 							&& !canspotmon(mtmp))
1164. 		map_invisible(bhitpos.x, bhitpos.y);
1165. 	}
1166. 	return 0;
1167. }
1168. 

mbhit Edit

1169. /* A modified bhit() for monsters.  Based on bhit() in zap.c.  Unlike
1170.  * buzz(), bhit() doesn't take into account the possibility of a monster
1171.  * zapping you, so we need a special function for it.  (Unless someone wants
1172.  * to merge the two functions...)
1173.  */
1174. STATIC_OVL void
1175. mbhit(mon,range,fhitm,fhito,obj)
1176. struct monst *mon;			/* monster shooting the wand */
1177. register int range;			/* direction and range */
1178. int FDECL((*fhitm),(MONST_P,OBJ_P));
1179. int FDECL((*fhito),(OBJ_P,OBJ_P));	/* fns called when mon/obj hit */
1180. struct obj *obj;			/* 2nd arg to fhitm/fhito */
1181. {
1182. 	register struct monst *mtmp;
1183. 	register struct obj *otmp;
1184. 	register uchar typ;
1185. 	int ddx, ddy;
1186. 
1187. 	bhitpos.x = mon->mx;
1188. 	bhitpos.y = mon->my;
1189. 	ddx = sgn(mon->mux - mon->mx);
1190. 	ddy = sgn(mon->muy - mon->my);
1191. 
1192. 	while(range-- > 0) {
1193. 		int x,y;
1194. 
1195. 		bhitpos.x += ddx;
1196. 		bhitpos.y += ddy;
1197. 		x = bhitpos.x; y = bhitpos.y;
1198. 
1199. 		if (!isok(x,y)) {
1200. 		    bhitpos.x -= ddx;
1201. 		    bhitpos.y -= ddy;
1202. 		    break;
1203. 		}
1204. 		if (find_drawbridge(&x,&y))
1205. 		    switch (obj->otyp) {
1206. 			case WAN_STRIKING:
1207. 			    destroy_drawbridge(x,y);
1208. 		    }
1209. 		if(bhitpos.x==u.ux && bhitpos.y==u.uy) {
1210. 			(*fhitm)(&youmonst, obj);
1211. 			range -= 3;
1212. 		} else if(MON_AT(bhitpos.x, bhitpos.y)){
1213. 			mtmp = m_at(bhitpos.x,bhitpos.y);
1214. 			if (cansee(bhitpos.x,bhitpos.y) && !canspotmon(mtmp))
1215. 			    map_invisible(bhitpos.x, bhitpos.y);
1216. 			(*fhitm)(mtmp, obj);
1217. 			range -= 3;
1218. 		}
1219. 		/* modified by GAN to hit all objects */
1220. 		if(fhito){
1221. 		    int hitanything = 0;
1222. 		    register struct obj *next_obj;
1223. 
1224. 		    for(otmp = level.objects[bhitpos.x][bhitpos.y];
1225. 							otmp; otmp = next_obj) {
1226. 			/* Fix for polymorph bug, Tim Wright */
1227. 			next_obj = otmp->nexthere;
1228. 			hitanything += (*fhito)(otmp, obj);
1229. 		    }
1230. 		    if(hitanything)	range--;
1231. 		}
1232. 		typ = levl[bhitpos.x][bhitpos.y].typ;
1233. 		if(IS_DOOR(typ) || typ == SDOOR) {
1234. 		    switch (obj->otyp) {
1235. 			/* note: monsters don't use opening or locking magic
1236. 			   at present, but keep these as placeholders */
1237. 			case WAN_OPENING:
1238. 			case WAN_LOCKING:
1239. 			case WAN_STRIKING:
1240. 			    if (doorlock(obj, bhitpos.x, bhitpos.y)) {
1241. 				makeknown(obj->otyp);
1242. 				/* if a shop door gets broken, add it to
1243. 				   the shk's fix list (no cost to player) */
1244. 				if (levl[bhitpos.x][bhitpos.y].doormask ==
1245. 					D_BROKEN &&
1246. 				    *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE))
1247. 				    add_damage(bhitpos.x, bhitpos.y, 0L);
1248. 			    }
1249. 			    break;
1250. 		    }
1251. 		}
1252. 		if(!ZAP_POS(typ) || (IS_DOOR(typ) &&
1253. 		   (levl[bhitpos.x][bhitpos.y].doormask & (D_LOCKED | D_CLOSED)))
1254. 		  ) {
1255. 			bhitpos.x -= ddx;
1256. 			bhitpos.y -= ddy;
1257. 			break;
1258. 		}
1259. 	}
1260. }
1261. 

use_offensive Edit

1262. /* Perform an offensive action for a monster.  Must be called immediately
1263.  * after find_offensive().  Return values are same as use_defensive().
1264.  */
1265. int
1266. use_offensive(mtmp)
1267. struct monst *mtmp;
1268. {
1269. 	int i;
1270. 	struct obj *otmp = m.offensive;
1271. 	boolean oseen;
1272. 
1273. 	/* offensive potions are not drunk, they're thrown */
1274. 	if (otmp->oclass != POTION_CLASS && (i = precheck(mtmp, otmp)) != 0)
1275. 		return i;
1276. 	oseen = otmp && canseemon(mtmp);
1277. 
1278. 	switch(m.has_offense) {
1279. 	case MUSE_WAN_DEATH:
1280. 	case MUSE_WAN_SLEEP:
1281. 	case MUSE_WAN_FIRE:
1282. 	case MUSE_WAN_COLD:
1283. 	case MUSE_WAN_LIGHTNING:
1284. 	case MUSE_WAN_MAGIC_MISSILE:
1285. 		mzapmsg(mtmp, otmp, FALSE);
1286. 		otmp->spe--;
1287. 		if (oseen) makeknown(otmp->otyp);
1288. 		m_using = TRUE;
1289. 		buzz((int)(-30 - (otmp->otyp - WAN_MAGIC_MISSILE)),
1290. 			(otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6,
1291. 			mtmp->mx, mtmp->my,
1292. 			sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my));
1293. 		m_using = FALSE;
1294. 		return (mtmp->mhp <= 0) ? 1 : 2;
1295. 	case MUSE_FIRE_HORN:
1296. 	case MUSE_FROST_HORN:
1297. 		if (oseen) {
1298. 			makeknown(otmp->otyp);
1299. 			pline("%s plays a %s!", Monnam(mtmp), xname(otmp));
1300. 		} else
1301. 			You_hear("a horn being played.");
1302. 		otmp->spe--;
1303. 		m_using = TRUE;
1304. 		buzz(-30 - ((otmp->otyp==FROST_HORN) ? AD_COLD-1 : AD_FIRE-1),
1305. 			rn1(6,6), mtmp->mx, mtmp->my,
1306. 			sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my));
1307. 		m_using = FALSE;
1308. 		return (mtmp->mhp <= 0) ? 1 : 2;
1309. 	case MUSE_WAN_TELEPORTATION:
1310. 	case MUSE_WAN_STRIKING:
1311. 		zap_oseen = oseen;
1312. 		mzapmsg(mtmp, otmp, FALSE);
1313. 		otmp->spe--;
1314. 		m_using = TRUE;
1315. 		mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp);
1316. 		m_using = FALSE;
1317. 		return 2;
1318. 	case MUSE_SCR_EARTH:
1319. 	    {
1320. 		/* TODO: handle steeds */
1321. 	    	register int x, y;
1322. 		/* don't use monster fields after killing it */
1323. 		boolean confused = (mtmp->mconf ? TRUE : FALSE);
1324. 		int mmx = mtmp->mx, mmy = mtmp->my;
1325. 
1326. 		mreadmsg(mtmp, otmp);
1327. 	    	/* Identify the scroll */
1328. 		if (canspotmon(mtmp)) {
1329. 		    pline_The("%s rumbles %s %s!", ceiling(mtmp->mx, mtmp->my),
1330. 	    			otmp->blessed ? "around" : "above",
1331. 				mon_nam(mtmp));
1332. 		    if (oseen) makeknown(otmp->otyp);
1333. 		} else if (cansee(mtmp->mx, mtmp->my)) {
1334. 		    pline_The("%s rumbles in the middle of nowhere!",
1335. 			ceiling(mtmp->mx, mtmp->my));
1336. 		    if (mtmp->minvis)
1337. 			map_invisible(mtmp->mx, mtmp->my);
1338. 		    if (oseen) makeknown(otmp->otyp);
1339. 		}
1340. 
1341. 	    	/* Loop through the surrounding squares */
1342. 	    	for (x = mmx-1; x <= mmx+1; x++) {
1343. 	    	    for (y = mmy-1; y <= mmy+1; y++) {
1344. 	    	    	/* Is this a suitable spot? */
1345. 	    	    	if (isok(x, y) && !closed_door(x, y) &&
1346. 	    	    			!IS_ROCK(levl[x][y].typ) &&
1347. 	    	    			!IS_AIR(levl[x][y].typ) &&
1348. 	    	    			(((x == mmx) && (y == mmy)) ?
1349. 	    	    			    !otmp->blessed : !otmp->cursed) &&
1350. 					(x != u.ux || y != u.uy)) {
1351. 			    register struct obj *otmp2;
1352. 			    register struct monst *mtmp2;
1353. 
1354. 	    	    	    /* Make the object(s) */
1355. 	    	    	    otmp2 = mksobj(confused ? ROCK : BOULDER,
1356. 	    	    	    		FALSE, FALSE);
1357. 	    	    	    if (!otmp2) continue;  /* Shouldn't happen */
1358. 	    	    	    otmp2->quan = confused ? rn1(5,2) : 1;
1359. 	    	    	    otmp2->owt = weight(otmp2);
1360. 
1361. 	    	    	    /* Find the monster here (might be same as mtmp) */
1362. 	    	    	    mtmp2 = m_at(x, y);
1363. 	    	    	    if (mtmp2 && !amorphous(mtmp2->data) &&
1364. 	    	    	    		!passes_walls(mtmp2->data) &&
1365. 	    	    	    		!noncorporeal(mtmp2->data) &&
1366. 	    	    	    		!unsolid(mtmp2->data)) {
1367. 				struct obj *helmet = which_armor(mtmp2, W_ARMH);
1368. 				int mdmg;
1369. 
1370. 				if (cansee(mtmp2->mx, mtmp2->my)) {
1371. 				    pline("%s is hit by %s!", Monnam(mtmp2),
1372. 	    	    	    			doname(otmp2));
1373. 				    if (mtmp2->minvis && !canspotmon(mtmp2))
1374. 					map_invisible(mtmp2->mx, mtmp2->my);
1375. 				}
1376. 	    	    	    	mdmg = dmgval(otmp2, mtmp2) * otmp2->quan;
1377. 				if (helmet) {
1378. 				    if(is_metallic(helmet)) {
1379. 					if (canspotmon(mtmp2))
1380. 					    pline("Fortunately, %s is wearing a hard helmet.", mon_nam(mtmp2));
1381. 					else if (flags.soundok)
1382. 					    You_hear("a clanging sound.");
1383. 					if (mdmg > 2) mdmg = 2;
1384. 				    } else {
1385. 					if (canspotmon(mtmp2))
1386. 					    pline("%s's %s does not protect %s.",
1387. 						Monnam(mtmp2), xname(helmet),
1388. 						mhim(mtmp2));
1389. 				    }
1390. 				}
1391. 	    	    	    	mtmp2->mhp -= mdmg;
1392. 	    	    	    	if (mtmp2->mhp <= 0) {
1393. 				    pline("%s is killed.", Monnam(mtmp2));
1394. 	    	    	    	    mondied(mtmp2);
1395. 				}
1396. 	    	    	    }
1397. 	    	    	    /* Drop the rock/boulder to the floor */
1398. 	    	    	    if (!flooreffects(otmp2, x, y, "fall")) {
1399. 	    	    	    	place_object(otmp2, x, y);
1400. 	    	    	    	stackobj(otmp2);
1401. 	    	    	    	newsym(x, y);  /* map the rock */
1402. 	    	    	    }
1403. 	    	    	}
1404. 		    }
1405. 		}
1406. 		m_useup(mtmp, otmp);
1407. 		/* Attack the player */
1408. 		if (distmin(mmx, mmy, u.ux, u.uy) == 1 && !otmp->cursed) {
1409. 		    int dmg;
1410. 		    struct obj *otmp2;
1411. 
1412. 		    /* Okay, _you_ write this without repeating the code */
1413. 		    otmp2 = mksobj(confused ? ROCK : BOULDER,
1414. 				FALSE, FALSE);
1415. 		    if (!otmp2) goto xxx_noobj;  /* Shouldn't happen */
1416. 		    otmp2->quan = confused ? rn1(5,2) : 1;
1417. 		    otmp2->owt = weight(otmp2);
1418. 		    if (!amorphous(youmonst.data) &&
1419. 			    !Passes_walls &&
1420. 			    !noncorporeal(youmonst.data) &&
1421. 			    !unsolid(youmonst.data)) {
1422. 			You("are hit by %s!", doname(otmp2));
1423. 			dmg = dmgval(otmp2, &youmonst) * otmp2->quan;
1424. 			if (uarmh) {
1425. 			    if(is_metallic(uarmh)) {
1426. 				pline("Fortunately, you are wearing a hard helmet.");
1427. 				if (dmg > 2) dmg = 2;
1428. 			    } else if (flags.verbose) {
1429. 				Your("%s does not protect you.",
1430. 						xname(uarmh));
1431. 			    }
1432. 			}
1433. 		    } else
1434. 			dmg = 0;
1435. 		    if (!flooreffects(otmp2, u.ux, u.uy, "fall")) {
1436. 			place_object(otmp2, u.ux, u.uy);
1437. 			stackobj(otmp2);
1438. 			newsym(u.ux, u.uy);
1439. 		    }
1440. 		    if (dmg) losehp(dmg, "scroll of earth", KILLED_BY_AN);
1441. 		}
1442. 	    xxx_noobj:
1443. 
1444. 		return (mtmp->mhp <= 0) ? 1 : 2;
1445. 	    }
1446. #if 0
1447. 	case MUSE_SCR_FIRE:
1448. 	      {
1449. 		boolean vis = cansee(mtmp->mx, mtmp->my);
1450. 
1451. 		mreadmsg(mtmp, otmp);
1452. 		if (mtmp->mconf) {
1453. 			if (vis)
1454. 			    pline("Oh, what a pretty fire!");
1455. 		} else {
1456. 			struct monst *mtmp2;
1457. 			int num;
1458. 
1459. 			if (vis)
1460. 			    pline_The("scroll erupts in a tower of flame!");
1461. 			shieldeff(mtmp->mx, mtmp->my);
1462. 			pline("%s is uninjured.", Monnam(mtmp));
1463. 			(void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
1464. 			(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
1465. 			(void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
1466. 			num = (2*(rn1(3, 3) + 2 * bcsign(otmp)) + 1)/3;
1467. 			if (Fire_resistance)
1468. 			    You("are not harmed.");
1469. 			burn_away_slime();
1470. 			if (Half_spell_damage) num = (num+1) / 2;
1471. 			else losehp(num, "scroll of fire", KILLED_BY_AN);
1472. 			for(mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) {
1473. 			   if(DEADMONSTER(mtmp2)) continue;
1474. 			   if(mtmp == mtmp2) continue;
1475. 			   if(dist2(mtmp2->mx,mtmp2->my,mtmp->mx,mtmp->my) < 3){
1476. 				if (resists_fire(mtmp2)) continue;
1477. 				mtmp2->mhp -= num;
1478. 				if (resists_cold(mtmp2))
1479. 				    mtmp2->mhp -= 3*num;
1480. 				if(mtmp2->mhp < 1) {
1481. 				    mondied(mtmp2);
1482. 				    break;
1483. 				}
1484. 			    }
1485. 			}
1486. 		}
1487. 		return 2;
1488. 	      }
1489. #endif	/* 0 */
1490. 	case MUSE_POT_PARALYSIS:
1491. 	case MUSE_POT_BLINDNESS:
1492. 	case MUSE_POT_CONFUSION:
1493. 	case MUSE_POT_SLEEPING:
1494. 	case MUSE_POT_ACID:
1495. 		/* Note: this setting of dknown doesn't suffice.  A monster
1496. 		 * which is out of sight might throw and it hits something _in_
1497. 		 * sight, a problem not existing with wands because wand rays
1498. 		 * are not objects.  Also set dknown in mthrowu.c.
1499. 		 */
1500. 		if (cansee(mtmp->mx, mtmp->my)) {
1501. 			otmp->dknown = 1;
1502. 			pline("%s hurls %s!", Monnam(mtmp),
1503. 						singular(otmp, doname));
1504. 		}
1505. 		m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux-mtmp->mx),
1506. 			sgn(mtmp->muy-mtmp->my),
1507. 			distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy), otmp);
1508. 		return 2;
1509. 	case 0: return 0; /* i.e. an exploded wand */
1510. 	default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
1511. 			m.has_offense);
1512. 		break;
1513. 	}
1514. 	return 0;
1515. }
1516. 

rnd_offensive_item Edit

1517. int
1518. rnd_offensive_item(mtmp)
1519. struct monst *mtmp;
1520. {
1521. 	struct permonst *pm = mtmp->data;
1522. 	int difficulty = monstr[(monsndx(pm))];
1523. 
1524. 	if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1525. 			|| pm->mlet == S_GHOST
1526. # ifdef KOPS
1527. 			|| pm->mlet == S_KOP
1528. # endif
1529. 		) return 0;
1530. 	if (difficulty > 7 && !rn2(35)) return WAN_DEATH;
1531. 	switch (rn2(9 - (difficulty < 4) + 4 * (difficulty > 6))) {
1532. 		case 0: {
1533. 		    struct obj *helmet = which_armor(mtmp, W_ARMH);
1534. 
1535. 		    if ((helmet && is_metallic(helmet)) || amorphous(pm) || passes_walls(pm) || noncorporeal(pm) || unsolid(pm))
1536. 			return SCR_EARTH;
1537. 		} /* fall through */
1538. 		case 1: return WAN_STRIKING;
1539. 		case 2: return POT_ACID;
1540. 		case 3: return POT_CONFUSION;
1541. 		case 4: return POT_BLINDNESS;
1542. 		case 5: return POT_SLEEPING;
1543. 		case 6: return POT_PARALYSIS;
1544. 		case 7: case 8:
1545. 			return WAN_MAGIC_MISSILE;
1546. 		case 9: return WAN_SLEEP;
1547. 		case 10: return WAN_FIRE;
1548. 		case 11: return WAN_COLD;
1549. 		case 12: return WAN_LIGHTNING;
1550. 	}
1551. 	/*NOTREACHED*/
1552. 	return 0;
1553. }
1554. 
1555. #define MUSE_POT_GAIN_LEVEL 1
1556. #define MUSE_WAN_MAKE_INVISIBLE 2
1557. #define MUSE_POT_INVISIBILITY 3
1558. #define MUSE_POLY_TRAP 4
1559. #define MUSE_WAN_POLYMORPH 5
1560. #define MUSE_POT_SPEED 6
1561. #define MUSE_WAN_SPEED_MONSTER 7
1562. #define MUSE_BULLWHIP 8
1563. #define MUSE_POT_POLYMORPH 9
1564. 

find_misc Edit

1565. boolean
1566. find_misc(mtmp)
1567. struct monst *mtmp;
1568. {
1569. 	register struct obj *obj;
1570. 	struct permonst *mdat = mtmp->data;
1571. 	int x = mtmp->mx, y = mtmp->my;
1572. 	struct trap *t;
1573. 	int xx, yy;
1574. 	boolean immobile = (mdat->mmove == 0);
1575. 	boolean stuck = (mtmp == u.ustuck);
1576. 
1577. 	m.misc = (struct obj *)0;
1578. 	m.has_misc = 0;
1579. 	if (is_animal(mdat) || mindless(mdat))
1580. 		return 0;
1581. 	if (u.uswallow && stuck) return FALSE;
1582. 
1583. 	/* We arbitrarily limit to times when a player is nearby for the
1584. 	 * same reason as Junior Pac-Man doesn't have energizers eaten until
1585. 	 * you can see them...
1586. 	 */
1587. 	if(dist2(x, y, mtmp->mux, mtmp->muy) > 36)
1588. 		return FALSE;
1589. 
1590. 	if (!stuck && !immobile && !mtmp->cham && monstr[monsndx(mdat)] < 6) {
1591. 	  boolean ignore_boulders = (verysmall(mdat) ||
1592. 				     throws_rocks(mdat) ||
1593. 				     passes_walls(mdat));
1594. 	  for(xx = x-1; xx <= x+1; xx++)
1595. 	    for(yy = y-1; yy <= y+1; yy++)
1596. 		if (isok(xx,yy) && (xx != u.ux || yy != u.uy))
1597. 		    if (mdat != &mons[PM_GRID_BUG] || xx == x || yy == y)
1598. 			if (/* (xx==x && yy==y) || */ !level.monsters[xx][yy])
1599. 			    if ((t = t_at(xx, yy)) != 0 &&
1600. 			      (ignore_boulders || !sobj_at(BOULDER, xx, yy))
1601. 			      && !onscary(xx, yy, mtmp)) {
1602. 				if (t->ttyp == POLY_TRAP) {
1603. 				    trapx = xx;
1604. 				    trapy = yy;
1605. 				    m.has_misc = MUSE_POLY_TRAP;
1606. 				    return TRUE;
1607. 				}
1608. 			    }
1609. 	}
1610. 	if (nohands(mdat))
1611. 		return 0;
1612. 
1613. #define nomore(x) if(m.has_misc==x) continue;
1614. 	for(obj=mtmp->minvent; obj; obj=obj->nobj) {
1615. 		/* Monsters shouldn't recognize cursed items; this kludge is */
1616. 		/* necessary to prevent serious problems though... */
1617. 		if(obj->otyp == POT_GAIN_LEVEL && (!obj->cursed ||
1618. 			    (!mtmp->isgd && !mtmp->isshk && !mtmp->ispriest))) {
1619. 			m.misc = obj;
1620. 			m.has_misc = MUSE_POT_GAIN_LEVEL;
1621. 		}
1622. 		nomore(MUSE_BULLWHIP);
1623. 		if(obj->otyp == BULLWHIP && (MON_WEP(mtmp) == obj) &&
1624. 		   distu(mtmp->mx,mtmp->my)==1 && uwep && !mtmp->mpeaceful) {
1625. 			m.misc = obj;
1626. 			m.has_misc = MUSE_BULLWHIP;
1627. 		}
1628. 		/* Note: peaceful/tame monsters won't make themselves
1629. 		 * invisible unless you can see them.  Not really right, but...
1630. 		 */
1631. 		nomore(MUSE_WAN_MAKE_INVISIBLE);
1632. 		if(obj->otyp == WAN_MAKE_INVISIBLE && obj->spe > 0 &&
1633. 		    !mtmp->minvis && !mtmp->invis_blkd &&
1634. 		    (!mtmp->mpeaceful || See_invisible) &&
1635. 		    (!attacktype(mtmp->data, AT_GAZE) || mtmp->mcan)) {
1636. 			m.misc = obj;
1637. 			m.has_misc = MUSE_WAN_MAKE_INVISIBLE;
1638. 		}
1639. 		nomore(MUSE_POT_INVISIBILITY);
1640. 		if(obj->otyp == POT_INVISIBILITY &&
1641. 		    !mtmp->minvis && !mtmp->invis_blkd &&
1642. 		    (!mtmp->mpeaceful || See_invisible) &&
1643. 		    (!attacktype(mtmp->data, AT_GAZE) || mtmp->mcan)) {
1644. 			m.misc = obj;
1645. 			m.has_misc = MUSE_POT_INVISIBILITY;
1646. 		}
1647. 		nomore(MUSE_WAN_SPEED_MONSTER);
1648. 		if(obj->otyp == WAN_SPEED_MONSTER && obj->spe > 0
1649. 				&& mtmp->mspeed != MFAST && !mtmp->isgd) {
1650. 			m.misc = obj;
1651. 			m.has_misc = MUSE_WAN_SPEED_MONSTER;
1652. 		}
1653. 		nomore(MUSE_POT_SPEED);
1654. 		if(obj->otyp == POT_SPEED && mtmp->mspeed != MFAST
1655. 							&& !mtmp->isgd) {
1656. 			m.misc = obj;
1657. 			m.has_misc = MUSE_POT_SPEED;
1658. 		}
1659. 		nomore(MUSE_WAN_POLYMORPH);
1660. 		if(obj->otyp == WAN_POLYMORPH && obj->spe > 0 && !mtmp->cham
1661. 				&& monstr[monsndx(mdat)] < 6) {
1662. 			m.misc = obj;
1663. 			m.has_misc = MUSE_WAN_POLYMORPH;
1664. 		}
1665. 		nomore(MUSE_POT_POLYMORPH);
1666. 		if(obj->otyp == POT_POLYMORPH && !mtmp->cham
1667. 				&& monstr[monsndx(mdat)] < 6) {
1668. 			m.misc = obj;
1669. 			m.has_misc = MUSE_POT_POLYMORPH;
1670. 		}
1671. 	}
1672. 	return((boolean)(!!m.has_misc));
1673. #undef nomore
1674. }
1675. 

muse_newcham_mon Edit

1676. /* type of monster to polymorph into; defaults to one suitable for the
1677.    current level rather than the totally arbitrary choice of newcham() */
1678. static struct permonst *
1679. muse_newcham_mon(mon)
1680. struct monst *mon;
1681. {
1682. 	struct obj *m_armr;
1683. 
1684. 	if ((m_armr = which_armor(mon, W_ARM)) != 0) {
1685. 	    if (Is_dragon_scales(m_armr))
1686. 		return Dragon_scales_to_pm(m_armr);
1687. 	    else if (Is_dragon_mail(m_armr))
1688. 		return Dragon_mail_to_pm(m_armr);
1689. 	}
1690. 	return rndmonst();
1691. }
1692. 

use_misc Edit

1693. int
1694. use_misc(mtmp)
1695. struct monst *mtmp;
1696. {
1697. 	int i;
1698. 	struct obj *otmp = m.misc;
1699. 	boolean vis, vismon, oseen;
1700. 	char nambuf[BUFSZ];
1701. 
1702. 	if ((i = precheck(mtmp, otmp)) != 0) return i;
1703. 	vis = cansee(mtmp->mx, mtmp->my);
1704. 	vismon = canseemon(mtmp);
1705. 	oseen = otmp && vismon;
1706. 
1707. 	switch(m.has_misc) {
1708. 	case MUSE_POT_GAIN_LEVEL:
1709. 		mquaffmsg(mtmp, otmp);
1710. 		if (otmp->cursed) {
1711. 		    if (Can_rise_up(mtmp->mx, mtmp->my, &u.uz)) {
1712. 			register int tolev = depth(&u.uz)-1;
1713. 			d_level tolevel;
1714. 
1715. 			get_level(&tolevel, tolev);
1716. 			/* insurance against future changes... */
1717. 			if(on_level(&tolevel, &u.uz)) goto skipmsg;
1718. 			if (vismon) {
1719. 			    pline("%s rises up, through the %s!",
1720. 				  Monnam(mtmp), ceiling(mtmp->mx, mtmp->my));
1721. 			    if(!objects[POT_GAIN_LEVEL].oc_name_known
1722. 			      && !objects[POT_GAIN_LEVEL].oc_uname)
1723. 				docall(otmp);
1724. 			}
1725. 			m_useup(mtmp, otmp);
1726. 			migrate_to_level(mtmp, ledger_no(&tolevel),
1727. 					 MIGR_RANDOM, (coord *)0);
1728. 			return 2;
1729. 		    } else {
1730. skipmsg:
1731. 			if (vismon) {
1732. 			    pline("%s looks uneasy.", Monnam(mtmp));
1733. 			    if(!objects[POT_GAIN_LEVEL].oc_name_known
1734. 			      && !objects[POT_GAIN_LEVEL].oc_uname)
1735. 				docall(otmp);
1736. 			}
1737. 			m_useup(mtmp, otmp);
1738. 			return 2;
1739. 		    }
1740. 		}
1741. 		if (vismon) pline("%s seems more experienced.", Monnam(mtmp));
1742. 		if (oseen) makeknown(POT_GAIN_LEVEL);
1743. 		m_useup(mtmp, otmp);
1744. 		if (!grow_up(mtmp,(struct monst *)0)) return 1;
1745. 			/* grew into genocided monster */
1746. 		return 2;
1747. 	case MUSE_WAN_MAKE_INVISIBLE:
1748. 	case MUSE_POT_INVISIBILITY:
1749. 		if (otmp->otyp == WAN_MAKE_INVISIBLE) {
1750. 		    mzapmsg(mtmp, otmp, TRUE);
1751. 		    otmp->spe--;
1752. 		} else
1753. 		    mquaffmsg(mtmp, otmp);
1754. 		/* format monster's name before altering its visibility */
1755. 		Strcpy(nambuf, See_invisible ? Monnam(mtmp) : mon_nam(mtmp));
1756. 		mon_set_minvis(mtmp);
1757. 		if (vismon && mtmp->minvis) {	/* was seen, now invisible */
1758. 		    if (See_invisible)
1759. 			pline("%s body takes on a %s transparency.",
1760. 			      s_suffix(nambuf),
1761. 			      Hallucination ? "normal" : "strange");
1762. 		    else
1763. 			pline("Suddenly you cannot see %s.", nambuf);
1764. 		    if (oseen) makeknown(otmp->otyp);
1765. 		}
1766. 		if (otmp->otyp == POT_INVISIBILITY) {
1767. 		    if (otmp->cursed) you_aggravate(mtmp);
1768. 		    m_useup(mtmp, otmp);
1769. 		}
1770. 		return 2;
1771. 	case MUSE_WAN_SPEED_MONSTER:
1772. 		mzapmsg(mtmp, otmp, TRUE);
1773. 		otmp->spe--;
1774. 		mon_adjust_speed(mtmp, 1, otmp);
1775. 		return 2;
1776. 	case MUSE_POT_SPEED:
1777. 		mquaffmsg(mtmp, otmp);
1778. 		/* note difference in potion effect due to substantially
1779. 		   different methods of maintaining speed ratings:
1780. 		   player's character becomes "very fast" temporarily;
1781. 		   monster becomes "one stage faster" permanently */
1782. 		mon_adjust_speed(mtmp, 1, otmp);
1783. 		m_useup(mtmp, otmp);
1784. 		return 2;
1785. 	case MUSE_WAN_POLYMORPH:
1786. 		mzapmsg(mtmp, otmp, TRUE);
1787. 		otmp->spe--;
1788. 		(void) newcham(mtmp, muse_newcham_mon(mtmp), TRUE, FALSE);
1789. 		if (oseen) makeknown(WAN_POLYMORPH);
1790. 		return 2;
1791. 	case MUSE_POT_POLYMORPH:
1792. 		mquaffmsg(mtmp, otmp);
1793. 		if (vismon) pline("%s suddenly mutates!", Monnam(mtmp));
1794. 		(void) newcham(mtmp, muse_newcham_mon(mtmp), FALSE, FALSE);
1795. 		if (oseen) makeknown(POT_POLYMORPH);
1796. 		m_useup(mtmp, otmp);
1797. 		return 2;
1798. 	case MUSE_POLY_TRAP:
1799. 		if (vismon)
1800. 		    pline("%s deliberately %s onto a polymorph trap!",
1801. 			Monnam(mtmp),
1802. 			makeplural(locomotion(mtmp->data, "jump")));
1803. 		if (vis) seetrap(t_at(trapx,trapy));
1804. 
1805. 		/*  don't use rloc() due to worms */
1806. 		remove_monster(mtmp->mx, mtmp->my);
1807. 		newsym(mtmp->mx, mtmp->my);
1808. 		place_monster(mtmp, trapx, trapy);
1809. 		if (mtmp->wormno) worm_move(mtmp);
1810. 		newsym(trapx, trapy);
1811. 
1812. 		(void) newcham(mtmp, (struct permonst *)0, FALSE, FALSE);
1813. 		return 2;
1814. 	case MUSE_BULLWHIP:
1815. 		/* attempt to disarm hero */
1816. 		if (uwep && !rn2(5)) {
1817. 		    const char *The_whip = vismon ? "The bullwhip" : "A whip";
1818. 		    int where_to = rn2(4);
1819. 		    struct obj *obj = uwep;
1820. 		    const char *hand;
1821. 		    char the_weapon[BUFSZ];
1822. 
1823. 		    Strcpy(the_weapon, the(xname(obj)));
1824. 		    hand = body_part(HAND);
1825. 		    if (bimanual(obj)) hand = makeplural(hand);
1826. 
1827. 		    if (vismon)
1828. 			pline("%s flicks a bullwhip towards your %s!",
1829. 			      Monnam(mtmp), hand);
1830. 		    if (obj->otyp == HEAVY_IRON_BALL) {
1831. 			pline("%s fails to wrap around %s.",
1832. 			      The_whip, the_weapon);
1833. 			return 1;
1834. 		    }
1835. 		    pline("%s wraps around %s you're wielding!",
1836. 			  The_whip, the_weapon);
1837. 		    if (welded(obj)) {
1838. 			pline("%s welded to your %s%c",
1839. 			      !is_plural(obj) ? "It is" : "They are",
1840. 			      hand, !obj->bknown ? '!' : '.');
1841. 			/* obj->bknown = 1; */ /* welded() takes care of this */
1842. 			where_to = 0;
1843. 		    }
1844. 		    if (!where_to) {
1845. 			pline_The("whip slips free.");  /* not `The_whip' */
1846. 			return 1;
1847. 		    } else if (where_to == 3 && hates_silver(mtmp->data) &&
1848. 			    objects[obj->otyp].oc_material == SILVER) {
1849. 			/* this monster won't want to catch a silver
1850. 			   weapon; drop it at hero's feet instead */
1851. 			where_to = 2;
1852. 		    }
1853. 		    freeinv(obj);
1854. 		    uwepgone();
1855. 		    switch (where_to) {
1856. 			case 1:		/* onto floor beneath mon */
1857. 			    pline("%s yanks %s from your %s!", Monnam(mtmp),
1858. 				  the_weapon, hand);
1859. 			    place_object(obj, mtmp->mx, mtmp->my);
1860. 			    break;
1861. 			case 2:		/* onto floor beneath you */
1862. 			    pline("%s yanks %s to the %s!", Monnam(mtmp),
1863. 				  the_weapon, surface(u.ux, u.uy));
1864. 			    dropy(obj);
1865. 			    break;
1866. 			case 3:		/* into mon's inventory */
1867. 			    pline("%s snatches %s!", Monnam(mtmp),
1868. 				  the_weapon);
1869. 			    (void) mpickobj(mtmp,obj);
1870. 			    break;
1871. 		    }
1872. 		    return 1;
1873. 		}
1874. 		return 0;
1875. 	case 0: return 0; /* i.e. an exploded wand */
1876. 	default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
1877. 			m.has_misc);
1878. 		break;
1879. 	}
1880. 	return 0;
1881. }
1882. 

you_aggravate Edit

1883. STATIC_OVL void
1884. you_aggravate(mtmp)
1885. struct monst *mtmp;
1886. {
1887. 	pline("For some reason, %s presence is known to you.",
1888. 		s_suffix(noit_mon_nam(mtmp)));
1889. 	cls();
1890. #ifdef CLIPPING
1891. 	cliparound(mtmp->mx, mtmp->my);
1892. #endif
1893. 	show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp));
1894. 	display_self();
1895. 	You_feel("aggravated at %s.", noit_mon_nam(mtmp));
1896. 	display_nhwindow(WIN_MAP, TRUE);
1897. 	docrt();
1898. 	if (unconscious()) {
1899. 		multi = -1;
1900. 		nomovemsg =
1901. 		      "Aggravated, you are jolted into full consciousness.";
1902. 	}
1903. 	newsym(mtmp->mx,mtmp->my);
1904. 	if (!canspotmon(mtmp))
1905. 	    map_invisible(mtmp->mx, mtmp->my);
1906. }
1907. 

rnd_misc_item Edit

1908. int
1909. rnd_misc_item(mtmp)
1910. struct monst *mtmp;
1911. {
1912. 	struct permonst *pm = mtmp->data;
1913. 	int difficulty = monstr[(monsndx(pm))];
1914. 
1915. 	if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1916. 			|| pm->mlet == S_GHOST
1917. # ifdef KOPS
1918. 			|| pm->mlet == S_KOP
1919. # endif
1920. 		) return 0;
1921. 	/* Unlike other rnd_item functions, we only allow _weak_ monsters
1922. 	 * to have this item; after all, the item will be used to strengthen
1923. 	 * the monster and strong monsters won't use it at all...
1924. 	 */
1925. 	if (difficulty < 6 && !rn2(30))
1926. 	    return rn2(6) ? POT_POLYMORPH : WAN_POLYMORPH;
1927. 
1928. 	if (!rn2(40) && !nonliving(pm)) return AMULET_OF_LIFE_SAVING;
1929. 
1930. 	switch (rn2(3)) {
1931. 		case 0:
1932. 			if (mtmp->isgd) return 0;
1933. 			return rn2(6) ? POT_SPEED : WAN_SPEED_MONSTER;
1934. 		case 1:
1935. 			if (mtmp->mpeaceful && !See_invisible) return 0;
1936. 			return rn2(6) ? POT_INVISIBILITY : WAN_MAKE_INVISIBLE;
1937. 		case 2:
1938. 			return POT_GAIN_LEVEL;
1939. 	}
1940. 	/*NOTREACHED*/
1941. 	return 0;
1942. }
1943. 

searches_for_item Edit

1944. boolean
1945. searches_for_item(mon, obj)
1946. struct monst *mon;
1947. struct obj *obj;
1948. {
1949. 	int typ = obj->otyp;
1950. 
1951. 	if (is_animal(mon->data) ||
1952. 		mindless(mon->data) ||
1953. 		mon->data == &mons[PM_GHOST])	/* don't loot bones piles */
1954. 	    return FALSE;
1955. 
1956. 	if (typ == WAN_MAKE_INVISIBLE || typ == POT_INVISIBILITY)
1957. 	    return (boolean)(!mon->minvis && !mon->invis_blkd && !attacktype(mon->data, AT_GAZE));
1958. 	if (typ == WAN_SPEED_MONSTER || typ == POT_SPEED)
1959. 	    return (boolean)(mon->mspeed != MFAST);
1960. 
1961. 	switch (obj->oclass) {
1962. 	case WAND_CLASS:
1963. 	    if (obj->spe <= 0)
1964. 		return FALSE;
1965. 	    if (typ == WAN_DIGGING)
1966. 		return (boolean)(!is_floater(mon->data));
1967. 	    if (typ == WAN_POLYMORPH)
1968. 		return (boolean)(monstr[monsndx(mon->data)] < 6);
1969. 	    if (objects[typ].oc_dir == RAY ||
1970. 		    typ == WAN_STRIKING ||
1971. 		    typ == WAN_TELEPORTATION ||
1972. 		    typ == WAN_CREATE_MONSTER)
1973. 		return TRUE;
1974. 	    break;
1975. 	case POTION_CLASS:
1976. 	    if (typ == POT_HEALING ||
1977. 		    typ == POT_EXTRA_HEALING ||
1978. 		    typ == POT_FULL_HEALING ||
1979. 		    typ == POT_POLYMORPH ||
1980. 		    typ == POT_GAIN_LEVEL ||
1981. 		    typ == POT_PARALYSIS ||
1982. 		    typ == POT_SLEEPING ||
1983. 		    typ == POT_ACID ||
1984. 		    typ == POT_CONFUSION)
1985. 		return TRUE;
1986. 	    if (typ == POT_BLINDNESS && !attacktype(mon->data, AT_GAZE))
1987. 		return TRUE;
1988. 	    break;
1989. 	case SCROLL_CLASS:
1990. 	    if (typ == SCR_TELEPORTATION || typ == SCR_CREATE_MONSTER
1991. 		    || typ == SCR_EARTH)
1992. 		return TRUE;
1993. 	    break;
1994. 	case AMULET_CLASS:
1995. 	    if (typ == AMULET_OF_LIFE_SAVING)
1996. 		return (boolean)(!nonliving(mon->data));
1997. 	    if (typ == AMULET_OF_REFLECTION)
1998. 		return TRUE;
1999. 	    break;
2000. 	case TOOL_CLASS:
2001. 	    if (typ == PICK_AXE)
2002. 		return (boolean)needspick(mon->data);
2003. 	    if (typ == UNICORN_HORN)
2004. 		return (boolean)(!obj->cursed && !is_unicorn(mon->data));
2005. 	    if (typ == FROST_HORN || typ == FIRE_HORN)
2006. 		return (obj->spe > 0);
2007. 	    break;
2008. 	case FOOD_CLASS:
2009. 	    if (typ == CORPSE)
2010. 		return (boolean)(((mon->misc_worn_check & W_ARMG) &&
2011. 				    touch_petrifies(&mons[obj->corpsenm])) ||
2012. 				(!resists_ston(mon) &&
2013. 				    (obj->corpsenm == PM_LIZARD ||
2014. 					(acidic(&mons[obj->corpsenm]) &&
2015. 					 obj->corpsenm != PM_GREEN_SLIME))));
2016. 	    if (typ == EGG)
2017. 		return (boolean)(touch_petrifies(&mons[obj->corpsenm]));
2018. 	    break;
2019. 	default:
2020. 	    break;
2021. 	}
2022. 
2023. 	return FALSE;
2024. }
2025. 

mon_reflects Edit

2026. boolean
2027. mon_reflects(mon,str)
2028. struct monst *mon;
2029. const char *str;
2030. {
2031. 	struct obj *orefl = which_armor(mon, W_ARMS);
2032. 
2033. 	if (orefl && orefl->otyp == SHIELD_OF_REFLECTION) {
2034. 	    if (str) {
2035. 		pline(str, s_suffix(mon_nam(mon)), "shield");
2036. 		makeknown(SHIELD_OF_REFLECTION);
2037. 	    }
2038. 	    return TRUE;
2039. 	} else if (arti_reflects(MON_WEP(mon))) {
2040. 	    /* due to wielded artifact weapon */
2041. 	    if (str)
2042. 		pline(str, s_suffix(mon_nam(mon)), "weapon");
2043. 	    return TRUE;
2044. 	} else if ((orefl = which_armor(mon, W_AMUL)) &&
2045. 				orefl->otyp == AMULET_OF_REFLECTION) {
2046. 	    if (str) {
2047. 		pline(str, s_suffix(mon_nam(mon)), "amulet");
2048. 		makeknown(AMULET_OF_REFLECTION);
2049. 	    }
2050. 	    return TRUE;
2051. 	} else if ((orefl = which_armor(mon, W_ARM)) &&
2052. 		(orefl->otyp == SILVER_DRAGON_SCALES || orefl->otyp == SILVER_DRAGON_SCALE_MAIL)) {
2053. 	    if (str)
2054. 		pline(str, s_suffix(mon_nam(mon)), "armor");
2055. 	    return TRUE;
2056. 	} else if (mon->data == &mons[PM_SILVER_DRAGON] ||
2057. 		mon->data == &mons[PM_CHROMATIC_DRAGON]) {
2058. 	    /* Silver dragons only reflect when mature; babies do not */
2059. 	    if (str)
2060. 		pline(str, s_suffix(mon_nam(mon)), "scales");
2061. 	    return TRUE;
2062. 	}
2063. 	return FALSE;
2064. }
2065. 

ureflects Edit

2066. boolean
2067. ureflects (fmt, str)
2068. const char *fmt, *str;
2069. {
2070. 	/* Check from outermost to innermost objects */
2071. 	if (EReflecting & W_ARMS) {
2072. 	    if (fmt && str) {
2073. 	    	pline(fmt, str, "shield");
2074. 	    	makeknown(SHIELD_OF_REFLECTION);
2075. 	    }
2076. 	    return TRUE;
2077. 	} else if (EReflecting & W_WEP) {
2078. 	    /* Due to wielded artifact weapon */
2079. 	    if (fmt && str)
2080. 	    	pline(fmt, str, "weapon");
2081. 	    return TRUE;
2082. 	} else if (EReflecting & W_AMUL) {
2083. 	    if (fmt && str) {
2084. 	    	pline(fmt, str, "medallion");
2085. 	    	makeknown(AMULET_OF_REFLECTION);
2086. 	    }
2087. 	    return TRUE;
2088. 	} else if (EReflecting & W_ARM) {
2089. 	    if (fmt && str)
2090. 	    	pline(fmt, str, "armor");
2091. 	    return TRUE;
2092. 	} else if (youmonst.data == &mons[PM_SILVER_DRAGON]) {
2093. 	    if (fmt && str)
2094. 	    	pline(fmt, str, "scales");
2095. 	    return TRUE;
2096. 	}
2097. 	return FALSE;
2098. }
2099. 
2100. 

munstone Edit

2101. /* TRUE if the monster ate something */
2102. boolean
2103. munstone(mon, by_you)
2104. struct monst *mon;
2105. boolean by_you;
2106. {
2107. 	struct obj *obj;
2108. 
2109. 	if (resists_ston(mon)) return FALSE;
2110. 	if (mon->meating || !mon->mcanmove || mon->msleeping) return FALSE;
2111. 
2112. 	for(obj = mon->minvent; obj; obj = obj->nobj) {
2113. 	    /* Monsters can also use potions of acid */
2114. 	    if ((obj->otyp == POT_ACID) || (obj->otyp == CORPSE &&
2115. 	    		(obj->corpsenm == PM_LIZARD || (acidic(&mons[obj->corpsenm]) && obj->corpsenm != PM_GREEN_SLIME)))) {
2116. 		mon_consume_unstone(mon, obj, by_you, TRUE);
2117. 		return TRUE;
2118. 	    }
2119. 	}
2120. 	return FALSE;
2121. }
2122. 

mon_consume_unstone Edit

2123. STATIC_OVL void
2124. mon_consume_unstone(mon, obj, by_you, stoning)
2125. struct monst *mon;
2126. struct obj *obj;
2127. boolean by_you;
2128. boolean stoning;
2129. {
2130.     int nutrit = (obj->otyp == CORPSE) ? dog_nutrition(mon, obj) : 0;
2131.     /* also sets meating */
2132. 
2133.     /* give a "<mon> is slowing down" message and also remove
2134.        intrinsic speed (comparable to similar effect on the hero) */
2135.     mon_adjust_speed(mon, -3, (struct obj *)0);
2136. 
2137.     if (canseemon(mon)) {
2138. 	long save_quan = obj->quan;
2139. 
2140. 	obj->quan = 1L;
2141. 	pline("%s %ss %s.", Monnam(mon),
2142. 		    (obj->otyp == POT_ACID) ? "quaff" : "eat",
2143. 		    distant_name(obj,doname));
2144. 	obj->quan = save_quan;
2145.     } else if (flags.soundok)
2146. 	You_hear("%s.", (obj->otyp == POT_ACID) ? "drinking" : "chewing");
2147.     m_useup(mon, obj);
2148.     if (((obj->otyp == POT_ACID) || acidic(&mons[obj->corpsenm])) &&
2149. 		    !resists_acid(mon)) {
2150. 	mon->mhp -= rnd(15);
2151. 	pline("%s has a very bad case of stomach acid.",
2152. 	    Monnam(mon));
2153.     }
2154.     if (mon->mhp <= 0) {
2155. 	pline("%s dies!", Monnam(mon));
2156. 	if (by_you) xkilled(mon, 0);
2157. 	else mondead(mon);
2158. 	return;
2159.     }
2160.     if (stoning && canseemon(mon)) {
2161. 	if (Hallucination)
2162.     pline("What a pity - %s just ruined a future piece of art!",
2163. 	    mon_nam(mon));
2164. 	else
2165. 	    pline("%s seems limber!", Monnam(mon));
2166.     }
2167.     if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD && mon->mconf) {
2168. 	mon->mconf = 0;
2169. 	if (canseemon(mon))
2170. 	    pline("%s seems steadier now.", Monnam(mon));
2171.     }
2172.     if (mon->mtame && !mon->isminion && nutrit > 0) {
2173. 	struct edog *edog = EDOG(mon);
2174. 
2175. 	if (edog->hungrytime < monstermoves) edog->hungrytime = monstermoves;
2176. 	edog->hungrytime += nutrit;
2177. 	mon->mconf = 0;
2178.     }
2179.     mon->mlstmv = monstermoves; /* it takes a turn */
2180. }
2181. 
2182. /*muse.c*/

Around Wikia's network

Random Wiki