1 /* NetHack 3.6 muse.c $NHDT-Date: 1447987786 2015/11/20 02:49:46 $ $NHDT-Branch: master $:$NHDT-Revision: 1.68 $ */
2 /* Copyright (C) 1990 by Ken Arromdee */
3 /* NetHack may be freely redistributed. See license for details. */
6 * Monster item usage routines.
11 extern const int monstr[];
13 boolean m_using = FALSE;
15 /* Let monsters use magic items. Arbitrary assumptions: Monsters only use
16 * scrolls when they can see, monsters know when wands have 0 charges,
17 * monsters cannot recognize if items are cursed are not, monsters which
18 * are confused don't know not to read scrolls, etc....
21 STATIC_DCL struct permonst *FDECL(muse_newcham_mon, (struct monst *));
22 STATIC_DCL int FDECL(precheck, (struct monst *, struct obj *));
23 STATIC_DCL void FDECL(mzapmsg, (struct monst *, struct obj *, BOOLEAN_P));
24 STATIC_DCL void FDECL(mreadmsg, (struct monst *, struct obj *));
25 STATIC_DCL void FDECL(mquaffmsg, (struct monst *, struct obj *));
26 STATIC_PTR int FDECL(mbhitm, (struct monst *, struct obj *));
27 STATIC_DCL void FDECL(mbhit, (struct monst *, int,
28 int FDECL((*), (MONST_P, OBJ_P)),
29 int FDECL((*), (OBJ_P, OBJ_P)), struct obj *));
30 STATIC_DCL void FDECL(you_aggravate, (struct monst *));
31 STATIC_DCL void FDECL(mon_consume_unstone, (struct monst *, struct obj *,
32 BOOLEAN_P, BOOLEAN_P));
33 STATIC_DCL boolean FDECL(cures_stoning, (struct monst *, struct obj *,
35 STATIC_DCL boolean FDECL(mcould_eat_tin, (struct monst *));
36 STATIC_DCL boolean FDECL(muse_unslime, (struct monst *, struct obj *,
38 STATIC_DCL int FDECL(cures_sliming, (struct monst *, struct obj *));
39 STATIC_DCL boolean FDECL(green_mon, (struct monst *));
41 static struct musable {
42 struct obj *offensive;
43 struct obj *defensive;
45 int has_offense, has_defense, has_misc;
46 /* =0, no capability; otherwise, different numbers.
47 * If it's an object, the object is also set (it's 0 otherwise).
50 static int trapx, trapy;
51 static boolean zap_oseen; /* for wands which use mbhitm and are zapped at
52 * players. We usually want an oseen local to
53 * the function, but this is impossible since the
54 * function mbhitm has to be compatible with the
55 * normal zap routines, and those routines don't
56 * remember who zapped the wand. */
58 /* Any preliminary checks which may result in the monster being unable to use
59 * the item. Returns 0 if nothing happened, 2 if the monster can't do
60 * anything (i.e. it teleported) and 1 if it's dead.
71 vis = cansee(mon->mx, mon->my);
73 if (obj->oclass == POTION_CLASS) {
75 static const char *empty = "The potion turns out to be empty.";
76 const char *potion_descr;
79 potion_descr = OBJ_DESCR(objects[obj->otyp]);
80 if (potion_descr && !strcmp(potion_descr, "milky")) {
81 if (!(mvitals[PM_GHOST].mvflags & G_GONE)
82 && !rn2(POTION_OCCUPANT_CHANCE(mvitals[PM_GHOST].born))) {
83 if (!enexto(&cc, mon->mx, mon->my, &mons[PM_GHOST]))
87 mtmp = makemon(&mons[PM_GHOST], cc.x, cc.y, NO_MM_FLAGS);
94 "As %s opens the bottle, an enormous %s emerges!",
96 Hallucination ? rndmonnam(NULL)
97 : (const char *) "ghost");
98 pline("%s is frightened to death, and unable to move.",
101 paralyze_monst(mon, 3);
106 if (potion_descr && !strcmp(potion_descr, "smoky")
107 && !(mvitals[PM_DJINNI].mvflags & G_GONE)
108 && !rn2(POTION_OCCUPANT_CHANCE(mvitals[PM_DJINNI].born))) {
109 if (!enexto(&cc, mon->mx, mon->my, &mons[PM_DJINNI]))
113 mtmp = makemon(&mons[PM_DJINNI], cc.x, cc.y, NO_MM_FLAGS);
119 pline("In a cloud of smoke, %s emerges!", a_monnam(mtmp));
120 pline("%s speaks.", vis ? Monnam(mtmp) : Something);
121 /* I suspect few players will be upset that monsters */
122 /* can't wish for wands of death here.... */
124 verbalize("You freed me!");
128 verbalize("It is about time.");
130 pline("%s vanishes.", Monnam(mtmp));
137 if (obj->oclass == WAND_CLASS && obj->cursed
138 && !rn2(WAND_BACKFIRE_CHANCE)) {
139 int dam = d(obj->spe + 2, 6);
143 pline("%s zaps %s, which suddenly explodes!", Monnam(mon),
146 You_hear("a zap and an explosion in the distance.");
149 if (mon->mhp <= dam) {
150 monkilled(mon, "", AD_RBRE);
154 m.has_defense = m.has_offense = m.has_misc = 0;
155 /* Only one needed to be set to 0 but the others are harmless */
161 mzapmsg(mtmp, otmp, self)
166 if (!canseemon(mtmp)) {
168 You_hear("a %s zap.", (distu(mtmp->mx, mtmp->my)
169 <= (BOLT_LIM + 1) * (BOLT_LIM + 1))
173 pline("%s zaps %sself with %s!", Monnam(mtmp), mhim(mtmp),
176 pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp)));
186 boolean vismon = canseemon(mtmp);
192 return; /* no feedback */
194 otmp->dknown = 1; /* seeing or hearing it read reveals its label */
195 /* shouldn't be able to hear curse/bless status of unseen scrolls;
196 for priest characters, bknown will always be set during naming */
197 savebknown = otmp->bknown;
198 saverole = Role_switch;
201 if (Role_if(PM_PRIEST))
204 Strcpy(onambuf, singular(otmp, doname));
205 Role_switch = saverole;
206 otmp->bknown = savebknown;
209 pline("%s reads %s!", Monnam(mtmp), onambuf);
211 You_hear("%s reading %s.",
212 x_monnam(mtmp, ARTICLE_A, (char *) 0,
213 (SUPPRESS_IT | SUPPRESS_INVISIBLE | SUPPRESS_SADDLE),
218 pline("Being confused, %s mispronounces the magic words...",
219 vismon ? mon_nam(mtmp) : mhe(mtmp));
223 mquaffmsg(mtmp, otmp)
227 if (canseemon(mtmp)) {
229 pline("%s drinks %s!", Monnam(mtmp), singular(otmp, doname));
231 You_hear("a chugging sound.");
234 /* Defines for various types of stuff. The order in which monsters prefer
235 * to use them is determined by the order of the code logic, not the
236 * numerical order in which they are defined.
238 #define MUSE_SCR_TELEPORTATION 1
239 #define MUSE_WAN_TELEPORTATION_SELF 2
240 #define MUSE_POT_HEALING 3
241 #define MUSE_POT_EXTRA_HEALING 4
242 #define MUSE_WAN_DIGGING 5
243 #define MUSE_TRAPDOOR 6
244 #define MUSE_TELEPORT_TRAP 7
245 #define MUSE_UPSTAIRS 8
246 #define MUSE_DOWNSTAIRS 9
247 #define MUSE_WAN_CREATE_MONSTER 10
248 #define MUSE_SCR_CREATE_MONSTER 11
249 #define MUSE_UP_LADDER 12
250 #define MUSE_DN_LADDER 13
251 #define MUSE_SSTAIRS 14
252 #define MUSE_WAN_TELEPORTATION 15
253 #define MUSE_BUGLE 16
254 #define MUSE_UNICORN_HORN 17
255 #define MUSE_POT_FULL_HEALING 18
256 #define MUSE_LIZARD_CORPSE 19
258 #define MUSE_INNATE_TPT 9999
259 * We cannot use this. Since monsters get unlimited teleportation, if they
260 * were allowed to teleport at will you could never catch them. Instead,
261 * assume they only teleport at random times, despite the inconsistency
262 * that if you polymorph into one you teleport at will.
265 /* Select a defensive item/action for a monster. Returns TRUE iff one is
271 register struct obj *obj = 0;
273 int x = mtmp->mx, y = mtmp->my;
274 boolean stuck = (mtmp == u.ustuck);
275 boolean immobile = (mtmp->data->mmove == 0);
278 if (is_animal(mtmp->data) || mindless(mtmp->data))
280 if (dist2(x, y, mtmp->mux, mtmp->muy) > 25)
282 if (u.uswallow && stuck)
285 m.defensive = (struct obj *) 0;
288 /* since unicorn horns don't get used up, the monster would look
289 * silly trying to use the same cursed horn round after round
291 if (mtmp->mconf || mtmp->mstun || !mtmp->mcansee) {
292 if (!is_unicorn(mtmp->data) && !nohands(mtmp->data)) {
293 for (obj = mtmp->minvent; obj; obj = obj->nobj)
294 if (obj->otyp == UNICORN_HORN && !obj->cursed)
297 if (obj || is_unicorn(mtmp->data)) {
299 m.has_defense = MUSE_UNICORN_HORN;
304 if (mtmp->mconf || mtmp->mstun) {
305 struct obj *liztin = 0;
307 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
308 if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD) {
310 m.has_defense = MUSE_LIZARD_CORPSE;
312 } else if (obj->otyp == TIN && obj->corpsenm == PM_LIZARD) {
316 /* confused or stunned monster might not be able to open tin */
317 if (liztin && mcould_eat_tin(mtmp) && rn2(3)) {
318 m.defensive = liztin;
319 /* tin and corpse ultimately end up being handled the same */
320 m.has_defense = MUSE_LIZARD_CORPSE;
325 /* It so happens there are two unrelated cases when we might want to
326 * check specifically for healing alone. The first is when the monster
327 * is blind (healing cures blindness). The second is when the monster
328 * is peaceful; then we don't want to flee the player, and by
329 * coincidence healing is all there is that doesn't involve fleeing.
330 * These would be hard to combine because of the control flow.
331 * Pestilence won't use healing even when blind.
333 if (!mtmp->mcansee && !nohands(mtmp->data)
334 && mtmp->data != &mons[PM_PESTILENCE]) {
335 if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) {
337 m.has_defense = MUSE_POT_FULL_HEALING;
340 if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) {
342 m.has_defense = MUSE_POT_EXTRA_HEALING;
345 if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) {
347 m.has_defense = MUSE_POT_HEALING;
352 fraction = u.ulevel < 10 ? 5 : u.ulevel < 14 ? 4 : 3;
353 if (mtmp->mhp >= mtmp->mhpmax
354 || (mtmp->mhp >= 10 && mtmp->mhp * fraction >= mtmp->mhpmax))
357 if (mtmp->mpeaceful) {
358 if (!nohands(mtmp->data)) {
359 if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) {
361 m.has_defense = MUSE_POT_FULL_HEALING;
364 if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) {
366 m.has_defense = MUSE_POT_EXTRA_HEALING;
369 if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) {
371 m.has_defense = MUSE_POT_HEALING;
378 if (stuck || immobile) {
379 ; /* fleeing by stairs or traps is not possible */
380 } else if (levl[x][y].typ == STAIRS) {
381 if (x == xdnstair && y == ydnstair) {
382 if (!is_floater(mtmp->data))
383 m.has_defense = MUSE_DOWNSTAIRS;
384 } else if (x == xupstair && y == yupstair) {
385 /* don't let monster leave the dungeon with the Amulet */
386 if (ledger_no(&u.uz) != 1)
387 m.has_defense = MUSE_UPSTAIRS;
388 } else if (sstairs.sx && x == sstairs.sx && y == sstairs.sy) {
389 if (sstairs.up || !is_floater(mtmp->data))
390 m.has_defense = MUSE_SSTAIRS;
392 } else if (levl[x][y].typ == LADDER) {
393 if (x == xupladder && y == yupladder) {
394 m.has_defense = MUSE_UP_LADDER;
395 } else if (x == xdnladder && y == ydnladder) {
396 if (!is_floater(mtmp->data))
397 m.has_defense = MUSE_DN_LADDER;
398 } else if (sstairs.sx && x == sstairs.sx && y == sstairs.sy) {
399 if (sstairs.up || !is_floater(mtmp->data))
400 m.has_defense = MUSE_SSTAIRS;
403 /* Note: trap doors take precedence over teleport traps. */
404 int xx, yy, i, locs[10][2];
405 boolean ignore_boulders = (verysmall(mtmp->data)
406 || throws_rocks(mtmp->data)
407 || passes_walls(mtmp->data)),
408 diag_ok = !NODIAG(monsndx(mtmp->data));
410 for (i = 0; i < 10; ++i) /* 10: 9 spots plus sentinel */
411 locs[i][0] = locs[i][1] = 0;
412 /* collect viable spots; monster's <mx,my> comes first */
413 locs[0][0] = x, locs[0][1] = y;
415 for (xx = x - 1; xx <= x + 1; xx++)
416 for (yy = y - 1; yy <= y + 1; yy++)
417 if (isok(xx, yy) && (xx != x || yy != y)) {
418 locs[i][0] = xx, locs[i][1] = yy;
421 /* look for a suitable trap among the viable spots */
422 for (i = 0; i < 10; ++i) {
423 xx = locs[i][0], yy = locs[i][1];
425 break; /* we've run out of spots */
426 /* skip if it's hero's location
427 or a diagonal spot and monster can't move diagonally
428 or some other monster is there */
429 if ((xx == u.ux && yy == u.uy)
430 || (xx != x && yy != y && !diag_ok)
431 || (level.monsters[xx][yy] && !(xx == x && yy == y)))
433 /* skip if there's no trap or can't/won't move onto trap */
434 if ((t = t_at(xx, yy)) == 0
435 || (!ignore_boulders && sobj_at(BOULDER, xx, yy))
436 || onscary(xx, yy, mtmp))
438 /* use trap if it's the correct type */
439 if ((t->ttyp == TRAPDOOR || t->ttyp == HOLE)
440 && !is_floater(mtmp->data)
441 && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest
442 && Can_fall_thru(&u.uz)) {
445 m.has_defense = MUSE_TRAPDOOR;
446 break; /* no need to look at any other spots */
447 } else if (t->ttyp == TELEP_TRAP) {
450 m.has_defense = MUSE_TELEPORT_TRAP;
455 if (nohands(mtmp->data)) /* can't use objects */
458 if (is_mercenary(mtmp->data) && (obj = m_carrying(mtmp, BUGLE)) != 0) {
462 /* Distance is arbitrary. What we really want to do is
463 * have the soldier play the bugle when it sees or
464 * remembers soldiers nearby...
466 for (xx = x - 3; xx <= x + 3; xx++) {
467 for (yy = y - 3; yy <= y + 3; yy++) {
468 if (!isok(xx, yy) || (xx == x && yy == y))
470 if ((mon = m_at(xx, yy)) != 0 && is_mercenary(mon->data)
471 && mon->data != &mons[PM_GUARD]
472 && (mon->msleeping || !mon->mcanmove)) {
474 m.has_defense = MUSE_BUGLE;
475 goto toot; /* double break */
483 /* use immediate physical escape prior to attempting magic */
484 if (m.has_defense) /* stairs, trap door or tele-trap, bugle alert */
487 /* kludge to cut down on trap destruction (particularly portals) */
489 if (t && (t->ttyp == PIT || t->ttyp == SPIKED_PIT || t->ttyp == WEB
490 || t->ttyp == BEAR_TRAP))
491 t = 0; /* ok for monster to dig here */
493 #define nomore(x) if (m.has_defense == x) continue;
494 /* selection could be improved by collecting all possibilities
495 into an array and then picking one at random */
496 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
497 /* don't always use the same selection pattern */
498 if (m.has_defense && !rn2(3))
501 /* nomore(MUSE_WAN_DIGGING); */
502 if (m.has_defense == MUSE_WAN_DIGGING)
504 if (obj->otyp == WAN_DIGGING && obj->spe > 0 && !stuck && !t
505 && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest
506 && !is_floater(mtmp->data)
507 /* monsters digging in Sokoban can ruin things */
509 /* digging wouldn't be effective; assume they know that */
510 && !(levl[x][y].wall_info & W_NONDIGGABLE)
511 && !(Is_botlevel(&u.uz) || In_endgame(&u.uz))
512 && !(is_ice(x, y) || is_pool(x, y) || is_lava(x, y))
513 && !(mtmp->data == &mons[PM_VLAD_THE_IMPALER]
514 && In_V_tower(&u.uz))) {
516 m.has_defense = MUSE_WAN_DIGGING;
518 nomore(MUSE_WAN_TELEPORTATION_SELF);
519 nomore(MUSE_WAN_TELEPORTATION);
520 if (obj->otyp == WAN_TELEPORTATION && obj->spe > 0) {
521 /* use the TELEP_TRAP bit to determine if they know
522 * about noteleport on this level or not. Avoids
523 * ineffective re-use of teleportation. This does
524 * mean if the monster leaves the level, they'll know
525 * about teleport traps.
527 if (!level.flags.noteleport
528 || !(mtmp->mtrapseen & (1 << (TELEP_TRAP - 1)))) {
530 m.has_defense = (mon_has_amulet(mtmp))
531 ? MUSE_WAN_TELEPORTATION
532 : MUSE_WAN_TELEPORTATION_SELF;
535 nomore(MUSE_SCR_TELEPORTATION);
536 if (obj->otyp == SCR_TELEPORTATION && mtmp->mcansee
537 && haseyes(mtmp->data)
538 && (!obj->cursed || (!(mtmp->isshk && inhishop(mtmp))
539 && !mtmp->isgd && !mtmp->ispriest))) {
540 /* see WAN_TELEPORTATION case above */
541 if (!level.flags.noteleport
542 || !(mtmp->mtrapseen & (1 << (TELEP_TRAP - 1)))) {
544 m.has_defense = MUSE_SCR_TELEPORTATION;
548 if (mtmp->data != &mons[PM_PESTILENCE]) {
549 nomore(MUSE_POT_FULL_HEALING);
550 if (obj->otyp == POT_FULL_HEALING) {
552 m.has_defense = MUSE_POT_FULL_HEALING;
554 nomore(MUSE_POT_EXTRA_HEALING);
555 if (obj->otyp == POT_EXTRA_HEALING) {
557 m.has_defense = MUSE_POT_EXTRA_HEALING;
559 nomore(MUSE_WAN_CREATE_MONSTER);
560 if (obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
562 m.has_defense = MUSE_WAN_CREATE_MONSTER;
564 nomore(MUSE_POT_HEALING);
565 if (obj->otyp == POT_HEALING) {
567 m.has_defense = MUSE_POT_HEALING;
569 } else { /* Pestilence */
570 nomore(MUSE_POT_FULL_HEALING);
571 if (obj->otyp == POT_SICKNESS) {
573 m.has_defense = MUSE_POT_FULL_HEALING;
575 nomore(MUSE_WAN_CREATE_MONSTER);
576 if (obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
578 m.has_defense = MUSE_WAN_CREATE_MONSTER;
581 nomore(MUSE_SCR_CREATE_MONSTER);
582 if (obj->otyp == SCR_CREATE_MONSTER) {
584 m.has_defense = MUSE_SCR_CREATE_MONSTER;
588 return (boolean) !!m.has_defense;
592 /* Perform a defensive action for a monster. Must be called immediately
593 * after find_defensive(). Return values are 0: did something, 1: died,
594 * 2: did something and can't attack again (i.e. teleported).
600 int i, fleetim, how = 0;
601 struct obj *otmp = m.defensive;
602 boolean vis, vismon, oseen;
603 const char *mcsa = "%s can see again.";
605 if ((i = precheck(mtmp, otmp)) != 0)
607 vis = cansee(mtmp->mx, mtmp->my);
608 vismon = canseemon(mtmp);
609 oseen = otmp && vismon;
611 /* when using defensive choice to run away, we want monster to avoid
612 rushing right straight back; don't override if already scared */
613 fleetim = !mtmp->mflee ? (33 - (30 * mtmp->mhp / mtmp->mhpmax)) : 0;
615 if (fleetim && !m->iswiz) { \
616 monflee(m, fleetim, FALSE, FALSE); \
619 switch (m.has_defense) {
620 case MUSE_UNICORN_HORN:
623 pline("%s uses a unicorn horn!", Monnam(mtmp));
625 pline_The("tip of %s's horn glows!", mon_nam(mtmp));
627 if (!mtmp->mcansee) {
631 pline(mcsa, Monnam(mtmp));
632 } else if (mtmp->mconf || mtmp->mstun) {
633 mtmp->mconf = mtmp->mstun = 0;
635 pline("%s seems steadier now.", Monnam(mtmp));
637 impossible("No need for unicorn horn?");
641 pline("%s plays %s!", Monnam(mtmp), doname(otmp));
643 You_hear("a bugle playing reveille!");
644 awaken_soldiers(mtmp);
646 case MUSE_WAN_TELEPORTATION_SELF:
647 if ((mtmp->isshk && inhishop(mtmp)) || mtmp->isgd || mtmp->ispriest)
650 mzapmsg(mtmp, otmp, TRUE);
652 how = WAN_TELEPORTATION;
654 if (tele_restrict(mtmp)) { /* mysterious force... */
655 if (vismon && how) /* mentions 'teleport' */
657 /* monster learns that teleportation isn't useful here */
658 if (level.flags.noteleport)
659 mtmp->mtrapseen |= (1 << (TELEP_TRAP - 1));
662 if ((mon_has_amulet(mtmp) || On_W_tower_level(&u.uz)) && !rn2(3)) {
664 pline("%s seems disoriented for a moment.", Monnam(mtmp));
669 (void) rloc(mtmp, TRUE);
671 case MUSE_WAN_TELEPORTATION:
673 mzapmsg(mtmp, otmp, FALSE);
676 mbhit(mtmp, rn1(8, 6), mbhitm, bhito, otmp);
677 /* monster learns that teleportation isn't useful here */
678 if (level.flags.noteleport)
679 mtmp->mtrapseen |= (1 << (TELEP_TRAP - 1));
682 case MUSE_SCR_TELEPORTATION: {
683 int obj_is_cursed = otmp->cursed;
685 if (mtmp->isshk || mtmp->isgd || mtmp->ispriest)
688 mreadmsg(mtmp, otmp);
689 m_useup(mtmp, otmp); /* otmp might be free'ed */
690 how = SCR_TELEPORTATION;
691 if (obj_is_cursed || mtmp->mconf) {
695 if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
697 pline("%s seems very disoriented for a moment.",
701 nlev = random_teleport_level();
702 if (nlev == depth(&u.uz)) {
704 pline("%s shudders for a moment.", Monnam(mtmp));
707 get_level(&flev, nlev);
708 migrate_to_level(mtmp, ledger_no(&flev), MIGR_RANDOM,
711 makeknown(SCR_TELEPORTATION);
716 case MUSE_WAN_DIGGING: {
720 mzapmsg(mtmp, otmp, FALSE);
723 makeknown(WAN_DIGGING);
724 if (IS_FURNITURE(levl[mtmp->mx][mtmp->my].typ)
725 || IS_DRAWBRIDGE(levl[mtmp->mx][mtmp->my].typ)
726 || (is_drawbridge_wall(mtmp->mx, mtmp->my) >= 0)
727 || (sstairs.sx && sstairs.sx == mtmp->mx
728 && sstairs.sy == mtmp->my)) {
729 pline_The("digging ray is ineffective.");
732 if (!Can_dig_down(&u.uz) && !levl[mtmp->mx][mtmp->my].candig) {
734 pline_The("%s here is too hard to dig in.",
735 surface(mtmp->mx, mtmp->my));
738 ttmp = maketrap(mtmp->mx, mtmp->my, HOLE);
743 pline("%s has made a hole in the %s.", Monnam(mtmp),
744 surface(mtmp->mx, mtmp->my));
745 pline("%s %s through...", Monnam(mtmp),
746 is_flyer(mtmp->data) ? "dives" : "falls");
748 You_hear("%s crash through the %s.", something,
749 surface(mtmp->mx, mtmp->my));
750 /* we made sure that there is a level for mtmp to go to */
751 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, MIGR_RANDOM,
755 case MUSE_WAN_CREATE_MONSTER: {
757 /* pm: 0 => random, eel => aquatic, croc => amphibious */
758 struct permonst *pm =
759 !is_pool(mtmp->mx, mtmp->my)
761 : &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE];
764 if (!enexto(&cc, mtmp->mx, mtmp->my, pm))
766 mzapmsg(mtmp, otmp, FALSE);
768 mon = makemon((struct permonst *) 0, cc.x, cc.y, NO_MM_FLAGS);
769 if (mon && canspotmon(mon) && oseen)
770 makeknown(WAN_CREATE_MONSTER);
773 case MUSE_SCR_CREATE_MONSTER: {
775 struct permonst *pm = 0, *fish = 0;
778 boolean known = FALSE;
782 if (mtmp->mconf || otmp->cursed)
785 pm = fish = &mons[PM_ACID_BLOB];
786 else if (is_pool(mtmp->mx, mtmp->my))
787 fish = &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE];
788 mreadmsg(mtmp, otmp);
790 /* `fish' potentially gives bias towards water locations;
791 `pm' is what to actually create (0 => random) */
792 if (!enexto(&cc, mtmp->mx, mtmp->my, fish))
794 mon = makemon(pm, cc.x, cc.y, NO_MM_FLAGS);
795 if (mon && canspotmon(mon))
798 /* The only case where we don't use oseen. For wands, you
799 * have to be able to see the monster zap the wand to know
800 * what type it is. For teleport scrolls, you have to see
801 * the monster to know it teleported.
804 makeknown(SCR_CREATE_MONSTER);
805 else if (!objects[SCR_CREATE_MONSTER].oc_name_known
806 && !objects[SCR_CREATE_MONSTER].oc_uname)
812 /* trap doors on "bottom" levels of dungeons are rock-drop
813 * trap doors, not holes in the floor. We check here for
816 if (Is_botlevel(&u.uz))
820 struct trap *t = t_at(trapx, trapy);
822 pline("%s %s into a %s!", Monnam(mtmp),
823 makeplural(locomotion(mtmp->data, "jump")),
824 t->ttyp == TRAPDOOR ? "trap door" : "hole");
825 if (levl[trapx][trapy].typ == SCORR) {
826 levl[trapx][trapy].typ = CORR;
827 unblock_point(trapx, trapy);
829 seetrap(t_at(trapx, trapy));
832 /* don't use rloc_to() because worm tails must "move" */
833 remove_monster(mtmp->mx, mtmp->my);
834 newsym(mtmp->mx, mtmp->my); /* update old location */
835 place_monster(mtmp, trapx, trapy);
838 newsym(trapx, trapy);
840 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, MIGR_RANDOM,
844 /* Monsters without amulets escape the dungeon and are
845 * gone for good when they leave up the up stairs.
846 * Monsters with amulets would reach the endlevel,
847 * which we cannot allow since that would leave the
850 if (ledger_no(&u.uz) == 1) {
851 if (mon_has_special(mtmp))
854 pline("%s escapes the dungeon!", Monnam(mtmp));
859 if (Inhell && mon_has_amulet(mtmp) && !rn2(4)
860 && (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) {
863 "As %s climbs the stairs, a mysterious force momentarily surrounds %s...",
864 mon_nam(mtmp), mhim(mtmp));
865 /* simpler than for the player; this will usually be
866 the Wizard and he'll immediately go right to the
867 upstairs, so there's not much point in having any
868 chance for a random position on the current level */
869 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, MIGR_RANDOM,
873 pline("%s escapes upstairs!", Monnam(mtmp));
874 migrate_to_level(mtmp, ledger_no(&u.uz) - 1, MIGR_STAIRS_DOWN,
878 case MUSE_DOWNSTAIRS:
881 pline("%s escapes downstairs!", Monnam(mtmp));
882 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, MIGR_STAIRS_UP,
888 pline("%s escapes up the ladder!", Monnam(mtmp));
889 migrate_to_level(mtmp, ledger_no(&u.uz) - 1, MIGR_LADDER_DOWN,
895 pline("%s escapes down the ladder!", Monnam(mtmp));
896 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, MIGR_LADDER_UP,
902 pline("%s escapes %sstairs!", Monnam(mtmp),
903 sstairs.up ? "up" : "down");
904 /* going from the Valley to Castle (Stronghold) has no sstairs
905 to target, but having sstairs.<sx,sy> == <0,0> will work the
906 same as specifying MIGR_RANDOM when mon_arrive() eventually
907 places the monster, so we can use MIGR_SSTAIRS unconditionally */
908 migrate_to_level(mtmp, ledger_no(&sstairs.tolev), MIGR_SSTAIRS,
911 case MUSE_TELEPORT_TRAP:
914 pline("%s %s onto a teleport trap!", Monnam(mtmp),
915 makeplural(locomotion(mtmp->data, "jump")));
916 seetrap(t_at(trapx, trapy));
918 /* don't use rloc_to() because worm tails must "move" */
919 remove_monster(mtmp->mx, mtmp->my);
920 newsym(mtmp->mx, mtmp->my); /* update old location */
921 place_monster(mtmp, trapx, trapy);
924 newsym(trapx, trapy);
927 case MUSE_POT_HEALING:
928 mquaffmsg(mtmp, otmp);
929 i = d(6 + 2 * bcsign(otmp), 4);
931 if (mtmp->mhp > mtmp->mhpmax)
932 mtmp->mhp = ++mtmp->mhpmax;
933 if (!otmp->cursed && !mtmp->mcansee) {
937 pline(mcsa, Monnam(mtmp));
940 pline("%s looks better.", Monnam(mtmp));
942 makeknown(POT_HEALING);
945 case MUSE_POT_EXTRA_HEALING:
946 mquaffmsg(mtmp, otmp);
947 i = d(6 + 2 * bcsign(otmp), 8);
949 if (mtmp->mhp > mtmp->mhpmax)
950 mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2));
951 if (!mtmp->mcansee) {
955 pline(mcsa, Monnam(mtmp));
958 pline("%s looks much better.", Monnam(mtmp));
960 makeknown(POT_EXTRA_HEALING);
963 case MUSE_POT_FULL_HEALING:
964 mquaffmsg(mtmp, otmp);
965 if (otmp->otyp == POT_SICKNESS)
966 unbless(otmp); /* Pestilence */
967 mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 8 : 4));
968 if (!mtmp->mcansee && otmp->otyp != POT_SICKNESS) {
972 pline(mcsa, Monnam(mtmp));
975 pline("%s looks completely healed.", Monnam(mtmp));
977 makeknown(otmp->otyp);
980 case MUSE_LIZARD_CORPSE:
981 /* not actually called for its unstoning effect */
982 mon_consume_unstone(mtmp, otmp, FALSE, FALSE);
985 return 0; /* i.e. an exploded wand */
987 impossible("%s wanted to perform action %d?", Monnam(mtmp),
996 rnd_defensive_item(mtmp)
999 struct permonst *pm = mtmp->data;
1000 int difficulty = monstr[(monsndx(pm))];
1003 if (is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1004 || pm->mlet == S_GHOST || pm->mlet == S_KOP)
1007 switch (rn2(8 + (difficulty > 3) + (difficulty > 6) + (difficulty > 8))) {
1010 if (level.flags.noteleport && ++trycnt < 2)
1013 return WAN_TELEPORTATION;
1017 return SCR_TELEPORTATION;
1021 return WAN_CREATE_MONSTER;
1024 return SCR_CREATE_MONSTER;
1028 return POT_EXTRA_HEALING;
1030 return (mtmp->data != &mons[PM_PESTILENCE]) ? POT_FULL_HEALING
1033 if (is_floater(pm) || mtmp->isshk || mtmp->isgd || mtmp->ispriest)
1042 #define MUSE_WAN_DEATH 1
1043 #define MUSE_WAN_SLEEP 2
1044 #define MUSE_WAN_FIRE 3
1045 #define MUSE_WAN_COLD 4
1046 #define MUSE_WAN_LIGHTNING 5
1047 #define MUSE_WAN_MAGIC_MISSILE 6
1048 #define MUSE_WAN_STRIKING 7
1049 #define MUSE_SCR_FIRE 8
1050 #define MUSE_POT_PARALYSIS 9
1051 #define MUSE_POT_BLINDNESS 10
1052 #define MUSE_POT_CONFUSION 11
1053 #define MUSE_FROST_HORN 12
1054 #define MUSE_FIRE_HORN 13
1055 #define MUSE_POT_ACID 14
1056 /*#define MUSE_WAN_TELEPORTATION 15*/
1057 #define MUSE_POT_SLEEPING 16
1058 #define MUSE_SCR_EARTH 17
1060 /* Select an offensive item/action for a monster. Returns TRUE iff one is
1064 find_offensive(mtmp)
1067 register struct obj *obj;
1068 boolean reflection_skip = (Reflecting && rn2(2));
1069 struct obj *helmet = which_armor(mtmp, W_ARMH);
1071 m.offensive = (struct obj *) 0;
1073 if (mtmp->mpeaceful || is_animal(mtmp->data) || mindless(mtmp->data)
1074 || nohands(mtmp->data))
1078 if (in_your_sanctuary(mtmp, 0, 0))
1080 if (dmgtype(mtmp->data, AD_HEAL)
1081 && !uwep && !uarmu && !uarm && !uarmh
1082 && !uarms && !uarmg && !uarmc && !uarmf)
1084 /* all offensive items require orthogonal or diagonal targetting */
1085 if (!lined_up(mtmp))
1088 #define nomore(x) if (m.has_offense == x) continue;
1089 /* this picks the last viable item rather than prioritizing choices */
1090 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
1091 if (!reflection_skip) {
1092 nomore(MUSE_WAN_DEATH);
1093 if (obj->otyp == WAN_DEATH && obj->spe > 0) {
1095 m.has_offense = MUSE_WAN_DEATH;
1097 nomore(MUSE_WAN_SLEEP);
1098 if (obj->otyp == WAN_SLEEP && obj->spe > 0 && multi >= 0) {
1100 m.has_offense = MUSE_WAN_SLEEP;
1102 nomore(MUSE_WAN_FIRE);
1103 if (obj->otyp == WAN_FIRE && obj->spe > 0) {
1105 m.has_offense = MUSE_WAN_FIRE;
1107 nomore(MUSE_FIRE_HORN);
1108 if (obj->otyp == FIRE_HORN && obj->spe > 0) {
1110 m.has_offense = MUSE_FIRE_HORN;
1112 nomore(MUSE_WAN_COLD);
1113 if (obj->otyp == WAN_COLD && obj->spe > 0) {
1115 m.has_offense = MUSE_WAN_COLD;
1117 nomore(MUSE_FROST_HORN);
1118 if (obj->otyp == FROST_HORN && obj->spe > 0) {
1120 m.has_offense = MUSE_FROST_HORN;
1122 nomore(MUSE_WAN_LIGHTNING);
1123 if (obj->otyp == WAN_LIGHTNING && obj->spe > 0) {
1125 m.has_offense = MUSE_WAN_LIGHTNING;
1127 nomore(MUSE_WAN_MAGIC_MISSILE);
1128 if (obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) {
1130 m.has_offense = MUSE_WAN_MAGIC_MISSILE;
1133 nomore(MUSE_WAN_STRIKING);
1134 if (obj->otyp == WAN_STRIKING && obj->spe > 0) {
1136 m.has_offense = MUSE_WAN_STRIKING;
1138 nomore(MUSE_POT_PARALYSIS);
1139 if (obj->otyp == POT_PARALYSIS && multi >= 0) {
1141 m.has_offense = MUSE_POT_PARALYSIS;
1143 nomore(MUSE_POT_BLINDNESS);
1144 if (obj->otyp == POT_BLINDNESS && !attacktype(mtmp->data, AT_GAZE)) {
1146 m.has_offense = MUSE_POT_BLINDNESS;
1148 nomore(MUSE_POT_CONFUSION);
1149 if (obj->otyp == POT_CONFUSION) {
1151 m.has_offense = MUSE_POT_CONFUSION;
1153 nomore(MUSE_POT_SLEEPING);
1154 if (obj->otyp == POT_SLEEPING) {
1156 m.has_offense = MUSE_POT_SLEEPING;
1158 nomore(MUSE_POT_ACID);
1159 if (obj->otyp == POT_ACID) {
1161 m.has_offense = MUSE_POT_ACID;
1163 /* we can safely put this scroll here since the locations that
1164 * are in a 1 square radius are a subset of the locations that
1165 * are in wand or throwing range (in other words, always lined_up())
1167 nomore(MUSE_SCR_EARTH);
1168 if (obj->otyp == SCR_EARTH
1169 && ((helmet && is_metallic(helmet)) || mtmp->mconf
1170 || amorphous(mtmp->data) || passes_walls(mtmp->data)
1171 || noncorporeal(mtmp->data) || unsolid(mtmp->data)
1173 && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 2
1174 && mtmp->mcansee && haseyes(mtmp->data)
1175 && !Is_rogue_level(&u.uz)
1176 && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) {
1178 m.has_offense = MUSE_SCR_EARTH;
1181 nomore(MUSE_SCR_FIRE);
1182 if (obj->otyp == SCR_FIRE && resists_fire(mtmp)
1183 && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 2
1184 && mtmp->mcansee && haseyes(mtmp->data)) {
1186 m.has_offense = MUSE_SCR_FIRE;
1190 return (boolean) !!m.has_offense;
1197 register struct monst *mtmp;
1198 register struct obj *otmp;
1202 boolean reveal_invis = FALSE;
1203 if (mtmp != &youmonst) {
1204 mtmp->msleeping = 0;
1205 if (mtmp->m_ap_type)
1208 switch (otmp->otyp) {
1210 reveal_invis = TRUE;
1211 if (mtmp == &youmonst) {
1213 makeknown(WAN_STRIKING);
1215 shieldeff(u.ux, u.uy);
1217 } else if (rnd(20) < 10 + u.uac) {
1218 pline_The("wand hits you!");
1220 if (Half_spell_damage)
1221 tmp = (tmp + 1) / 2;
1222 losehp(tmp, "wand", KILLED_BY_AN);
1224 pline_The("wand misses you.");
1227 } else if (resists_magm(mtmp)) {
1228 shieldeff(mtmp->mx, mtmp->my);
1230 } else if (rnd(20) < 10 + find_mac(mtmp)) {
1232 hit("wand", mtmp, exclam(tmp));
1233 (void) resist(mtmp, otmp->oclass, tmp, TELL);
1234 if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
1235 makeknown(WAN_STRIKING);
1238 if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
1239 makeknown(WAN_STRIKING);
1242 case WAN_TELEPORTATION:
1243 if (mtmp == &youmonst) {
1245 makeknown(WAN_TELEPORTATION);
1248 /* for consistency with zap.c, don't identify */
1249 if (mtmp->ispriest && *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
1250 if (cansee(mtmp->mx, mtmp->my))
1251 pline("%s resists the magic!", Monnam(mtmp));
1252 } else if (!tele_restrict(mtmp))
1253 (void) rloc(mtmp, TRUE);
1256 case WAN_CANCELLATION:
1257 case SPE_CANCELLATION:
1258 (void) cancel_monst(mtmp, otmp, FALSE, TRUE, FALSE);
1262 if (mtmp->mhp > 0 && cansee(bhitpos.x, bhitpos.y)
1263 && !canspotmon(mtmp))
1264 map_invisible(bhitpos.x, bhitpos.y);
1269 /* A modified bhit() for monsters. Based on bhit() in zap.c. Unlike
1270 * buzz(), bhit() doesn't take into account the possibility of a monster
1271 * zapping you, so we need a special function for it. (Unless someone wants
1272 * to merge the two functions...)
1275 mbhit(mon, range, fhitm, fhito, obj)
1276 struct monst *mon; /* monster shooting the wand */
1277 register int range; /* direction and range */
1278 int FDECL((*fhitm), (MONST_P, OBJ_P));
1279 int FDECL((*fhito), (OBJ_P, OBJ_P)); /* fns called when mon/obj hit */
1280 struct obj *obj; /* 2nd arg to fhitm/fhito */
1282 register struct monst *mtmp;
1283 register struct obj *otmp;
1287 bhitpos.x = mon->mx;
1288 bhitpos.y = mon->my;
1289 ddx = sgn(mon->mux - mon->mx);
1290 ddy = sgn(mon->muy - mon->my);
1292 while (range-- > 0) {
1305 if (find_drawbridge(&x, &y))
1306 switch (obj->otyp) {
1308 destroy_drawbridge(x, y);
1310 if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
1311 (*fhitm)(&youmonst, obj);
1313 } else if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) {
1314 if (cansee(bhitpos.x, bhitpos.y) && !canspotmon(mtmp))
1315 map_invisible(bhitpos.x, bhitpos.y);
1316 (*fhitm)(mtmp, obj);
1319 /* modified by GAN to hit all objects */
1321 int hitanything = 0;
1322 register struct obj *next_obj;
1324 for (otmp = level.objects[bhitpos.x][bhitpos.y]; otmp;
1326 /* Fix for polymorph bug, Tim Wright */
1327 next_obj = otmp->nexthere;
1328 hitanything += (*fhito)(otmp, obj);
1333 typ = levl[bhitpos.x][bhitpos.y].typ;
1334 if (IS_DOOR(typ) || typ == SDOOR) {
1335 switch (obj->otyp) {
1336 /* note: monsters don't use opening or locking magic
1337 at present, but keep these as placeholders */
1341 if (doorlock(obj, bhitpos.x, bhitpos.y)) {
1343 makeknown(obj->otyp);
1344 /* if a shop door gets broken, add it to
1345 the shk's fix list (no cost to player) */
1346 if (levl[bhitpos.x][bhitpos.y].doormask == D_BROKEN
1347 && *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE))
1348 add_damage(bhitpos.x, bhitpos.y, 0L);
1354 || (IS_DOOR(typ) && (levl[bhitpos.x][bhitpos.y].doormask
1355 & (D_LOCKED | D_CLOSED)))) {
1363 /* Perform an offensive action for a monster. Must be called immediately
1364 * after find_offensive(). Return values are same as use_defensive().
1371 struct obj *otmp = m.offensive;
1374 /* offensive potions are not drunk, they're thrown */
1375 if (otmp->oclass != POTION_CLASS && (i = precheck(mtmp, otmp)) != 0)
1377 oseen = otmp && canseemon(mtmp);
1379 switch (m.has_offense) {
1380 case MUSE_WAN_DEATH:
1381 case MUSE_WAN_SLEEP:
1384 case MUSE_WAN_LIGHTNING:
1385 case MUSE_WAN_MAGIC_MISSILE:
1386 mzapmsg(mtmp, otmp, FALSE);
1389 makeknown(otmp->otyp);
1391 buzz((int) (-30 - (otmp->otyp - WAN_MAGIC_MISSILE)),
1392 (otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6, mtmp->mx, mtmp->my,
1393 sgn(mtmp->mux - mtmp->mx), sgn(mtmp->muy - mtmp->my));
1395 return (mtmp->mhp <= 0) ? 1 : 2;
1396 case MUSE_FIRE_HORN:
1397 case MUSE_FROST_HORN:
1399 makeknown(otmp->otyp);
1400 pline("%s plays a %s!", Monnam(mtmp), xname(otmp));
1402 You_hear("a horn being played.");
1405 buzz(-30 - ((otmp->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1),
1406 rn1(6, 6), mtmp->mx, mtmp->my, sgn(mtmp->mux - mtmp->mx),
1407 sgn(mtmp->muy - mtmp->my));
1409 return (mtmp->mhp <= 0) ? 1 : 2;
1410 case MUSE_WAN_TELEPORTATION:
1411 case MUSE_WAN_STRIKING:
1413 mzapmsg(mtmp, otmp, FALSE);
1416 mbhit(mtmp, rn1(8, 6), mbhitm, bhito, otmp);
1419 case MUSE_SCR_EARTH: {
1420 /* TODO: handle steeds */
1422 /* don't use monster fields after killing it */
1423 boolean confused = (mtmp->mconf ? TRUE : FALSE);
1424 int mmx = mtmp->mx, mmy = mtmp->my;
1425 boolean is_cursed = otmp->cursed;
1427 mreadmsg(mtmp, otmp);
1428 /* Identify the scroll */
1429 if (canspotmon(mtmp)) {
1430 pline_The("%s rumbles %s %s!", ceiling(mtmp->mx, mtmp->my),
1431 otmp->blessed ? "around" : "above", mon_nam(mtmp));
1433 makeknown(otmp->otyp);
1434 } else if (cansee(mtmp->mx, mtmp->my)) {
1435 pline_The("%s rumbles in the middle of nowhere!",
1436 ceiling(mtmp->mx, mtmp->my));
1438 map_invisible(mtmp->mx, mtmp->my);
1440 makeknown(otmp->otyp);
1443 /* Loop through the surrounding squares */
1444 for (x = mmx - 1; x <= mmx + 1; x++) {
1445 for (y = mmy - 1; y <= mmy + 1; y++) {
1446 /* Is this a suitable spot? */
1447 if (isok(x, y) && !closed_door(x, y)
1448 && !IS_ROCK(levl[x][y].typ) && !IS_AIR(levl[x][y].typ)
1449 && (((x == mmx) && (y == mmy)) ? !otmp->blessed
1451 && (x != u.ux || y != u.uy)) {
1452 (void) drop_boulder_on_monster(x, y, confused, FALSE);
1456 m_useup(mtmp, otmp);
1457 /* Attack the player */
1458 if (distmin(mmx, mmy, u.ux, u.uy) == 1 && !is_cursed) {
1459 drop_boulder_on_player(confused, !is_cursed, FALSE, TRUE);
1462 return (mtmp->mhp <= 0) ? 1 : 2;
1465 case MUSE_SCR_FIRE: {
1466 boolean vis = cansee(mtmp->mx, mtmp->my);
1468 mreadmsg(mtmp, otmp);
1471 pline("Oh, what a pretty fire!");
1473 struct monst *mtmp2;
1477 pline_The("scroll erupts in a tower of flame!");
1478 shieldeff(mtmp->mx, mtmp->my);
1479 pline("%s is uninjured.", Monnam(mtmp));
1480 (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
1481 (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
1482 (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
1483 num = (2 * (rn1(3, 3) + 2 * bcsign(otmp)) + 1) / 3;
1484 if (Fire_resistance)
1485 You("are not harmed.");
1487 if (Half_spell_damage)
1488 num = (num + 1) / 2;
1490 losehp(num, "scroll of fire", KILLED_BY_AN);
1491 for (mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) {
1492 if (DEADMONSTER(mtmp2)) continue;
1493 if (mtmp == mtmp2) continue;
1494 if (dist2(mtmp2->mx, mtmp2->my, mtmp->mx, mtmp->my) < 3) {
1495 if (resists_fire(mtmp2)) continue;
1497 if (resists_cold(mtmp2))
1498 mtmp2->mhp -= 3 * num;
1499 if (mtmp2->mhp < 1) {
1509 case MUSE_POT_PARALYSIS:
1510 case MUSE_POT_BLINDNESS:
1511 case MUSE_POT_CONFUSION:
1512 case MUSE_POT_SLEEPING:
1514 /* Note: this setting of dknown doesn't suffice. A monster
1515 * which is out of sight might throw and it hits something _in_
1516 * sight, a problem not existing with wands because wand rays
1517 * are not objects. Also set dknown in mthrowu.c.
1519 if (cansee(mtmp->mx, mtmp->my)) {
1521 pline("%s hurls %s!", Monnam(mtmp), singular(otmp, doname));
1523 m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux - mtmp->mx),
1524 sgn(mtmp->muy - mtmp->my),
1525 distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy), otmp);
1528 return 0; /* i.e. an exploded wand */
1530 impossible("%s wanted to perform action %d?", Monnam(mtmp),
1538 rnd_offensive_item(mtmp)
1541 struct permonst *pm = mtmp->data;
1542 int difficulty = monstr[(monsndx(pm))];
1544 if (is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1545 || pm->mlet == S_GHOST || pm->mlet == S_KOP)
1547 if (difficulty > 7 && !rn2(35))
1549 switch (rn2(9 - (difficulty < 4) + 4 * (difficulty > 6))) {
1551 struct obj *helmet = which_armor(mtmp, W_ARMH);
1553 if ((helmet && is_metallic(helmet)) || amorphous(pm)
1554 || passes_walls(pm) || noncorporeal(pm) || unsolid(pm))
1556 } /* fall through */
1558 return WAN_STRIKING;
1562 return POT_CONFUSION;
1564 return POT_BLINDNESS;
1566 return POT_SLEEPING;
1568 return POT_PARALYSIS;
1571 return WAN_MAGIC_MISSILE;
1579 return WAN_LIGHTNING;
1585 #define MUSE_POT_GAIN_LEVEL 1
1586 #define MUSE_WAN_MAKE_INVISIBLE 2
1587 #define MUSE_POT_INVISIBILITY 3
1588 #define MUSE_POLY_TRAP 4
1589 #define MUSE_WAN_POLYMORPH 5
1590 #define MUSE_POT_SPEED 6
1591 #define MUSE_WAN_SPEED_MONSTER 7
1592 #define MUSE_BULLWHIP 8
1593 #define MUSE_POT_POLYMORPH 9
1599 register struct obj *obj;
1600 struct permonst *mdat = mtmp->data;
1601 int x = mtmp->mx, y = mtmp->my;
1603 int xx, yy, pmidx = NON_PM;
1604 boolean immobile = (mdat->mmove == 0);
1605 boolean stuck = (mtmp == u.ustuck);
1607 m.misc = (struct obj *) 0;
1609 if (is_animal(mdat) || mindless(mdat))
1611 if (u.uswallow && stuck)
1614 /* We arbitrarily limit to times when a player is nearby for the
1615 * same reason as Junior Pac-Man doesn't have energizers eaten until
1616 * you can see them...
1618 if (dist2(x, y, mtmp->mux, mtmp->muy) > 36)
1621 if (!stuck && !immobile && (mtmp->cham == NON_PM)
1622 && monstr[(pmidx = monsndx(mdat))] < 6) {
1623 boolean ignore_boulders = (verysmall(mdat) || throws_rocks(mdat)
1624 || passes_walls(mdat)),
1625 diag_ok = !NODIAG(pmidx);
1627 for (xx = x - 1; xx <= x + 1; xx++)
1628 for (yy = y - 1; yy <= y + 1; yy++)
1629 if (isok(xx, yy) && (xx != u.ux || yy != u.uy)
1630 && (diag_ok || xx == x || yy == y)
1631 && ((xx == x && yy == y) || !level.monsters[xx][yy]))
1632 if ((t = t_at(xx, yy)) != 0
1633 && (ignore_boulders || !sobj_at(BOULDER, xx, yy))
1634 && !onscary(xx, yy, mtmp)) {
1635 /* use trap if it's the correct type */
1636 if (t->ttyp == POLY_TRAP) {
1639 m.has_misc = MUSE_POLY_TRAP;
1647 #define nomore(x) if (m.has_misc == x) continue
1649 * [bug?] Choice of item is not prioritized; the last viable one
1650 * in the monster's inventory will be chosen.
1651 * 'nomore()' is nearly worthless because it only screens checking
1652 * of duplicates when there is no alternate type in between them.
1654 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
1655 /* Monsters shouldn't recognize cursed items; this kludge is
1656 necessary to prevent serious problems though... */
1657 if (obj->otyp == POT_GAIN_LEVEL
1659 || (!mtmp->isgd && !mtmp->isshk && !mtmp->ispriest))) {
1661 m.has_misc = MUSE_POT_GAIN_LEVEL;
1663 nomore(MUSE_BULLWHIP);
1664 if (obj->otyp == BULLWHIP && !mtmp->mpeaceful
1665 /* the random test prevents whip-wielding
1666 monster from attempting disarm every turn */
1667 && uwep && !rn2(5) && obj == MON_WEP(mtmp)
1668 /* hero's location must be known and adjacent */
1669 && mtmp->mux == u.ux && mtmp->muy == u.uy
1670 && distu(mtmp->mx, mtmp->my) <= 2
1671 /* don't bother if it can't work (this doesn't
1672 prevent cursed weapons from being targetted) */
1673 && (canletgo(uwep, "")
1674 || (u.twoweap && canletgo(uswapwep, "")))) {
1676 m.has_misc = MUSE_BULLWHIP;
1678 /* Note: peaceful/tame monsters won't make themselves
1679 * invisible unless you can see them. Not really right, but...
1681 nomore(MUSE_WAN_MAKE_INVISIBLE);
1682 if (obj->otyp == WAN_MAKE_INVISIBLE && obj->spe > 0 && !mtmp->minvis
1683 && !mtmp->invis_blkd && (!mtmp->mpeaceful || See_invisible)
1684 && (!attacktype(mtmp->data, AT_GAZE) || mtmp->mcan)) {
1686 m.has_misc = MUSE_WAN_MAKE_INVISIBLE;
1688 nomore(MUSE_POT_INVISIBILITY);
1689 if (obj->otyp == POT_INVISIBILITY && !mtmp->minvis
1690 && !mtmp->invis_blkd && (!mtmp->mpeaceful || See_invisible)
1691 && (!attacktype(mtmp->data, AT_GAZE) || mtmp->mcan)) {
1693 m.has_misc = MUSE_POT_INVISIBILITY;
1695 nomore(MUSE_WAN_SPEED_MONSTER);
1696 if (obj->otyp == WAN_SPEED_MONSTER && obj->spe > 0
1697 && mtmp->mspeed != MFAST && !mtmp->isgd) {
1699 m.has_misc = MUSE_WAN_SPEED_MONSTER;
1701 nomore(MUSE_POT_SPEED);
1702 if (obj->otyp == POT_SPEED && mtmp->mspeed != MFAST && !mtmp->isgd) {
1704 m.has_misc = MUSE_POT_SPEED;
1706 nomore(MUSE_WAN_POLYMORPH);
1707 if (obj->otyp == WAN_POLYMORPH && obj->spe > 0
1708 && (mtmp->cham == NON_PM) && monstr[monsndx(mdat)] < 6) {
1710 m.has_misc = MUSE_WAN_POLYMORPH;
1712 nomore(MUSE_POT_POLYMORPH);
1713 if (obj->otyp == POT_POLYMORPH && (mtmp->cham == NON_PM)
1714 && monstr[monsndx(mdat)] < 6) {
1716 m.has_misc = MUSE_POT_POLYMORPH;
1719 return (boolean) !!m.has_misc;
1723 /* type of monster to polymorph into; defaults to one suitable for the
1724 current level rather than the totally arbitrary choice of newcham() */
1725 static struct permonst *
1726 muse_newcham_mon(mon)
1731 if ((m_armr = which_armor(mon, W_ARM)) != 0) {
1732 if (Is_dragon_scales(m_armr))
1733 return Dragon_scales_to_pm(m_armr);
1734 else if (Is_dragon_mail(m_armr))
1735 return Dragon_mail_to_pm(m_armr);
1745 struct obj *otmp = m.misc;
1746 boolean vis, vismon, oseen;
1749 if ((i = precheck(mtmp, otmp)) != 0)
1751 vis = cansee(mtmp->mx, mtmp->my);
1752 vismon = canseemon(mtmp);
1753 oseen = otmp && vismon;
1755 switch (m.has_misc) {
1756 case MUSE_POT_GAIN_LEVEL:
1757 mquaffmsg(mtmp, otmp);
1759 if (Can_rise_up(mtmp->mx, mtmp->my, &u.uz)) {
1760 register int tolev = depth(&u.uz) - 1;
1763 get_level(&tolevel, tolev);
1764 /* insurance against future changes... */
1765 if (on_level(&tolevel, &u.uz))
1768 pline("%s rises up, through the %s!", Monnam(mtmp),
1769 ceiling(mtmp->mx, mtmp->my));
1770 if (!objects[POT_GAIN_LEVEL].oc_name_known
1771 && !objects[POT_GAIN_LEVEL].oc_uname)
1774 m_useup(mtmp, otmp);
1775 migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM,
1781 pline("%s looks uneasy.", Monnam(mtmp));
1782 if (!objects[POT_GAIN_LEVEL].oc_name_known
1783 && !objects[POT_GAIN_LEVEL].oc_uname)
1786 m_useup(mtmp, otmp);
1791 pline("%s seems more experienced.", Monnam(mtmp));
1793 makeknown(POT_GAIN_LEVEL);
1794 m_useup(mtmp, otmp);
1795 if (!grow_up(mtmp, (struct monst *) 0))
1797 /* grew into genocided monster */
1799 case MUSE_WAN_MAKE_INVISIBLE:
1800 case MUSE_POT_INVISIBILITY:
1801 if (otmp->otyp == WAN_MAKE_INVISIBLE) {
1802 mzapmsg(mtmp, otmp, TRUE);
1805 mquaffmsg(mtmp, otmp);
1806 /* format monster's name before altering its visibility */
1807 Strcpy(nambuf, mon_nam(mtmp));
1808 mon_set_minvis(mtmp);
1809 if (vismon && mtmp->minvis) { /* was seen, now invisible */
1810 if (canspotmon(mtmp))
1811 pline("%s body takes on a %s transparency.",
1812 upstart(s_suffix(nambuf)),
1813 Hallucination ? "normal" : "strange");
1815 pline("Suddenly you cannot see %s.", nambuf);
1817 makeknown(otmp->otyp);
1819 if (otmp->otyp == POT_INVISIBILITY) {
1821 you_aggravate(mtmp);
1822 m_useup(mtmp, otmp);
1825 case MUSE_WAN_SPEED_MONSTER:
1826 mzapmsg(mtmp, otmp, TRUE);
1828 mon_adjust_speed(mtmp, 1, otmp);
1830 case MUSE_POT_SPEED:
1831 mquaffmsg(mtmp, otmp);
1832 /* note difference in potion effect due to substantially
1833 different methods of maintaining speed ratings:
1834 player's character becomes "very fast" temporarily;
1835 monster becomes "one stage faster" permanently */
1836 mon_adjust_speed(mtmp, 1, otmp);
1837 m_useup(mtmp, otmp);
1839 case MUSE_WAN_POLYMORPH:
1840 mzapmsg(mtmp, otmp, TRUE);
1842 (void) newcham(mtmp, muse_newcham_mon(mtmp), TRUE, FALSE);
1844 makeknown(WAN_POLYMORPH);
1846 case MUSE_POT_POLYMORPH:
1847 mquaffmsg(mtmp, otmp);
1849 pline("%s suddenly mutates!", Monnam(mtmp));
1850 (void) newcham(mtmp, muse_newcham_mon(mtmp), FALSE, FALSE);
1852 makeknown(POT_POLYMORPH);
1853 m_useup(mtmp, otmp);
1855 case MUSE_POLY_TRAP:
1857 pline("%s deliberately %s onto a polymorph trap!", Monnam(mtmp),
1858 makeplural(locomotion(mtmp->data, "jump")));
1860 seetrap(t_at(trapx, trapy));
1862 /* don't use rloc() due to worms */
1863 remove_monster(mtmp->mx, mtmp->my);
1864 newsym(mtmp->mx, mtmp->my);
1865 place_monster(mtmp, trapx, trapy);
1868 newsym(trapx, trapy);
1870 (void) newcham(mtmp, (struct permonst *) 0, FALSE, FALSE);
1873 /* attempt to disarm hero */
1875 const char *The_whip = vismon ? "The bullwhip" : "A whip";
1876 int where_to = rn2(4);
1877 struct obj *obj = uwep;
1879 char the_weapon[BUFSZ];
1881 if (!obj || !canletgo(obj, "")
1882 || (u.twoweap && canletgo(uswapwep, "") && rn2(2)))
1885 break; /* shouldn't happen after find_misc() */
1887 Strcpy(the_weapon, the(xname(obj)));
1888 hand = body_part(HAND);
1890 hand = makeplural(hand);
1893 pline("%s flicks a bullwhip towards your %s!", Monnam(mtmp),
1895 if (obj->otyp == HEAVY_IRON_BALL) {
1896 pline("%s fails to wrap around %s.", The_whip, the_weapon);
1899 pline("%s wraps around %s you're wielding!", The_whip,
1902 pline("%s welded to your %s%c",
1903 !is_plural(obj) ? "It is" : "They are", hand,
1904 !obj->bknown ? '!' : '.');
1905 /* obj->bknown = 1; */ /* welded() takes care of this */
1909 pline_The("whip slips free."); /* not `The_whip' */
1911 } else if (where_to == 3 && mon_hates_silver(mtmp)
1912 && objects[obj->otyp].oc_material == SILVER) {
1913 /* this monster won't want to catch a silver
1914 weapon; drop it at hero's feet instead */
1917 remove_worn_item(obj, FALSE);
1920 case 1: /* onto floor beneath mon */
1921 pline("%s yanks %s from your %s!", Monnam(mtmp), the_weapon,
1923 place_object(obj, mtmp->mx, mtmp->my);
1925 case 2: /* onto floor beneath you */
1926 pline("%s yanks %s to the %s!", Monnam(mtmp), the_weapon,
1927 surface(u.ux, u.uy));
1930 case 3: /* into mon's inventory */
1931 pline("%s snatches %s!", Monnam(mtmp), the_weapon);
1932 (void) mpickobj(mtmp, obj);
1939 return 0; /* i.e. an exploded wand */
1941 impossible("%s wanted to perform action %d?", Monnam(mtmp),
1952 pline("For some reason, %s presence is known to you.",
1953 s_suffix(noit_mon_nam(mtmp)));
1956 cliparound(mtmp->mx, mtmp->my);
1958 show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp));
1960 You_feel("aggravated at %s.", noit_mon_nam(mtmp));
1961 display_nhwindow(WIN_MAP, TRUE);
1963 if (unconscious()) {
1965 nomovemsg = "Aggravated, you are jolted into full consciousness.";
1967 newsym(mtmp->mx, mtmp->my);
1968 if (!canspotmon(mtmp))
1969 map_invisible(mtmp->mx, mtmp->my);
1976 struct permonst *pm = mtmp->data;
1977 int difficulty = monstr[(monsndx(pm))];
1979 if (is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1980 || pm->mlet == S_GHOST || pm->mlet == S_KOP)
1982 /* Unlike other rnd_item functions, we only allow _weak_ monsters
1983 * to have this item; after all, the item will be used to strengthen
1984 * the monster and strong monsters won't use it at all...
1986 if (difficulty < 6 && !rn2(30))
1987 return rn2(6) ? POT_POLYMORPH : WAN_POLYMORPH;
1989 if (!rn2(40) && !nonliving(pm) && !is_vampshifter(mtmp))
1990 return AMULET_OF_LIFE_SAVING;
1996 return rn2(6) ? POT_SPEED : WAN_SPEED_MONSTER;
1998 if (mtmp->mpeaceful && !See_invisible)
2000 return rn2(6) ? POT_INVISIBILITY : WAN_MAKE_INVISIBLE;
2002 return POT_GAIN_LEVEL;
2009 searches_for_item(mon, obj)
2013 int typ = obj->otyp;
2015 if (is_animal(mon->data) || mindless(mon->data)
2016 || mon->data == &mons[PM_GHOST]) /* don't loot bones piles */
2019 if (typ == WAN_MAKE_INVISIBLE || typ == POT_INVISIBILITY)
2020 return (boolean) (!mon->minvis && !mon->invis_blkd
2021 && !attacktype(mon->data, AT_GAZE));
2022 if (typ == WAN_SPEED_MONSTER || typ == POT_SPEED)
2023 return (boolean) (mon->mspeed != MFAST);
2025 switch (obj->oclass) {
2029 if (typ == WAN_DIGGING)
2030 return (boolean) !is_floater(mon->data);
2031 if (typ == WAN_POLYMORPH)
2032 return (boolean) (monstr[monsndx(mon->data)] < 6);
2033 if (objects[typ].oc_dir == RAY || typ == WAN_STRIKING
2034 || typ == WAN_TELEPORTATION || typ == WAN_CREATE_MONSTER)
2038 if (typ == POT_HEALING || typ == POT_EXTRA_HEALING
2039 || typ == POT_FULL_HEALING || typ == POT_POLYMORPH
2040 || typ == POT_GAIN_LEVEL || typ == POT_PARALYSIS
2041 || typ == POT_SLEEPING || typ == POT_ACID || typ == POT_CONFUSION)
2043 if (typ == POT_BLINDNESS && !attacktype(mon->data, AT_GAZE))
2047 if (typ == SCR_TELEPORTATION || typ == SCR_CREATE_MONSTER
2048 || typ == SCR_EARTH || typ == SCR_FIRE)
2052 if (typ == AMULET_OF_LIFE_SAVING)
2053 return (boolean) !(nonliving(mon->data) || is_vampshifter(mon));
2054 if (typ == AMULET_OF_REFLECTION)
2058 if (typ == PICK_AXE)
2059 return (boolean) needspick(mon->data);
2060 if (typ == UNICORN_HORN)
2061 return (boolean) (!obj->cursed && !is_unicorn(mon->data));
2062 if (typ == FROST_HORN || typ == FIRE_HORN)
2063 return (obj->spe > 0);
2067 return (boolean) (((mon->misc_worn_check & W_ARMG) != 0L
2068 && touch_petrifies(&mons[obj->corpsenm]))
2069 || (!resists_ston(mon)
2070 && cures_stoning(mon, obj, FALSE)));
2072 return (boolean) (mcould_eat_tin(mon)
2073 && (!resists_ston(mon)
2074 && cures_stoning(mon, obj, TRUE)));
2076 return (boolean) touch_petrifies(&mons[obj->corpsenm]);
2086 mon_reflects(mon, str)
2090 struct obj *orefl = which_armor(mon, W_ARMS);
2092 if (orefl && orefl->otyp == SHIELD_OF_REFLECTION) {
2094 pline(str, s_suffix(mon_nam(mon)), "shield");
2095 makeknown(SHIELD_OF_REFLECTION);
2098 } else if (arti_reflects(MON_WEP(mon))) {
2099 /* due to wielded artifact weapon */
2101 pline(str, s_suffix(mon_nam(mon)), "weapon");
2103 } else if ((orefl = which_armor(mon, W_AMUL))
2104 && orefl->otyp == AMULET_OF_REFLECTION) {
2106 pline(str, s_suffix(mon_nam(mon)), "amulet");
2107 makeknown(AMULET_OF_REFLECTION);
2110 } else if ((orefl = which_armor(mon, W_ARM))
2111 && (orefl->otyp == SILVER_DRAGON_SCALES
2112 || orefl->otyp == SILVER_DRAGON_SCALE_MAIL)) {
2114 pline(str, s_suffix(mon_nam(mon)), "armor");
2116 } else if (mon->data == &mons[PM_SILVER_DRAGON]
2117 || mon->data == &mons[PM_CHROMATIC_DRAGON]) {
2118 /* Silver dragons only reflect when mature; babies do not */
2120 pline(str, s_suffix(mon_nam(mon)), "scales");
2128 const char *fmt, *str;
2130 /* Check from outermost to innermost objects */
2131 if (EReflecting & W_ARMS) {
2133 pline(fmt, str, "shield");
2134 makeknown(SHIELD_OF_REFLECTION);
2137 } else if (EReflecting & W_WEP) {
2138 /* Due to wielded artifact weapon */
2140 pline(fmt, str, "weapon");
2142 } else if (EReflecting & W_AMUL) {
2144 pline(fmt, str, "medallion");
2145 makeknown(AMULET_OF_REFLECTION);
2148 } else if (EReflecting & W_ARM) {
2150 pline(fmt, str, uskin ? "luster" : "armor");
2152 } else if (youmonst.data == &mons[PM_SILVER_DRAGON]) {
2154 pline(fmt, str, "scales");
2160 /* TRUE if the monster ate something */
2162 munstone(mon, by_you)
2169 if (resists_ston(mon))
2171 if (mon->meating || !mon->mcanmove || mon->msleeping)
2173 mon->mstrategy &= ~STRAT_WAITFORU;
2175 tinok = mcould_eat_tin(mon);
2176 for (obj = mon->minvent; obj; obj = obj->nobj) {
2177 if (cures_stoning(mon, obj, tinok)) {
2178 mon_consume_unstone(mon, obj, by_you, TRUE);
2186 mon_consume_unstone(mon, obj, by_you, stoning)
2192 boolean vis = canseemon(mon), tinned = obj->otyp == TIN,
2193 food = obj->otyp == CORPSE || tinned,
2194 acid = obj->otyp == POT_ACID
2195 || (food && acidic(&mons[obj->corpsenm])),
2196 lizard = food && obj->corpsenm == PM_LIZARD;
2197 int nutrit = food ? dog_nutrition(mon, obj) : 0; /* also sets meating */
2199 /* give a "<mon> is slowing down" message and also remove
2200 intrinsic speed (comparable to similar effect on the hero) */
2202 mon_adjust_speed(mon, -3, (struct obj *) 0);
2205 long save_quan = obj->quan;
2208 pline("%s %s %s.", Monnam(mon),
2209 (obj->oclass == POTION_CLASS)
2211 : (obj->otyp == TIN) ? "opens and eats the contents of"
2213 distant_name(obj, doname));
2214 obj->quan = save_quan;
2217 (obj->oclass == POTION_CLASS) ? "drinking" : "chewing");
2220 /* obj is now gone */
2222 if (acid && !tinned && !resists_acid(mon)) {
2223 mon->mhp -= rnd(15);
2225 pline("%s has a very bad case of stomach acid.", Monnam(mon));
2226 if (mon->mhp <= 0) {
2227 pline("%s dies!", Monnam(mon));
2235 if (stoning && vis) {
2237 pline("What a pity - %s just ruined a future piece of art!",
2240 pline("%s seems limber!", Monnam(mon));
2242 if (lizard && (mon->mconf || mon->mstun)) {
2245 if (vis && !is_bat(mon->data) && mon->data != &mons[PM_STALKER])
2246 pline("%s seems steadier now.", Monnam(mon));
2248 if (mon->mtame && !mon->isminion && nutrit > 0) {
2249 struct edog *edog = EDOG(mon);
2251 if (edog->hungrytime < monstermoves)
2252 edog->hungrytime = monstermoves;
2253 edog->hungrytime += nutrit;
2256 /* use up monster's next move */
2257 mon->movement -= NORMAL_SPEED;
2258 mon->mlstmv = monstermoves;
2261 /* decide whether obj can cure petrification; also used when picking up */
2263 cures_stoning(mon, obj, tinok)
2268 if (obj->otyp == POT_ACID)
2270 if (obj->otyp != CORPSE && (obj->otyp != TIN || !tinok))
2272 /* corpse, or tin that mon can open */
2273 return (boolean) (obj->corpsenm == PM_LIZARD
2274 || (acidic(&mons[obj->corpsenm])
2275 && (obj->corpsenm != PM_GREEN_SLIME
2276 || slimeproof(mon->data))));
2283 struct obj *obj, *mwep;
2286 /* monkeys who manage to steal tins can't open and eat them
2287 even if they happen to also have the appropriate tool */
2288 if (is_animal(mon->data))
2291 mwep = MON_WEP(mon);
2292 welded_wep = mwep && mwelded(mwep);
2293 /* this is different from the player; tin opener or dagger doesn't
2294 have to be wielded, and knife can be used instead of dagger */
2295 for (obj = mon->minvent; obj; obj = obj->nobj) {
2296 /* if stuck with a cursed weapon, don't check rest of inventory */
2297 if (welded_wep && obj != mwep)
2300 if (obj->otyp == TIN_OPENER
2301 || (obj->oclass == WEAPON_CLASS
2302 && (objects[obj->otyp].oc_skill == P_DAGGER
2303 || objects[obj->otyp].oc_skill == P_KNIFE)))
2309 /* TRUE if monster does something to avoid turning into green slime */
2311 munslime(mon, by_you)
2315 struct obj *obj, odummy;
2318 * muse_unslime() gives "mon starts turning green", "mon zaps
2319 * itself with a wand of fire", and "mon's slime burns away"
2320 * messages. Monsters who don't get any chance at that just have
2321 * (via our caller) newcham()'s "mon turns into slime" feedback.
2324 if (slimeproof(mon->data))
2326 if (mon->meating || !mon->mcanmove || mon->msleeping)
2328 mon->mstrategy &= ~STRAT_WAITFORU;
2330 /* if monster can breathe fire, do so upon self; a monster who deals
2331 fire damage by biting, clawing, gazing, and especially exploding
2332 isn't able to cure itself of green slime with its own attack
2333 [possible extension: monst capable of casting high level clerical
2334 spells could toss pillar of fire at self--probably too suicidal] */
2335 if (!mon->mcan && !mon->mspec_used
2336 && attacktype_fordmg(mon->data, AT_BREA, AD_FIRE)) {
2337 odummy = zeroobj; /* otyp == STRANGE_OBJECT */
2338 return muse_unslime(mon, &odummy, by_you);
2341 for (obj = mon->minvent; obj; obj = obj->nobj)
2342 if (cures_sliming(mon, obj))
2343 return muse_unslime(mon, obj, by_you);
2345 /* TODO: check for and move onto an adjacent fire trap */
2350 /* mon uses an item--selected by caller--to burn away incipient slime */
2352 muse_unslime(mon, obj, by_you)
2355 boolean by_you; /* true: if mon kills itself, hero gets credit/blame */
2357 struct obj *odummyp;
2358 int otyp = obj->otyp, dmg;
2359 boolean vis = canseemon(mon), res = TRUE;
2362 pline("%s starts turning %s.", Monnam(mon),
2363 green_mon(mon) ? "into ooze" : hcolor(NH_GREEN));
2364 /* -4 => sliming, causes quiet loss of enhanced speed */
2365 mon_adjust_speed(mon, -4, (struct obj *) 0);
2367 if (otyp == STRANGE_OBJECT) {
2368 /* monster is using fire breath on self */
2370 pline("%s breathes fire on %sself.", Monnam(mon), mhim(mon));
2372 mon->mspec_used = rn1(10, 5);
2373 /* -21 => monster's fire breath; 1 => # of damage dice */
2374 (void) zhitm(mon, by_you ? 21 : -21, 1, &odummyp);
2375 } else if (otyp == SCR_FIRE) {
2378 if (cansee(mon->mx, mon->my))
2379 pline("Oh, what a pretty fire!");
2380 if (vis && !objects[otyp].oc_name_known
2381 && !objects[otyp].oc_uname)
2383 m_useup(mon, obj); /* after docall() */
2384 vis = FALSE; /* skip makeknown() below */
2385 res = FALSE; /* failed to cure sliming */
2387 m_useup(mon, obj); /* before explode() */
2388 dmg = (2 * (rn1(3, 3) + 2 * bcsign(obj)) + 1) / 3;
2389 /* -11 => monster's fireball */
2390 explode(mon->mx, mon->my, -11, dmg, SCROLL_CLASS,
2391 /* by_you: override -11 for mon but not others */
2392 by_you ? -EXPL_FIERY : EXPL_FIERY);
2394 } else { /* wand/horn of fire w/ positive charge count */
2395 mzapmsg(mon, obj, TRUE);
2397 /* -1 => monster's wand of fire; 2 => # of damage dice */
2398 (void) zhitm(mon, by_you ? 1 : -1, 2, &odummyp);
2402 if (res && mon->mhp > 0)
2403 pline("%s slime is burned away!", s_suffix(Monnam(mon)));
2404 if (otyp != STRANGE_OBJECT)
2407 /* use up monster's next move */
2408 mon->movement -= NORMAL_SPEED;
2409 mon->mlstmv = monstermoves;
2413 /* decide whether obj can be used to cure green slime */
2415 cures_sliming(mon, obj)
2419 /* scroll of fire, non-empty wand or horn of fire */
2420 if (obj->otyp == SCR_FIRE)
2421 return (haseyes(mon->data) && mon->mcansee);
2422 /* hero doesn't need hands or even limbs to zap, so mon doesn't either */
2423 return ((obj->otyp == WAN_FIRE || obj->otyp == FIRE_HORN)
2427 /* TRUE if monster appears to be green; for active TEXTCOLOR, we go by
2428 the display color, otherwise we just pick things that seem plausibly
2429 green (which doesn't necessarily match the TEXTCOLOR categorization) */
2434 struct permonst *ptr = mon->data;
2439 if (iflags.use_color)
2440 return (ptr->mcolor == CLR_GREEN || ptr->mcolor == CLR_BRIGHT_GREEN);
2443 if (strstri(ptr->mname, "green"))
2445 switch (monsndx(ptr)) {
2446 case PM_FOREST_CENTAUR:
2447 case PM_GARTER_SNAKE:
2458 if (is_elf(ptr) && !is_prince(ptr) && !is_lord(ptr)
2459 && ptr != &mons[PM_GREY_ELF])