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