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. */
6 * Monster item usage routines.
12 extern const int monstr[];
14 boolean m_using = FALSE;
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....
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));
35 static struct musable {
36 struct obj *offensive;
37 struct obj *defensive;
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).
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.
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.
64 vis = cansee(mon->mx, mon->my);
66 if (obj->oclass == POTION_CLASS) {
68 static const char *empty = "The potion turns out to be empty.";
69 const char *potion_descr;
71 #define POTION_OCCUPANT_CHANCE(n) (13 + 2*(n)) /* also in potion.c */
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;
80 mtmp = makemon(&mons[PM_GHOST], cc.x, cc.y, NO_MM_FLAGS);
82 if (vis) pline(empty);
85 pline("As %s opens the bottle, an enormous %s emerges!",
87 Hallucination ? rndmonnam() : (const char *)"ghost");
88 pline("%s is frightened to death, and unable to move.",
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;
103 mtmp = makemon(&mons[PM_DJINNI], cc.x, cc.y, NO_MM_FLAGS);
105 if (vis) pline(empty);
108 pline("In a cloud of smoke, %s emerges!",
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.... */
114 verbalize("You freed me!");
118 verbalize("It is about time.");
119 if (vis) pline("%s vanishes.", Monnam(mtmp));
126 if (obj->oclass == WAND_CLASS && obj->cursed && !rn2(100)) {
127 int dam = d(obj->spe+2, 6);
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.");
135 if (mon->mhp <= dam) {
136 monkilled(mon, "", AD_RBRE);
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 */
147 mzapmsg(mtmp, otmp, self)
152 if (!canseemon(mtmp)) {
154 You_hear("a %s zap.",
155 (distu(mtmp->mx,mtmp->my) <= (BOLT_LIM+1)*(BOLT_LIM+1)) ?
156 "nearby" : "distant");
158 pline("%s zaps %sself with %s!",
159 Monnam(mtmp), mhim(mtmp), doname(otmp));
161 pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp)));
171 boolean vismon = canseemon(mtmp);
176 if (!vismon && !flags.soundok)
177 return; /* no feedback */
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;
186 if (Role_if(PM_PRIEST)) Role_switch = 0;
188 Strcpy(onambuf, singular(otmp, doname));
189 Role_switch = saverole;
190 otmp->bknown = savebknown;
193 pline("%s reads %s!", Monnam(mtmp), onambuf);
195 You_hear("%s reading %s.",
196 x_monnam(mtmp, ARTICLE_A, (char *)0,
197 (SUPPRESS_IT|SUPPRESS_INVISIBLE|SUPPRESS_SADDLE), FALSE),
201 pline("Being confused, %s mispronounces the magic words...",
202 vismon ? mon_nam(mtmp) : mhe(mtmp));
206 mquaffmsg(mtmp, otmp)
210 if (canseemon(mtmp)) {
212 pline("%s drinks %s!", Monnam(mtmp), singular(otmp, doname));
215 You_hear("a chugging sound.");
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.
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
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.
249 /* Select a defensive item/action for a monster. Returns TRUE iff one is
256 register struct obj *obj = 0;
258 int x=mtmp->mx, y=mtmp->my;
259 boolean stuck = (mtmp == u.ustuck);
260 boolean immobile = (mtmp->data->mmove == 0);
263 if (is_animal(mtmp->data) || mindless(mtmp->data))
265 if(dist2(x, y, mtmp->mux, mtmp->muy) > 25)
267 if (u.uswallow && stuck) return FALSE;
269 m.defensive = (struct obj *)0;
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
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)
281 if (obj || is_unicorn(mtmp->data)) {
283 m.has_defense = MUSE_UNICORN_HORN;
289 for(obj = mtmp->minvent; obj; obj = obj->nobj) {
290 if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD) {
292 m.has_defense = MUSE_LIZARD_CORPSE;
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.
306 if (!mtmp->mcansee && !nohands(mtmp->data) &&
307 mtmp->data != &mons[PM_PESTILENCE]) {
308 if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) {
310 m.has_defense = MUSE_POT_FULL_HEALING;
313 if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) {
315 m.has_defense = MUSE_POT_EXTRA_HEALING;
318 if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) {
320 m.has_defense = MUSE_POT_HEALING;
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))
330 if (mtmp->mpeaceful) {
331 if (!nohands(mtmp->data)) {
332 if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) {
334 m.has_defense = MUSE_POT_FULL_HEALING;
337 if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) {
339 m.has_defense = MUSE_POT_EXTRA_HEALING;
342 if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) {
344 m.has_defense = MUSE_POT_HEALING;
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. */
369 for(xx = x-1; xx <= x+1; xx++) for(yy = y-1; yy <= y+1; 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
382 && Can_fall_thru(&u.uz)
386 m.has_defense = MUSE_TRAPDOOR;
387 } else if (t->ttyp == TELEP_TRAP && m.has_defense != MUSE_TRAPDOOR) {
390 m.has_defense = MUSE_TELEPORT_TRAP;
395 if (nohands(mtmp->data)) /* can't use objects */
398 if (is_mercenary(mtmp->data) && (obj = m_carrying(mtmp, BUGLE))) {
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...
406 for(xx = x-3; xx <= x+3; xx++) for(yy = y-3; yy <= y+3; yy++)
408 if ((mon = m_at(xx,yy)) && is_mercenary(mon->data) &&
409 mon->data != &mons[PM_GUARD] &&
410 (mon->msleeping || (!mon->mcanmove))) {
412 m.has_defense = MUSE_BUGLE;
416 /* use immediate physical escape prior to attempting magic */
417 if (m.has_defense) /* stairs, trap door or tele-trap, bugle alert */
420 /* kludge to cut down on trap destruction (particularly portals) */
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 */
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;
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))) {
445 m.has_defense = MUSE_WAN_DIGGING;
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.
456 if (!level.flags.noteleport ||
457 !(mtmp->mtrapseen & (1 << (TELEP_TRAP-1)))) {
459 m.has_defense = (mon_has_amulet(mtmp))
460 ? MUSE_WAN_TELEPORTATION
461 : MUSE_WAN_TELEPORTATION_SELF;
464 nomore(MUSE_SCR_TELEPORTATION);
465 if(obj->otyp == SCR_TELEPORTATION && mtmp->mcansee
466 && haseyes(mtmp->data)
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)))) {
474 m.has_defense = MUSE_SCR_TELEPORTATION;
478 if (mtmp->data != &mons[PM_PESTILENCE]) {
479 nomore(MUSE_POT_FULL_HEALING);
480 if(obj->otyp == POT_FULL_HEALING) {
482 m.has_defense = MUSE_POT_FULL_HEALING;
484 nomore(MUSE_POT_EXTRA_HEALING);
485 if(obj->otyp == POT_EXTRA_HEALING) {
487 m.has_defense = MUSE_POT_EXTRA_HEALING;
489 nomore(MUSE_WAN_CREATE_MONSTER);
490 if(obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
492 m.has_defense = MUSE_WAN_CREATE_MONSTER;
494 nomore(MUSE_POT_HEALING);
495 if(obj->otyp == POT_HEALING) {
497 m.has_defense = MUSE_POT_HEALING;
499 } else { /* Pestilence */
500 nomore(MUSE_POT_FULL_HEALING);
501 if (obj->otyp == POT_SICKNESS) {
503 m.has_defense = MUSE_POT_FULL_HEALING;
505 nomore(MUSE_WAN_CREATE_MONSTER);
506 if (obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
508 m.has_defense = MUSE_WAN_CREATE_MONSTER;
511 nomore(MUSE_SCR_CREATE_MONSTER);
512 if(obj->otyp == SCR_CREATE_MONSTER) {
514 m.has_defense = MUSE_SCR_CREATE_MONSTER;
517 botm: return((boolean)(!!m.has_defense));
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).
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.";
534 if ((i = precheck(mtmp, otmp)) != 0) return i;
535 vis = cansee(mtmp->mx, mtmp->my);
536 vismon = canseemon(mtmp);
537 oseen = otmp && vismon;
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); }
545 switch(m.has_defense) {
546 case MUSE_UNICORN_HORN:
549 pline("%s uses a unicorn horn!", Monnam(mtmp));
551 pline_The("tip of %s's horn glows!", mon_nam(mtmp));
553 if (!mtmp->mcansee) {
556 if (vismon) pline(mcsa, Monnam(mtmp));
557 } else if (mtmp->mconf || mtmp->mstun) {
558 mtmp->mconf = mtmp->mstun = 0;
560 pline("%s seems steadier now.", Monnam(mtmp));
561 } else impossible("No need for unicorn horn?");
565 pline("%s plays %s!", Monnam(mtmp), doname(otmp));
566 else if (flags.soundok)
567 You_hear("a bugle playing reveille!");
570 case MUSE_WAN_TELEPORTATION_SELF:
571 if ((mtmp->isshk && inhishop(mtmp))
572 || mtmp->isgd || mtmp->ispriest) return 2;
574 mzapmsg(mtmp, otmp, TRUE);
576 how = WAN_TELEPORTATION;
578 if (tele_restrict(mtmp)) { /* mysterious force... */
579 if (vismon && how) /* mentions 'teleport' */
581 /* monster learns that teleportation isn't useful here */
582 if (level.flags.noteleport)
583 mtmp->mtrapseen |= (1 << (TELEP_TRAP-1));
588 mon_has_amulet(mtmp) ||
590 On_W_tower_level(&u.uz)) && !rn2(3)) {
592 pline("%s seems disoriented for a moment.",
596 if (oseen && how) makeknown(how);
597 (void) rloc(mtmp, FALSE);
599 case MUSE_WAN_TELEPORTATION:
601 mzapmsg(mtmp, otmp, FALSE);
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));
610 case MUSE_SCR_TELEPORTATION:
612 int obj_is_cursed = otmp->cursed;
614 if (mtmp->isshk || mtmp->isgd || mtmp->ispriest) return 2;
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) {
623 if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
625 pline("%s seems very disoriented for a moment.",
629 nlev = random_teleport_level();
630 if (nlev == depth(&u.uz)) {
632 pline("%s shudders for a moment.",
636 get_level(&flev, nlev);
637 migrate_to_level(mtmp, ledger_no(&flev), MIGR_RANDOM,
639 if (oseen) makeknown(SCR_TELEPORTATION);
640 } else goto mon_tele;
643 case MUSE_WAN_DIGGING:
647 mzapmsg(mtmp, otmp, FALSE);
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.");
658 if (!Can_dig_down(&u.uz)) {
660 pline_The("%s here is too hard to dig in.",
661 surface(mtmp->mx, mtmp->my));
664 ttmp = maketrap(mtmp->mx, mtmp->my, HOLE);
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);
680 case MUSE_WAN_CREATE_MONSTER:
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];
687 if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) return 0;
688 mzapmsg(mtmp, otmp, FALSE);
690 mon = makemon((struct permonst *)0, cc.x, cc.y, NO_MM_FLAGS);
691 if (mon && canspotmon(mon) && oseen)
692 makeknown(WAN_CREATE_MONSTER);
695 case MUSE_SCR_CREATE_MONSTER:
697 struct permonst *pm = 0, *fish = 0;
700 boolean known = FALSE;
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);
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;
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.
721 makeknown(SCR_CREATE_MONSTER);
722 else if (!objects[SCR_CREATE_MONSTER].oc_name_known
723 && !objects[SCR_CREATE_MONSTER].oc_uname)
729 /* trap doors on "bottom" levels of dungeons are rock-drop
730 * trap doors, not holes in the floor. We check here for
733 if (Is_botlevel(&u.uz)) return 0;
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);
745 seetrap(t_at(trapx,trapy));
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);
755 migrate_to_level(mtmp, ledger_no(&u.uz) + 1,
756 MIGR_RANDOM, (coord *)0);
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
765 if (ledger_no(&u.uz) == 1) {
766 if (mon_has_special(mtmp))
769 pline("%s escapes the dungeon!", Monnam(mtmp));
774 if (Inhell && mon_has_amulet(mtmp) && !rn2(4) &&
775 (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) {
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);
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);
791 case MUSE_DOWNSTAIRS:
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);
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);
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);
811 /* the stairs leading up from the 1st level are */
812 /* regular stairs, not sstairs. */
815 pline("%s escapes upstairs!", Monnam(mtmp));
817 migrate_to_level(mtmp, ledger_no(&sstairs.tolev),
818 MIGR_RANDOM, (coord *)0);
822 pline("%s escapes downstairs!", Monnam(mtmp));
823 migrate_to_level(mtmp, ledger_no(&sstairs.tolev),
824 MIGR_SSTAIRS, (coord *)0);
826 case MUSE_TELEPORT_TRAP:
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);
835 seetrap(t_at(trapx,trapy));
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);
845 case MUSE_POT_HEALING:
846 mquaffmsg(mtmp, otmp);
847 i = d(6 + 2 * bcsign(otmp), 4);
849 if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = ++mtmp->mhpmax;
850 if (!otmp->cursed && !mtmp->mcansee) {
853 if (vismon) pline(mcsa, Monnam(mtmp));
855 if (vismon) pline("%s looks better.", Monnam(mtmp));
856 if (oseen) makeknown(POT_HEALING);
859 case MUSE_POT_EXTRA_HEALING:
860 mquaffmsg(mtmp, otmp);
861 i = d(6 + 2 * bcsign(otmp), 8);
863 if (mtmp->mhp > mtmp->mhpmax)
864 mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2));
865 if (!mtmp->mcansee) {
868 if (vismon) pline(mcsa, Monnam(mtmp));
870 if (vismon) pline("%s looks much better.", Monnam(mtmp));
871 if (oseen) makeknown(POT_EXTRA_HEALING);
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) {
881 if (vismon) pline(mcsa, Monnam(mtmp));
883 if (vismon) pline("%s looks completely healed.", Monnam(mtmp));
884 if (oseen) makeknown(otmp->otyp);
887 case MUSE_LIZARD_CORPSE:
888 /* not actually called for its unstoning effect */
889 mon_consume_unstone(mtmp, otmp, FALSE, FALSE);
891 case 0: return 0; /* i.e. an exploded wand */
892 default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
901 rnd_defensive_item(mtmp)
904 struct permonst *pm = mtmp->data;
905 int difficulty = monstr[(monsndx(pm))];
908 if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
909 || pm->mlet == S_GHOST
915 switch (rn2(8 + (difficulty > 3) + (difficulty > 6) +
918 if (level.flags.noteleport && ++trycnt < 2)
920 if (!rn2(3)) return WAN_TELEPORTATION;
923 return SCR_TELEPORTATION;
925 if (!rn2(3)) return WAN_CREATE_MONSTER;
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
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
961 /* Select an offensive item/action for a monster. Returns TRUE iff one is
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);
973 m.offensive = (struct obj *)0;
975 if (mtmp->mpeaceful || is_animal(mtmp->data) ||
976 mindless(mtmp->data) || nohands(mtmp->data))
978 if (u.uswallow) return FALSE;
979 if (in_your_sanctuary(mtmp, 0, 0)) return FALSE;
980 if (dmgtype(mtmp->data, AD_HEAL) && !uwep
984 && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf)
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) {
994 m.has_offense = MUSE_WAN_DEATH;
996 nomore(MUSE_WAN_SLEEP);
997 if(obj->otyp == WAN_SLEEP && obj->spe > 0 && multi >= 0) {
999 m.has_offense = MUSE_WAN_SLEEP;
1001 nomore(MUSE_WAN_FIRE);
1002 if(obj->otyp == WAN_FIRE && obj->spe > 0) {
1004 m.has_offense = MUSE_WAN_FIRE;
1006 nomore(MUSE_FIRE_HORN);
1007 if(obj->otyp == FIRE_HORN && obj->spe > 0) {
1009 m.has_offense = MUSE_FIRE_HORN;
1011 nomore(MUSE_WAN_COLD);
1012 if(obj->otyp == WAN_COLD && obj->spe > 0) {
1014 m.has_offense = MUSE_WAN_COLD;
1016 nomore(MUSE_FROST_HORN);
1017 if(obj->otyp == FROST_HORN && obj->spe > 0) {
1019 m.has_offense = MUSE_FROST_HORN;
1021 nomore(MUSE_WAN_LIGHTNING);
1022 if(obj->otyp == WAN_LIGHTNING && obj->spe > 0) {
1024 m.has_offense = MUSE_WAN_LIGHTNING;
1026 nomore(MUSE_WAN_MAGIC_MISSILE);
1027 if(obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) {
1029 m.has_offense = MUSE_WAN_MAGIC_MISSILE;
1032 nomore(MUSE_WAN_STRIKING);
1033 if(obj->otyp == WAN_STRIKING && obj->spe > 0) {
1035 m.has_offense = MUSE_WAN_STRIKING;
1037 nomore(MUSE_POT_PARALYSIS);
1038 if(obj->otyp == POT_PARALYSIS && multi >= 0) {
1040 m.has_offense = MUSE_POT_PARALYSIS;
1042 nomore(MUSE_POT_BLINDNESS);
1043 if(obj->otyp == POT_BLINDNESS && !attacktype(mtmp->data, AT_GAZE)) {
1045 m.has_offense = MUSE_POT_BLINDNESS;
1047 nomore(MUSE_POT_CONFUSION);
1048 if(obj->otyp == POT_CONFUSION) {
1050 m.has_offense = MUSE_POT_CONFUSION;
1052 nomore(MUSE_POT_SLEEPING);
1053 if(obj->otyp == POT_SLEEPING) {
1055 m.has_offense = MUSE_POT_SLEEPING;
1057 nomore(MUSE_POT_ACID);
1058 if(obj->otyp == POT_ACID) {
1060 m.has_offense = MUSE_POT_ACID;
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
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)
1078 && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) {
1080 m.has_offense = MUSE_SCR_EARTH;
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)) {
1088 m.has_offense = MUSE_SCR_FIRE;
1092 return((boolean)(!!m.has_offense));
1099 register struct monst *mtmp;
1100 register struct obj *otmp;
1104 boolean reveal_invis = FALSE;
1105 if (mtmp != &youmonst) {
1106 mtmp->msleeping = 0;
1107 if (mtmp->m_ap_type) seemimic(mtmp);
1109 switch(otmp->otyp) {
1111 reveal_invis = TRUE;
1112 if (mtmp == &youmonst) {
1113 if (zap_oseen) makeknown(WAN_STRIKING);
1115 shieldeff(u.ux, u.uy);
1117 } else if (rnd(20) < 10 + u.uac) {
1118 pline_The("wand hits you!");
1120 if(Half_spell_damage) tmp = (tmp+1) / 2;
1121 losehp(tmp, "wand", KILLED_BY_AN);
1122 } else pline_The("wand misses you.");
1125 } else if (resists_magm(mtmp)) {
1126 shieldeff(mtmp->mx, mtmp->my);
1128 } else if (rnd(20) < 10+find_mac(mtmp)) {
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);
1136 if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
1137 makeknown(WAN_STRIKING);
1140 case WAN_TELEPORTATION:
1141 if (mtmp == &youmonst) {
1142 if (zap_oseen) makeknown(WAN_TELEPORTATION);
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);
1156 case WAN_CANCELLATION:
1157 case SPE_CANCELLATION:
1158 (void) cancel_monst(mtmp, otmp, FALSE, TRUE, FALSE);
1162 if (mtmp->mhp > 0 && cansee(bhitpos.x,bhitpos.y)
1163 && !canspotmon(mtmp))
1164 map_invisible(bhitpos.x, bhitpos.y);
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...)
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 */
1182 register struct monst *mtmp;
1183 register struct obj *otmp;
1187 bhitpos.x = mon->mx;
1188 bhitpos.y = mon->my;
1189 ddx = sgn(mon->mux - mon->mx);
1190 ddy = sgn(mon->muy - mon->my);
1192 while(range-- > 0) {
1197 x = bhitpos.x; y = bhitpos.y;
1204 if (find_drawbridge(&x,&y))
1205 switch (obj->otyp) {
1207 destroy_drawbridge(x,y);
1209 if(bhitpos.x==u.ux && bhitpos.y==u.uy) {
1210 (*fhitm)(&youmonst, obj);
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);
1219 /* modified by GAN to hit all objects */
1221 int hitanything = 0;
1222 register struct obj *next_obj;
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);
1230 if(hitanything) range--;
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 */
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 ==
1246 *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE))
1247 add_damage(bhitpos.x, bhitpos.y, 0L);
1252 if(!ZAP_POS(typ) || (IS_DOOR(typ) &&
1253 (levl[bhitpos.x][bhitpos.y].doormask & (D_LOCKED | D_CLOSED)))
1262 /* Perform an offensive action for a monster. Must be called immediately
1263 * after find_offensive(). Return values are same as use_defensive().
1270 struct obj *otmp = m.offensive;
1273 /* offensive potions are not drunk, they're thrown */
1274 if (otmp->oclass != POTION_CLASS && (i = precheck(mtmp, otmp)) != 0)
1276 oseen = otmp && canseemon(mtmp);
1278 switch(m.has_offense) {
1279 case MUSE_WAN_DEATH:
1280 case MUSE_WAN_SLEEP:
1283 case MUSE_WAN_LIGHTNING:
1284 case MUSE_WAN_MAGIC_MISSILE:
1285 mzapmsg(mtmp, otmp, FALSE);
1287 if (oseen) makeknown(otmp->otyp);
1289 buzz((int)(-30 - (otmp->otyp - WAN_MAGIC_MISSILE)),
1290 (otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6,
1292 sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my));
1294 return (mtmp->mhp <= 0) ? 1 : 2;
1295 case MUSE_FIRE_HORN:
1296 case MUSE_FROST_HORN:
1298 makeknown(otmp->otyp);
1299 pline("%s plays a %s!", Monnam(mtmp), xname(otmp));
1301 You_hear("a horn being played.");
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));
1308 return (mtmp->mhp <= 0) ? 1 : 2;
1309 case MUSE_WAN_TELEPORTATION:
1310 case MUSE_WAN_STRIKING:
1312 mzapmsg(mtmp, otmp, FALSE);
1315 mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp);
1318 case MUSE_SCR_EARTH:
1320 /* TODO: handle steeds */
1322 /* don't use monster fields after killing it */
1323 boolean confused = (mtmp->mconf ? TRUE : FALSE);
1324 int mmx = mtmp->mx, mmy = mtmp->my;
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",
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));
1337 map_invisible(mtmp->mx, mtmp->my);
1338 if (oseen) makeknown(otmp->otyp);
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;
1354 /* Make the object(s) */
1355 otmp2 = mksobj(confused ? ROCK : BOULDER,
1357 if (!otmp2) continue; /* Shouldn't happen */
1358 otmp2->quan = confused ? rn1(5,2) : 1;
1359 otmp2->owt = weight(otmp2);
1361 /* Find the monster here (might be same as mtmp) */
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);
1370 if (cansee(mtmp2->mx, mtmp2->my)) {
1371 pline("%s is hit by %s!", Monnam(mtmp2),
1373 if (mtmp2->minvis && !canspotmon(mtmp2))
1374 map_invisible(mtmp2->mx, mtmp2->my);
1376 mdmg = dmgval(otmp2, mtmp2) * otmp2->quan;
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;
1385 if (canspotmon(mtmp2))
1386 pline("%s's %s does not protect %s.",
1387 Monnam(mtmp2), xname(helmet),
1392 if (mtmp2->mhp <= 0) {
1393 pline("%s is killed.", Monnam(mtmp2));
1397 /* Drop the rock/boulder to the floor */
1398 if (!flooreffects(otmp2, x, y, "fall")) {
1399 place_object(otmp2, x, y);
1401 newsym(x, y); /* map the rock */
1406 m_useup(mtmp, otmp);
1407 /* Attack the player */
1408 if (distmin(mmx, mmy, u.ux, u.uy) == 1 && !otmp->cursed) {
1412 /* Okay, _you_ write this without repeating the code */
1413 otmp2 = mksobj(confused ? ROCK : BOULDER,
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) &&
1420 !noncorporeal(youmonst.data) &&
1421 !unsolid(youmonst.data)) {
1422 You("are hit by %s!", doname(otmp2));
1423 dmg = dmgval(otmp2, &youmonst) * otmp2->quan;
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.",
1435 if (!flooreffects(otmp2, u.ux, u.uy, "fall")) {
1436 place_object(otmp2, u.ux, u.uy);
1440 if (dmg) losehp(dmg, "scroll of earth", KILLED_BY_AN);
1444 return (mtmp->mhp <= 0) ? 1 : 2;
1449 boolean vis = cansee(mtmp->mx, mtmp->my);
1451 mreadmsg(mtmp, otmp);
1454 pline("Oh, what a pretty fire!");
1456 struct monst *mtmp2;
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.");
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;
1478 if (resists_cold(mtmp2))
1479 mtmp2->mhp -= 3*num;
1480 if(mtmp2->mhp < 1) {
1490 case MUSE_POT_PARALYSIS:
1491 case MUSE_POT_BLINDNESS:
1492 case MUSE_POT_CONFUSION:
1493 case MUSE_POT_SLEEPING:
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.
1500 if (cansee(mtmp->mx, mtmp->my)) {
1502 pline("%s hurls %s!", Monnam(mtmp),
1503 singular(otmp, doname));
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);
1509 case 0: return 0; /* i.e. an exploded wand */
1510 default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
1518 rnd_offensive_item(mtmp)
1521 struct permonst *pm = mtmp->data;
1522 int difficulty = monstr[(monsndx(pm))];
1524 if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1525 || pm->mlet == S_GHOST
1527 || pm->mlet == S_KOP
1530 if (difficulty > 7 && !rn2(35)) return WAN_DEATH;
1531 switch (rn2(9 - (difficulty < 4) + 4 * (difficulty > 6))) {
1533 struct obj *helmet = which_armor(mtmp, W_ARMH);
1535 if ((helmet && is_metallic(helmet)) || amorphous(pm) || passes_walls(pm) || noncorporeal(pm) || unsolid(pm))
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;
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;
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
1569 register struct obj *obj;
1570 struct permonst *mdat = mtmp->data;
1571 int x = mtmp->mx, y = mtmp->my;
1574 boolean immobile = (mdat->mmove == 0);
1575 boolean stuck = (mtmp == u.ustuck);
1577 m.misc = (struct obj *)0;
1579 if (is_animal(mdat) || mindless(mdat))
1581 if (u.uswallow && stuck) return FALSE;
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...
1587 if(dist2(x, y, mtmp->mux, mtmp->muy) > 36)
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) {
1605 m.has_misc = MUSE_POLY_TRAP;
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))) {
1620 m.has_misc = MUSE_POT_GAIN_LEVEL;
1622 nomore(MUSE_BULLWHIP);
1623 if(obj->otyp == BULLWHIP && (MON_WEP(mtmp) == obj) &&
1624 distu(mtmp->mx,mtmp->my)==1 && uwep && !mtmp->mpeaceful) {
1626 m.has_misc = MUSE_BULLWHIP;
1628 /* Note: peaceful/tame monsters won't make themselves
1629 * invisible unless you can see them. Not really right, but...
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)) {
1637 m.has_misc = MUSE_WAN_MAKE_INVISIBLE;
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)) {
1645 m.has_misc = MUSE_POT_INVISIBILITY;
1647 nomore(MUSE_WAN_SPEED_MONSTER);
1648 if(obj->otyp == WAN_SPEED_MONSTER && obj->spe > 0
1649 && mtmp->mspeed != MFAST && !mtmp->isgd) {
1651 m.has_misc = MUSE_WAN_SPEED_MONSTER;
1653 nomore(MUSE_POT_SPEED);
1654 if(obj->otyp == POT_SPEED && mtmp->mspeed != MFAST
1657 m.has_misc = MUSE_POT_SPEED;
1659 nomore(MUSE_WAN_POLYMORPH);
1660 if(obj->otyp == WAN_POLYMORPH && obj->spe > 0 && !mtmp->cham
1661 && monstr[monsndx(mdat)] < 6) {
1663 m.has_misc = MUSE_WAN_POLYMORPH;
1665 nomore(MUSE_POT_POLYMORPH);
1666 if(obj->otyp == POT_POLYMORPH && !mtmp->cham
1667 && monstr[monsndx(mdat)] < 6) {
1669 m.has_misc = MUSE_POT_POLYMORPH;
1672 return((boolean)(!!m.has_misc));
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)
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);
1698 struct obj *otmp = m.misc;
1699 boolean vis, vismon, oseen;
1702 if ((i = precheck(mtmp, otmp)) != 0) return i;
1703 vis = cansee(mtmp->mx, mtmp->my);
1704 vismon = canseemon(mtmp);
1705 oseen = otmp && vismon;
1707 switch(m.has_misc) {
1708 case MUSE_POT_GAIN_LEVEL:
1709 mquaffmsg(mtmp, otmp);
1711 if (Can_rise_up(mtmp->mx, mtmp->my, &u.uz)) {
1712 register int tolev = depth(&u.uz)-1;
1715 get_level(&tolevel, tolev);
1716 /* insurance against future changes... */
1717 if(on_level(&tolevel, &u.uz)) goto skipmsg;
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)
1725 m_useup(mtmp, otmp);
1726 migrate_to_level(mtmp, ledger_no(&tolevel),
1727 MIGR_RANDOM, (coord *)0);
1732 pline("%s looks uneasy.", Monnam(mtmp));
1733 if(!objects[POT_GAIN_LEVEL].oc_name_known
1734 && !objects[POT_GAIN_LEVEL].oc_uname)
1737 m_useup(mtmp, otmp);
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 */
1747 case MUSE_WAN_MAKE_INVISIBLE:
1748 case MUSE_POT_INVISIBILITY:
1749 if (otmp->otyp == WAN_MAKE_INVISIBLE) {
1750 mzapmsg(mtmp, otmp, TRUE);
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 */
1759 pline("%s body takes on a %s transparency.",
1761 Hallucination ? "normal" : "strange");
1763 pline("Suddenly you cannot see %s.", nambuf);
1764 if (oseen) makeknown(otmp->otyp);
1766 if (otmp->otyp == POT_INVISIBILITY) {
1767 if (otmp->cursed) you_aggravate(mtmp);
1768 m_useup(mtmp, otmp);
1771 case MUSE_WAN_SPEED_MONSTER:
1772 mzapmsg(mtmp, otmp, TRUE);
1774 mon_adjust_speed(mtmp, 1, otmp);
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);
1785 case MUSE_WAN_POLYMORPH:
1786 mzapmsg(mtmp, otmp, TRUE);
1788 (void) newcham(mtmp, muse_newcham_mon(mtmp), TRUE, FALSE);
1789 if (oseen) makeknown(WAN_POLYMORPH);
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);
1798 case MUSE_POLY_TRAP:
1800 pline("%s deliberately %s onto a polymorph trap!",
1802 makeplural(locomotion(mtmp->data, "jump")));
1803 if (vis) seetrap(t_at(trapx,trapy));
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);
1812 (void) newcham(mtmp, (struct permonst *)0, FALSE, FALSE);
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;
1821 char the_weapon[BUFSZ];
1823 Strcpy(the_weapon, the(xname(obj)));
1824 hand = body_part(HAND);
1825 if (bimanual(obj)) hand = makeplural(hand);
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);
1835 pline("%s wraps around %s you're wielding!",
1836 The_whip, the_weapon);
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 */
1845 pline_The("whip slips free."); /* not `The_whip' */
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 */
1856 case 1: /* onto floor beneath mon */
1857 pline("%s yanks %s from your %s!", Monnam(mtmp),
1859 place_object(obj, mtmp->mx, mtmp->my);
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));
1866 case 3: /* into mon's inventory */
1867 pline("%s snatches %s!", Monnam(mtmp),
1869 (void) mpickobj(mtmp,obj);
1875 case 0: return 0; /* i.e. an exploded wand */
1876 default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
1887 pline("For some reason, %s presence is known to you.",
1888 s_suffix(noit_mon_nam(mtmp)));
1891 cliparound(mtmp->mx, mtmp->my);
1893 show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp));
1895 You_feel("aggravated at %s.", noit_mon_nam(mtmp));
1896 display_nhwindow(WIN_MAP, TRUE);
1898 if (unconscious()) {
1901 "Aggravated, you are jolted into full consciousness.";
1903 newsym(mtmp->mx,mtmp->my);
1904 if (!canspotmon(mtmp))
1905 map_invisible(mtmp->mx, mtmp->my);
1912 struct permonst *pm = mtmp->data;
1913 int difficulty = monstr[(monsndx(pm))];
1915 if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1916 || pm->mlet == S_GHOST
1918 || pm->mlet == S_KOP
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...
1925 if (difficulty < 6 && !rn2(30))
1926 return rn2(6) ? POT_POLYMORPH : WAN_POLYMORPH;
1928 if (!rn2(40) && !nonliving(pm)) return AMULET_OF_LIFE_SAVING;
1932 if (mtmp->isgd) return 0;
1933 return rn2(6) ? POT_SPEED : WAN_SPEED_MONSTER;
1935 if (mtmp->mpeaceful && !See_invisible) return 0;
1936 return rn2(6) ? POT_INVISIBILITY : WAN_MAKE_INVISIBLE;
1938 return POT_GAIN_LEVEL;
1945 searches_for_item(mon, obj)
1949 int typ = obj->otyp;
1951 if (is_animal(mon->data) ||
1952 mindless(mon->data) ||
1953 mon->data == &mons[PM_GHOST]) /* don't loot bones piles */
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);
1961 switch (obj->oclass) {
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)
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 ||
1984 typ == POT_CONFUSION)
1986 if (typ == POT_BLINDNESS && !attacktype(mon->data, AT_GAZE))
1990 if (typ == SCR_TELEPORTATION || typ == SCR_CREATE_MONSTER
1991 || typ == SCR_EARTH)
1995 if (typ == AMULET_OF_LIFE_SAVING)
1996 return (boolean)(!nonliving(mon->data));
1997 if (typ == AMULET_OF_REFLECTION)
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);
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))));
2017 return (boolean)(touch_petrifies(&mons[obj->corpsenm]));
2027 mon_reflects(mon,str)
2031 struct obj *orefl = which_armor(mon, W_ARMS);
2033 if (orefl && orefl->otyp == SHIELD_OF_REFLECTION) {
2035 pline(str, s_suffix(mon_nam(mon)), "shield");
2036 makeknown(SHIELD_OF_REFLECTION);
2039 } else if (arti_reflects(MON_WEP(mon))) {
2040 /* due to wielded artifact weapon */
2042 pline(str, s_suffix(mon_nam(mon)), "weapon");
2044 } else if ((orefl = which_armor(mon, W_AMUL)) &&
2045 orefl->otyp == AMULET_OF_REFLECTION) {
2047 pline(str, s_suffix(mon_nam(mon)), "amulet");
2048 makeknown(AMULET_OF_REFLECTION);
2051 } else if ((orefl = which_armor(mon, W_ARM)) &&
2052 (orefl->otyp == SILVER_DRAGON_SCALES || orefl->otyp == SILVER_DRAGON_SCALE_MAIL)) {
2054 pline(str, s_suffix(mon_nam(mon)), "armor");
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 */
2060 pline(str, s_suffix(mon_nam(mon)), "scales");
2067 ureflects (fmt, str)
2068 const char *fmt, *str;
2070 /* Check from outermost to innermost objects */
2071 if (EReflecting & W_ARMS) {
2073 pline(fmt, str, "shield");
2074 makeknown(SHIELD_OF_REFLECTION);
2077 } else if (EReflecting & W_WEP) {
2078 /* Due to wielded artifact weapon */
2080 pline(fmt, str, "weapon");
2082 } else if (EReflecting & W_AMUL) {
2084 pline(fmt, str, "medallion");
2085 makeknown(AMULET_OF_REFLECTION);
2088 } else if (EReflecting & W_ARM) {
2090 pline(fmt, str, "armor");
2092 } else if (youmonst.data == &mons[PM_SILVER_DRAGON]) {
2094 pline(fmt, str, "scales");
2101 /* TRUE if the monster ate something */
2103 munstone(mon, by_you)
2109 if (resists_ston(mon)) return FALSE;
2110 if (mon->meating || !mon->mcanmove || mon->msleeping) return FALSE;
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);
2124 mon_consume_unstone(mon, obj, by_you, stoning)
2130 int nutrit = (obj->otyp == CORPSE) ? dog_nutrition(mon, obj) : 0;
2131 /* also sets meating */
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);
2137 if (canseemon(mon)) {
2138 long save_quan = obj->quan;
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");
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.",
2154 if (mon->mhp <= 0) {
2155 pline("%s dies!", Monnam(mon));
2156 if (by_you) xkilled(mon, 0);
2160 if (stoning && canseemon(mon)) {
2162 pline("What a pity - %s just ruined a future piece of art!",
2165 pline("%s seems limber!", Monnam(mon));
2167 if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD && mon->mconf) {
2170 pline("%s seems steadier now.", Monnam(mon));
2172 if (mon->mtame && !mon->isminion && nutrit > 0) {
2173 struct edog *edog = EDOG(mon);
2175 if (edog->hungrytime < monstermoves) edog->hungrytime = monstermoves;
2176 edog->hungrytime += nutrit;
2179 mon->mlstmv = monstermoves; /* it takes a turn */