1 /* NetHack 3.6 muse.c $NHDT-Date: 1561053256 2019/06/20 17:54:16 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.97 $ */
2 /* Copyright (C) 1990 by Ken Arromdee */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020 */
8 /* JNetHack may be freely redistributed. See license for details. */
11 * Monster item usage routines.
16 boolean m_using = FALSE;
18 /* Let monsters use magic items. Arbitrary assumptions: Monsters only use
19 * scrolls when they can see, monsters know when wands have 0 charges,
20 * monsters cannot recognize if items are cursed are not, monsters which
21 * are confused don't know not to read scrolls, etc....
24 STATIC_DCL struct permonst *FDECL(muse_newcham_mon, (struct monst *));
25 STATIC_DCL int FDECL(precheck, (struct monst *, struct obj *));
26 STATIC_DCL void FDECL(mzapwand, (struct monst *, struct obj *, BOOLEAN_P));
27 STATIC_DCL void FDECL(mplayhorn, (struct monst *, struct obj *, BOOLEAN_P));
28 STATIC_DCL void FDECL(mreadmsg, (struct monst *, struct obj *));
29 STATIC_DCL void FDECL(mquaffmsg, (struct monst *, struct obj *));
30 STATIC_DCL boolean FDECL(m_use_healing, (struct monst *));
31 STATIC_PTR int FDECL(mbhitm, (struct monst *, struct obj *));
32 STATIC_DCL void FDECL(mbhit, (struct monst *, int,
33 int FDECL((*), (MONST_P, OBJ_P)),
34 int FDECL((*), (OBJ_P, OBJ_P)), struct obj *));
35 STATIC_DCL void FDECL(you_aggravate, (struct monst *));
36 STATIC_DCL void FDECL(mon_consume_unstone, (struct monst *, struct obj *,
37 BOOLEAN_P, BOOLEAN_P));
38 STATIC_DCL boolean FDECL(cures_stoning, (struct monst *, struct obj *,
40 STATIC_DCL boolean FDECL(mcould_eat_tin, (struct monst *));
41 STATIC_DCL boolean FDECL(muse_unslime, (struct monst *, struct obj *,
42 struct trap *, BOOLEAN_P));
43 STATIC_DCL int FDECL(cures_sliming, (struct monst *, struct obj *));
44 STATIC_DCL boolean FDECL(green_mon, (struct monst *));
46 static struct musable {
47 struct obj *offensive;
48 struct obj *defensive;
50 int has_offense, has_defense, has_misc;
51 /* =0, no capability; otherwise, different numbers.
52 * If it's an object, the object is also set (it's 0 otherwise).
55 static int trapx, trapy;
56 static boolean zap_oseen; /* for wands which use mbhitm and are zapped at
57 * players. We usually want an oseen local to
58 * the function, but this is impossible since the
59 * function mbhitm has to be compatible with the
60 * normal zap routines, and those routines don't
61 * remember who zapped the wand. */
63 /* Any preliminary checks which may result in the monster being unable to use
64 * the item. Returns 0 if nothing happened, 2 if the monster can't do
65 * anything (i.e. it teleported) and 1 if it's dead.
76 vis = cansee(mon->mx, mon->my);
78 if (obj->oclass == POTION_CLASS) {
81 static const char *empty = "The potion turns out to be empty.";
83 static const char *empty = "
\96ò
\82Í
\8bó
\82Á
\82Û
\82Å
\82 \82é
\82±
\82Æ
\82ª
\82í
\82©
\82Á
\82½
\81D";
84 const char *potion_descr;
87 potion_descr = OBJ_DESCR(objects[obj->otyp]);
89 if (potion_descr && !strcmp(potion_descr, "milky")) {
91 if (potion_descr && !strcmp(potion_descr, "
\83~
\83\8b\83N
\90F
\82Ì")) {
92 if (!(mvitals[PM_GHOST].mvflags & G_GONE)
93 && !rn2(POTION_OCCUPANT_CHANCE(mvitals[PM_GHOST].born))) {
94 if (!enexto(&cc, mon->mx, mon->my, &mons[PM_GHOST]))
98 mtmp = makemon(&mons[PM_GHOST], cc.x, cc.y, NO_MM_FLAGS);
106 "As %s opens the bottle, an enormous %s emerges!",
108 Hallucination ? rndmonnam(NULL)
109 : (const char *) "ghost");
112 "%s
\82ª
\95r
\82ð
\8aJ
\82¯
\82é
\82Æ
\81C
\8b\90\91å
\82È%s
\82ª
\8fo
\82Ä
\82«
\82½
\81I",
114 Hallucination ? rndmonnam(NULL)
115 : (const char *)"
\97H
\97ì");
118 pline("%s is frightened to death, and unable to move.",
120 pline("%s
\82Í
\82Ü
\82Á
\82³
\82¨
\82É
\82È
\82Á
\82Ä
\8bÁ
\82«
\81C
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81D",
123 paralyze_monst(mon, 3);
129 if (potion_descr && !strcmp(potion_descr, "smoky")
131 if (potion_descr && !strcmp(potion_descr, "
\89\8c\82Ì
\8fo
\82Ä
\82¢
\82é")
132 && !(mvitals[PM_DJINNI].mvflags & G_GONE)
133 && !rn2(POTION_OCCUPANT_CHANCE(mvitals[PM_DJINNI].born))) {
134 if (!enexto(&cc, mon->mx, mon->my, &mons[PM_DJINNI]))
138 mtmp = makemon(&mons[PM_DJINNI], cc.x, cc.y, NO_MM_FLAGS);
145 pline("In a cloud of smoke, %s emerges!", a_monnam(mtmp));
147 pline("
\89\8c\82Ì
\92\86\82©
\82ç
\81C%s
\82ª
\8c»
\82í
\82ê
\82½
\81I", a_monnam(mtmp));
149 pline("%s speaks.", vis ? Monnam(mtmp) : Something);
151 pline("%s
\82Í
\98b
\82µ
\82½
\81D", vis ? Monnam(mtmp) : Something);
152 /* I suspect few players will be upset that monsters */
153 /* can't wish for wands of death here.... */
156 verbalize("You freed me!");
158 verbalize("
\89ð
\95ú
\82µ
\82Ä
\82
\82ê
\82½
\82Ì
\82Í
\82¨
\91O
\82©
\81I");
163 verbalize("It is about time.");
165 verbalize("
\82³
\82ç
\82Î
\82¾
\81I");
168 pline("%s vanishes.", Monnam(mtmp));
170 pline("%s
\82Í
\8fÁ
\82¦
\82½
\81D", Monnam(mtmp));
177 if (obj->oclass == WAND_CLASS && obj->cursed
178 && !rn2(WAND_BACKFIRE_CHANCE)) {
179 int dam = d(obj->spe + 2, 6);
181 /* 3.6.1: no Deaf filter; 'if' message doesn't warrant it, 'else'
182 message doesn't need it since You_hear() has one of its own */
185 pline("%s zaps %s, which suddenly explodes!", Monnam(mon),
188 pline("%s
\82ª%s
\82ð
\82Ó
\82è
\82©
\82´
\82·
\82Æ
\81C
\82»
\82ê
\82Í
\93Ë
\91R
\94\9a\94
\82µ
\82½
\81I", Monnam(mon),
192 /* same near/far threshold as mzapwand() */
193 int range = couldsee(mon->mx, mon->my) /* 9 or 5 */
194 ? (BOLT_LIM + 1) : (BOLT_LIM - 3);
197 You_hear("a zap and an explosion %s.",
198 (distu(mon->mx, mon->my) <= range * range)
199 ? "nearby" : "in the distance");
201 You_hear("%s
\82
\82Ì
\8fñ
\82Ì
\89¹
\82Æ
\94\9a\94
\89¹
\82ð
\95·
\82¢
\82½
\81D",
202 (distu(mon->mx, mon->my) <= range * range)
203 ? "
\8bß" : "
\89\93");
208 if (DEADMONSTER(mon)) {
209 monkilled(mon, "", AD_RBRE);
212 m.has_defense = m.has_offense = m.has_misc = 0;
213 /* Only one needed to be set to 0 but the others are harmless */
218 /* when a monster zaps a wand give a message, deduct a charge, and if it
219 isn't directly seen, remove hero's memory of the number of charges */
221 mzapwand(mtmp, otmp, self)
226 if (!canseemon(mtmp)) {
227 int range = couldsee(mtmp->mx, mtmp->my) /* 9 or 5 */
228 ? (BOLT_LIM + 1) : (BOLT_LIM - 3);
231 You_hear("a %s zap.", (distu(mtmp->mx, mtmp->my) <= range * range)
232 ? "nearby" : "distant");
234 You_hear("%s
\82
\82Å
\8fñ
\82Ì
\89¹
\82ð
\95·
\82¢
\82½
\81D",
235 (distu(mtmp->mx, mtmp->my) <= range * range)
236 ? "
\8bß" : "
\89\93");
241 pline("%s zaps %sself with %s!", Monnam(mtmp), mhim(mtmp),
244 pline("%s
\82Í
\8e©
\95ª
\8e©
\90g
\82É%s
\82ð
\82Ó
\82è
\82©
\82´
\82µ
\82½
\81I", Monnam(mtmp),
249 pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp)));
251 pline("%s
\82Í%s
\82ð
\82Ó
\82è
\82©
\82´
\82µ
\82½
\81I", Monnam(mtmp), an(xname(otmp)));
257 /* similar to mzapwand() but for magical horns (only instrument mons play) */
259 mplayhorn(mtmp, otmp, self)
264 if (!canseemon(mtmp)) {
265 int range = couldsee(mtmp->mx, mtmp->my) /* 9 or 5 */
266 ? (BOLT_LIM + 1) : (BOLT_LIM - 3);
269 You_hear("a horn being played %s.",
270 (distu(mtmp->mx, mtmp->my) <= range * range)
271 ? "nearby" : "in the distance");
273 You_hear("%s
\82
\82Å
\83z
\83\8b\83\93\82Ì
\89¹
\82ð
\95·
\82¢
\82½
\81D",
274 (distu(mtmp->mx, mtmp->my) <= range * range)
275 ? "
\8bß" : "
\89\93");
277 otmp->known = 0; /* hero doesn't know how many charges are left */
281 pline("%s plays a %s directed at %s!", Monnam(mtmp), xname(otmp),
282 self ? mon_nam_too(mtmp, mtmp) : (char *) "you");
284 pline("%s
\82Í%s
\82É
\8cü
\82¯
\82Ä%s
\82ð
\90\81\82¢
\82½
\81I", Monnam(mtmp),
285 self ? mon_nam_too(mtmp, mtmp) : (char *) "
\82 \82È
\82½",
288 makeknown(otmp->otyp); /* (wands handle this slightly differently) */
292 otmp->spe -= 1; /* use a charge */
300 boolean vismon = canseemon(mtmp);
306 return; /* no feedback */
308 otmp->dknown = 1; /* seeing or hearing it read reveals its label */
309 /* shouldn't be able to hear curse/bless status of unseen scrolls;
310 for priest characters, bknown will always be set during naming */
311 savebknown = otmp->bknown;
312 saverole = Role_switch;
315 if (Role_if(PM_PRIEST))
318 Strcpy(onambuf, singular(otmp, doname));
319 Role_switch = saverole;
320 otmp->bknown = savebknown;
324 pline("%s reads %s!", Monnam(mtmp), onambuf);
326 pline("%s
\82Í%s
\82ð
\93Ç
\82ñ
\82¾
\81I", Monnam(mtmp), onambuf);
329 You_hear("%s reading %s.",
330 x_monnam(mtmp, ARTICLE_A, (char *) 0,
331 (SUPPRESS_IT | SUPPRESS_INVISIBLE | SUPPRESS_SADDLE),
335 You_hear("%s
\82ª%s
\82ð
\93Ç
\82ñ
\82Å
\82¢
\82é
\90º
\82ð
\95·
\82¢
\82½
\81D",
336 x_monnam(mtmp, ARTICLE_A, (char *)0,
337 (SUPPRESS_IT|SUPPRESS_INVISIBLE|SUPPRESS_SADDLE),
344 pline("Being confused, %s mispronounces the magic words...",
346 pline("
\8d¬
\97\90\82µ
\82Ä
\82¢
\82é
\82Ì
\82Å
\81C%s
\82Í
\8eô
\95¶
\82ð
\8aÔ
\88á
\82Á
\82Ä
\8f¥
\82¦
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D
\81D
\81D",
347 vismon ? mon_nam(mtmp) : mhe(mtmp));
351 mquaffmsg(mtmp, otmp)
355 if (canseemon(mtmp)) {
358 pline("%s drinks %s!", Monnam(mtmp), singular(otmp, doname));
360 pline("%s
\82Í%s
\82ð
\88ù
\82ñ
\82¾
\81I", Monnam(mtmp), singular(otmp, doname));
363 You_hear("a chugging sound.");
365 You_hear("
\83S
\83N
\83b
\81I
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
368 /* Defines for various types of stuff. The order in which monsters prefer
369 * to use them is determined by the order of the code logic, not the
370 * numerical order in which they are defined.
372 #define MUSE_SCR_TELEPORTATION 1
373 #define MUSE_WAN_TELEPORTATION_SELF 2
374 #define MUSE_POT_HEALING 3
375 #define MUSE_POT_EXTRA_HEALING 4
376 #define MUSE_WAN_DIGGING 5
377 #define MUSE_TRAPDOOR 6
378 #define MUSE_TELEPORT_TRAP 7
379 #define MUSE_UPSTAIRS 8
380 #define MUSE_DOWNSTAIRS 9
381 #define MUSE_WAN_CREATE_MONSTER 10
382 #define MUSE_SCR_CREATE_MONSTER 11
383 #define MUSE_UP_LADDER 12
384 #define MUSE_DN_LADDER 13
385 #define MUSE_SSTAIRS 14
386 #define MUSE_WAN_TELEPORTATION 15
387 #define MUSE_BUGLE 16
388 #define MUSE_UNICORN_HORN 17
389 #define MUSE_POT_FULL_HEALING 18
390 #define MUSE_LIZARD_CORPSE 19
392 #define MUSE_INNATE_TPT 9999
393 * We cannot use this. Since monsters get unlimited teleportation, if they
394 * were allowed to teleport at will you could never catch them. Instead,
395 * assume they only teleport at random times, despite the inconsistency
396 * that if you polymorph into one you teleport at will.
404 if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) {
406 m.has_defense = MUSE_POT_FULL_HEALING;
409 if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) {
411 m.has_defense = MUSE_POT_EXTRA_HEALING;
414 if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) {
416 m.has_defense = MUSE_POT_HEALING;
422 /* Select a defensive item/action for a monster. Returns TRUE iff one is
428 register struct obj *obj = 0;
430 int x = mtmp->mx, y = mtmp->my;
431 boolean stuck = (mtmp == u.ustuck);
432 boolean immobile = (mtmp->data->mmove == 0);
435 if (is_animal(mtmp->data) || mindless(mtmp->data))
437 if (dist2(x, y, mtmp->mux, mtmp->muy) > 25)
439 if (u.uswallow && stuck)
442 m.defensive = (struct obj *) 0;
445 /* since unicorn horns don't get used up, the monster would look
446 * silly trying to use the same cursed horn round after round
448 if (mtmp->mconf || mtmp->mstun || !mtmp->mcansee) {
449 if (!is_unicorn(mtmp->data) && !nohands(mtmp->data)) {
450 for (obj = mtmp->minvent; obj; obj = obj->nobj)
451 if (obj->otyp == UNICORN_HORN && !obj->cursed)
454 if (obj || is_unicorn(mtmp->data)) {
456 m.has_defense = MUSE_UNICORN_HORN;
461 if (mtmp->mconf || mtmp->mstun) {
462 struct obj *liztin = 0;
464 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
465 if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD) {
467 m.has_defense = MUSE_LIZARD_CORPSE;
469 } else if (obj->otyp == TIN && obj->corpsenm == PM_LIZARD) {
473 /* confused or stunned monster might not be able to open tin */
474 if (liztin && mcould_eat_tin(mtmp) && rn2(3)) {
475 m.defensive = liztin;
476 /* tin and corpse ultimately end up being handled the same */
477 m.has_defense = MUSE_LIZARD_CORPSE;
482 /* It so happens there are two unrelated cases when we might want to
483 * check specifically for healing alone. The first is when the monster
484 * is blind (healing cures blindness). The second is when the monster
485 * is peaceful; then we don't want to flee the player, and by
486 * coincidence healing is all there is that doesn't involve fleeing.
487 * These would be hard to combine because of the control flow.
488 * Pestilence won't use healing even when blind.
490 if (!mtmp->mcansee && !nohands(mtmp->data)
491 && mtmp->data != &mons[PM_PESTILENCE]) {
492 if (m_use_healing(mtmp))
496 fraction = u.ulevel < 10 ? 5 : u.ulevel < 14 ? 4 : 3;
497 if (mtmp->mhp >= mtmp->mhpmax
498 || (mtmp->mhp >= 10 && mtmp->mhp * fraction >= mtmp->mhpmax))
501 if (mtmp->mpeaceful) {
502 if (!nohands(mtmp->data)) {
503 if (m_use_healing(mtmp))
509 if (stuck || immobile) {
510 ; /* fleeing by stairs or traps is not possible */
511 } else if (levl[x][y].typ == STAIRS) {
512 if (x == xdnstair && y == ydnstair) {
513 if (!is_floater(mtmp->data))
514 m.has_defense = MUSE_DOWNSTAIRS;
515 } else if (x == xupstair && y == yupstair) {
516 m.has_defense = MUSE_UPSTAIRS;
517 } else if (sstairs.sx && x == sstairs.sx && y == sstairs.sy) {
518 if (sstairs.up || !is_floater(mtmp->data))
519 m.has_defense = MUSE_SSTAIRS;
521 } else if (levl[x][y].typ == LADDER) {
522 if (x == xupladder && y == yupladder) {
523 m.has_defense = MUSE_UP_LADDER;
524 } else if (x == xdnladder && y == ydnladder) {
525 if (!is_floater(mtmp->data))
526 m.has_defense = MUSE_DN_LADDER;
527 } else if (sstairs.sx && x == sstairs.sx && y == sstairs.sy) {
528 if (sstairs.up || !is_floater(mtmp->data))
529 m.has_defense = MUSE_SSTAIRS;
532 /* Note: trap doors take precedence over teleport traps. */
533 int xx, yy, i, locs[10][2];
534 boolean ignore_boulders = (verysmall(mtmp->data)
535 || throws_rocks(mtmp->data)
536 || passes_walls(mtmp->data)),
537 diag_ok = !NODIAG(monsndx(mtmp->data));
539 for (i = 0; i < 10; ++i) /* 10: 9 spots plus sentinel */
540 locs[i][0] = locs[i][1] = 0;
541 /* collect viable spots; monster's <mx,my> comes first */
542 locs[0][0] = x, locs[0][1] = y;
544 for (xx = x - 1; xx <= x + 1; xx++)
545 for (yy = y - 1; yy <= y + 1; yy++)
546 if (isok(xx, yy) && (xx != x || yy != y)) {
547 locs[i][0] = xx, locs[i][1] = yy;
550 /* look for a suitable trap among the viable spots */
551 for (i = 0; i < 10; ++i) {
552 xx = locs[i][0], yy = locs[i][1];
554 break; /* we've run out of spots */
555 /* skip if it's hero's location
556 or a diagonal spot and monster can't move diagonally
557 or some other monster is there */
558 if ((xx == u.ux && yy == u.uy)
559 || (xx != x && yy != y && !diag_ok)
560 || (level.monsters[xx][yy] && !(xx == x && yy == y)))
562 /* skip if there's no trap or can't/won't move onto trap */
563 if ((t = t_at(xx, yy)) == 0
564 || (!ignore_boulders && sobj_at(BOULDER, xx, yy))
565 || onscary(xx, yy, mtmp))
567 /* use trap if it's the correct type */
569 && !is_floater(mtmp->data)
570 && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest
571 && Can_fall_thru(&u.uz)) {
574 m.has_defense = MUSE_TRAPDOOR;
575 break; /* no need to look at any other spots */
576 } else if (t->ttyp == TELEP_TRAP) {
579 m.has_defense = MUSE_TELEPORT_TRAP;
584 if (nohands(mtmp->data)) /* can't use objects */
587 if (is_mercenary(mtmp->data) && (obj = m_carrying(mtmp, BUGLE)) != 0) {
591 /* Distance is arbitrary. What we really want to do is
592 * have the soldier play the bugle when it sees or
593 * remembers soldiers nearby...
595 for (xx = x - 3; xx <= x + 3; xx++) {
596 for (yy = y - 3; yy <= y + 3; yy++) {
597 if (!isok(xx, yy) || (xx == x && yy == y))
599 if ((mon = m_at(xx, yy)) != 0 && is_mercenary(mon->data)
600 && mon->data != &mons[PM_GUARD]
601 && (mon->msleeping || !mon->mcanmove)) {
603 m.has_defense = MUSE_BUGLE;
604 goto toot; /* double break */
612 /* use immediate physical escape prior to attempting magic */
613 if (m.has_defense) /* stairs, trap door or tele-trap, bugle alert */
616 /* kludge to cut down on trap destruction (particularly portals) */
618 if (t && (is_pit(t->ttyp) || t->ttyp == WEB
619 || t->ttyp == BEAR_TRAP))
620 t = 0; /* ok for monster to dig here */
622 #define nomore(x) if (m.has_defense == x) continue;
623 /* selection could be improved by collecting all possibilities
624 into an array and then picking one at random */
625 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
626 /* don't always use the same selection pattern */
627 if (m.has_defense && !rn2(3))
630 /* nomore(MUSE_WAN_DIGGING); */
631 if (m.has_defense == MUSE_WAN_DIGGING)
633 if (obj->otyp == WAN_DIGGING && obj->spe > 0 && !stuck && !t
634 && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest
635 && !is_floater(mtmp->data)
636 /* monsters digging in Sokoban can ruin things */
638 /* digging wouldn't be effective; assume they know that */
639 && !(levl[x][y].wall_info & W_NONDIGGABLE)
640 && !(Is_botlevel(&u.uz) || In_endgame(&u.uz))
641 && !(is_ice(x, y) || is_pool(x, y) || is_lava(x, y))
642 && !(mtmp->data == &mons[PM_VLAD_THE_IMPALER]
643 && In_V_tower(&u.uz))) {
645 m.has_defense = MUSE_WAN_DIGGING;
647 nomore(MUSE_WAN_TELEPORTATION_SELF);
648 nomore(MUSE_WAN_TELEPORTATION);
649 if (obj->otyp == WAN_TELEPORTATION && obj->spe > 0) {
650 /* use the TELEP_TRAP bit to determine if they know
651 * about noteleport on this level or not. Avoids
652 * ineffective re-use of teleportation. This does
653 * mean if the monster leaves the level, they'll know
654 * about teleport traps.
656 if (!level.flags.noteleport
657 || !(mtmp->mtrapseen & (1 << (TELEP_TRAP - 1)))) {
659 m.has_defense = (mon_has_amulet(mtmp))
660 ? MUSE_WAN_TELEPORTATION
661 : MUSE_WAN_TELEPORTATION_SELF;
664 nomore(MUSE_SCR_TELEPORTATION);
665 if (obj->otyp == SCR_TELEPORTATION && mtmp->mcansee
666 && haseyes(mtmp->data)
667 && (!obj->cursed || (!(mtmp->isshk && inhishop(mtmp))
668 && !mtmp->isgd && !mtmp->ispriest))) {
669 /* see WAN_TELEPORTATION case above */
670 if (!level.flags.noteleport
671 || !(mtmp->mtrapseen & (1 << (TELEP_TRAP - 1)))) {
673 m.has_defense = MUSE_SCR_TELEPORTATION;
677 if (mtmp->data != &mons[PM_PESTILENCE]) {
678 nomore(MUSE_POT_FULL_HEALING);
679 if (obj->otyp == POT_FULL_HEALING) {
681 m.has_defense = MUSE_POT_FULL_HEALING;
683 nomore(MUSE_POT_EXTRA_HEALING);
684 if (obj->otyp == POT_EXTRA_HEALING) {
686 m.has_defense = MUSE_POT_EXTRA_HEALING;
688 nomore(MUSE_WAN_CREATE_MONSTER);
689 if (obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
691 m.has_defense = MUSE_WAN_CREATE_MONSTER;
693 nomore(MUSE_POT_HEALING);
694 if (obj->otyp == POT_HEALING) {
696 m.has_defense = MUSE_POT_HEALING;
698 } else { /* Pestilence */
699 nomore(MUSE_POT_FULL_HEALING);
700 if (obj->otyp == POT_SICKNESS) {
702 m.has_defense = MUSE_POT_FULL_HEALING;
704 nomore(MUSE_WAN_CREATE_MONSTER);
705 if (obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
707 m.has_defense = MUSE_WAN_CREATE_MONSTER;
710 nomore(MUSE_SCR_CREATE_MONSTER);
711 if (obj->otyp == SCR_CREATE_MONSTER) {
713 m.has_defense = MUSE_SCR_CREATE_MONSTER;
717 return (boolean) !!m.has_defense;
721 /* Perform a defensive action for a monster. Must be called immediately
722 * after find_defensive(). Return values are 0: did something, 1: died,
723 * 2: did something and can't attack again (i.e. teleported).
729 int i, fleetim, how = 0;
730 struct obj *otmp = m.defensive;
731 boolean vis, vismon, oseen;
734 if ((i = precheck(mtmp, otmp)) != 0)
736 vis = cansee(mtmp->mx, mtmp->my);
737 vismon = canseemon(mtmp);
738 oseen = otmp && vismon;
740 /* when using defensive choice to run away, we want monster to avoid
741 rushing right straight back; don't override if already scared */
742 fleetim = !mtmp->mflee ? (33 - (30 * mtmp->mhp / mtmp->mhpmax)) : 0;
744 if (fleetim && !m->iswiz) { \
745 monflee(m, fleetim, FALSE, FALSE); \
748 switch (m.has_defense) {
749 case MUSE_UNICORN_HORN:
753 pline("%s uses a unicorn horn!", Monnam(mtmp));
755 pline("%s
\82Í
\83\86\83j
\83R
\81[
\83\93\82Ì
\8ap
\82ð
\8eg
\82Á
\82½
\81I", Monnam(mtmp));
758 pline_The("tip of %s's horn glows!", mon_nam(mtmp));
760 pline("%s
\82Ì
\8ap
\82Ì
\90æ
\92[
\82ª
\8bP
\82¢
\82½
\81I", mon_nam(mtmp));
762 if (!mtmp->mcansee) {
763 mcureblindness(mtmp, vismon);
764 } else if (mtmp->mconf || mtmp->mstun) {
765 mtmp->mconf = mtmp->mstun = 0;
768 pline("%s seems steadier now.", Monnam(mtmp));
770 pline("%s
\82Í
\95½
\90Ã
\82ð
\82Æ
\82è
\82à
\82Ç
\82µ
\82½
\81D", Monnam(mtmp));
772 impossible("No need for unicorn horn?");
777 pline("%s plays %s!", Monnam(mtmp), doname(otmp));
779 pline("%s
\82Í%s
\82ð
\90\81\82¢
\82½
\81I", Monnam(mtmp), doname(otmp));
782 You_hear("a bugle playing reveille!");
784 You_hear("
\8bN
\8f°
\83\89\83b
\83p
\82Ì
\89¹
\82ð
\95·
\82¢
\82½
\81I");
785 awaken_soldiers(mtmp);
787 case MUSE_WAN_TELEPORTATION_SELF:
788 if ((mtmp->isshk && inhishop(mtmp)) || mtmp->isgd || mtmp->ispriest)
791 mzapwand(mtmp, otmp, TRUE);
792 how = WAN_TELEPORTATION;
794 if (tele_restrict(mtmp)) { /* mysterious force... */
795 if (vismon && how) /* mentions 'teleport' */
797 /* monster learns that teleportation isn't useful here */
798 if (level.flags.noteleport)
799 mtmp->mtrapseen |= (1 << (TELEP_TRAP - 1));
802 if ((mon_has_amulet(mtmp) || On_W_tower_level(&u.uz)) && !rn2(3)) {
805 pline("%s seems disoriented for a moment.", Monnam(mtmp));
807 pline("%s
\82Í
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\81D", Monnam(mtmp));
812 (void) rloc(mtmp, TRUE);
814 case MUSE_WAN_TELEPORTATION:
816 mzapwand(mtmp, otmp, FALSE);
818 mbhit(mtmp, rn1(8, 6), mbhitm, bhito, otmp);
819 /* monster learns that teleportation isn't useful here */
820 if (level.flags.noteleport)
821 mtmp->mtrapseen |= (1 << (TELEP_TRAP - 1));
824 case MUSE_SCR_TELEPORTATION: {
825 int obj_is_cursed = otmp->cursed;
827 if (mtmp->isshk || mtmp->isgd || mtmp->ispriest)
830 mreadmsg(mtmp, otmp);
831 m_useup(mtmp, otmp); /* otmp might be free'ed */
832 how = SCR_TELEPORTATION;
833 if (obj_is_cursed || mtmp->mconf) {
837 if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
840 pline("%s seems very disoriented for a moment.",
842 pline("%s
\82Í
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\81D",
846 nlev = random_teleport_level();
847 if (nlev == depth(&u.uz)) {
850 pline("%s shudders for a moment.", Monnam(mtmp));
852 pline("%s
\82Í
\88ê
\8fu
\90k
\82¦
\82½
\81D", Monnam(mtmp));
855 get_level(&flev, nlev);
856 migrate_to_level(mtmp, ledger_no(&flev), MIGR_RANDOM,
859 makeknown(SCR_TELEPORTATION);
864 case MUSE_WAN_DIGGING: {
868 mzapwand(mtmp, otmp, FALSE);
870 makeknown(WAN_DIGGING);
871 if (IS_FURNITURE(levl[mtmp->mx][mtmp->my].typ)
872 || IS_DRAWBRIDGE(levl[mtmp->mx][mtmp->my].typ)
873 || (is_drawbridge_wall(mtmp->mx, mtmp->my) >= 0)
874 || (sstairs.sx && sstairs.sx == mtmp->mx
875 && sstairs.sy == mtmp->my)) {
877 pline_The("digging ray is ineffective.");
879 pline("
\8c@
\8dí
\8cõ
\90ü
\82Í
\8cø
\89Ê
\82ª
\82È
\82¢
\81D");
882 if (!Can_dig_down(&u.uz) && !levl[mtmp->mx][mtmp->my].candig) {
885 pline_The("%s here is too hard to dig in.",
887 pline("
\82±
\82±
\82Ì%s
\82Í
\8cÅ
\82
\82Ä
\8c@
\82ê
\82È
\82¢
\81D",
888 surface(mtmp->mx, mtmp->my));
891 ttmp = maketrap(mtmp->mx, mtmp->my, HOLE);
897 pline("%s has made a hole in the %s.", Monnam(mtmp),
898 surface(mtmp->mx, mtmp->my));
900 pline("%s
\82Í%s
\82É
\8c\8a\82ð
\8aJ
\82¯
\82½
\81D", Monnam(mtmp),
901 surface(mtmp->mx, mtmp->my));
904 pline("%s %s through...", Monnam(mtmp),
905 is_flyer(mtmp->data) ? "dives" : "falls");
907 pline("%s
\82Í
\92Ê
\82è
\94²
\82¯
\82Ä%s
\81D
\81D
\81D", Monnam(mtmp),
908 is_flyer(mtmp->data) ? "
\94ò
\82Ñ
\82±
\82ñ
\82¾" : "
\97\8e\82¿
\82½");
912 You_hear("%s crash through the %s.", something,
913 surface(mtmp->mx, mtmp->my));
915 You_hear("
\89½
\82©
\82ª%s
\82ð
\92Ê
\82è
\94²
\82¯
\82Ä
\97\8e\82¿
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D
\81D
\81D",
916 surface(mtmp->mx, mtmp->my));
918 /* we made sure that there is a level for mtmp to go to */
919 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, MIGR_RANDOM,
923 case MUSE_WAN_CREATE_MONSTER: {
925 /* pm: 0 => random, eel => aquatic, croc => amphibious */
926 struct permonst *pm =
927 !is_pool(mtmp->mx, mtmp->my)
929 : &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE];
932 if (!enexto(&cc, mtmp->mx, mtmp->my, pm))
934 mzapwand(mtmp, otmp, FALSE);
935 mon = makemon((struct permonst *) 0, cc.x, cc.y, NO_MM_FLAGS);
936 if (mon && canspotmon(mon) && oseen)
937 makeknown(WAN_CREATE_MONSTER);
940 case MUSE_SCR_CREATE_MONSTER: {
942 struct permonst *pm = 0, *fish = 0;
945 boolean known = FALSE;
949 if (mtmp->mconf || otmp->cursed)
952 pm = fish = &mons[PM_ACID_BLOB];
953 else if (is_pool(mtmp->mx, mtmp->my))
954 fish = &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE];
955 mreadmsg(mtmp, otmp);
957 /* `fish' potentially gives bias towards water locations;
958 `pm' is what to actually create (0 => random) */
959 if (!enexto(&cc, mtmp->mx, mtmp->my, fish))
961 mon = makemon(pm, cc.x, cc.y, NO_MM_FLAGS);
962 if (mon && canspotmon(mon))
965 /* The only case where we don't use oseen. For wands, you
966 * have to be able to see the monster zap the wand to know
967 * what type it is. For teleport scrolls, you have to see
968 * the monster to know it teleported.
971 makeknown(SCR_CREATE_MONSTER);
972 else if (!objects[SCR_CREATE_MONSTER].oc_name_known
973 && !objects[SCR_CREATE_MONSTER].oc_uname)
979 /* trap doors on "bottom" levels of dungeons are rock-drop
980 * trap doors, not holes in the floor. We check here for
983 if (Is_botlevel(&u.uz))
987 struct trap *t = t_at(trapx, trapy);
991 pline("%s %s into a %s!", Mnam,
992 vtense(fakename[0], locomotion(mtmp->data, "jump")),
993 (t->ttyp == TRAPDOOR) ? "trap door" : "hole");
995 pline("%s
\82Í%s
\82É%s
\93ü
\82Á
\82½
\81I", Mnam,
996 t->ttyp == TRAPDOOR ? "
\97\8e\82µ
\94à" : "
\8c\8a",
997 jconj(locomotion(mtmp->data, "
\94ò
\82Ô"), "
\82Ä"));
999 if (levl[trapx][trapy].typ == SCORR) {
1000 levl[trapx][trapy].typ = CORR;
1001 unblock_point(trapx, trapy);
1003 seetrap(t_at(trapx, trapy));
1006 /* don't use rloc_to() because worm tails must "move" */
1007 remove_monster(mtmp->mx, mtmp->my);
1008 newsym(mtmp->mx, mtmp->my); /* update old location */
1009 place_monster(mtmp, trapx, trapy);
1012 newsym(trapx, trapy);
1014 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, MIGR_RANDOM,
1019 if (ledger_no(&u.uz) == 1)
1020 goto escape; /* impossible; level 1 upstairs are SSTAIRS */
1021 if (Inhell && mon_has_amulet(mtmp) && !rn2(4)
1022 && (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) {
1026 "As %s climbs the stairs, a mysterious force momentarily surrounds %s...",
1027 mon_nam(mtmp), mhim(mtmp));
1030 "%s
\82ª
\8aK
\92i
\82ð
\82Ì
\82Ú
\82ë
\82¤
\82Æ
\82·
\82é
\82Æ
\8aï
\96
\82È
\97Í
\82ª%s
\82ð
\82Â
\82Â
\82ñ
\82¾
\81D
\81D
\81D",
1031 mon_nam(mtmp), mhim(mtmp));
1033 /* simpler than for the player; this will usually be
1034 the Wizard and he'll immediately go right to the
1035 upstairs, so there's not much point in having any
1036 chance for a random position on the current level */
1037 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, MIGR_RANDOM,
1042 pline("%s escapes upstairs!", Monnam(mtmp));
1044 pline("%s
\82Í
\8aK
\92i
\82ð
\82Ì
\82Ú
\82Á
\82Ä
\93¦
\82°
\82½
\81I", Monnam(mtmp));
1045 migrate_to_level(mtmp, ledger_no(&u.uz) - 1, MIGR_STAIRS_DOWN,
1049 case MUSE_DOWNSTAIRS:
1053 pline("%s escapes downstairs!", Monnam(mtmp));
1055 pline("%s
\82Í
\8aK
\92i
\82ð
\8d~
\82è
\82Ä
\93¦
\82°
\82½
\81I", Monnam(mtmp));
1056 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, MIGR_STAIRS_UP,
1059 case MUSE_UP_LADDER:
1063 pline("%s escapes up the ladder!", Monnam(mtmp));
1065 pline("%s
\82Í
\82Í
\82µ
\82²
\82ð
\82Ì
\82Ú
\82Á
\82Ä
\93¦
\82°
\82½
\81I", Monnam(mtmp));
1066 migrate_to_level(mtmp, ledger_no(&u.uz) - 1, MIGR_LADDER_DOWN,
1069 case MUSE_DN_LADDER:
1073 pline("%s escapes down the ladder!", Monnam(mtmp));
1075 pline("%s
\82Í
\82Í
\82µ
\82²
\82ð
\8d~
\82è
\82Ä
\93¦
\82°
\82½
\81I", Monnam(mtmp));
1076 migrate_to_level(mtmp, ledger_no(&u.uz) + 1, MIGR_LADDER_UP,
1081 if (ledger_no(&u.uz) == 1) {
1083 /* Monsters without the Amulet escape the dungeon and
1084 * are gone for good when they leave up the up stairs.
1085 * A monster with the Amulet would leave it behind
1086 * (mongone -> mdrop_special_objs) but we force any
1087 * monster who manages to acquire it or the invocation
1088 * tools to stick around instead of letting it escape.
1090 if (mon_has_special(mtmp))
1094 pline("%s escapes the dungeon!", Monnam(mtmp));
1096 pline("%s
\82Í
\96À
\8b{
\82©
\82ç
\93¦
\91\96\82µ
\82½
\81I", Monnam(mtmp));
1102 pline("%s escapes %sstairs!", Monnam(mtmp),
1103 sstairs.up ? "up" : "down");
1105 pline("%s
\82Í
\8aK
\92i
\82ð%s
\93¦
\82°
\82½
\81I", Monnam(mtmp),
1106 sstairs.up ? "
\82Ì
\82Ú
\82Á
\82Ä" : "
\8d~
\82è
\82Ä");
1108 /* going from the Valley to Castle (Stronghold) has no sstairs
1109 to target, but having sstairs.<sx,sy> == <0,0> will work the
1110 same as specifying MIGR_RANDOM when mon_arrive() eventually
1111 places the monster, so we can use MIGR_SSTAIRS unconditionally */
1112 migrate_to_level(mtmp, ledger_no(&sstairs.tolev), MIGR_SSTAIRS,
1115 case MUSE_TELEPORT_TRAP:
1118 Mnam = Monnam(mtmp);
1120 pline("%s %s onto a teleport trap!", Mnam,
1121 vtense(fakename[0], locomotion(mtmp->data, "jump")));
1123 /*
\93ú
\96{
\8cê
\82Å
\82Í
\91S
\82Ä
\81u
\94ò
\82Ñ
\8d\9e\82ñ
\82¾
\81v */
1124 pline("%s
\82Í
\8fu
\8aÔ
\88Ú
\93®
\82Ìã©
\82É
\94ò
\82Ñ
\8d\9e\82ñ
\82¾
\81I", Mnam);
1126 seetrap(t_at(trapx, trapy));
1128 /* don't use rloc_to() because worm tails must "move" */
1129 remove_monster(mtmp->mx, mtmp->my);
1130 newsym(mtmp->mx, mtmp->my); /* update old location */
1131 place_monster(mtmp, trapx, trapy);
1134 newsym(trapx, trapy);
1137 case MUSE_POT_HEALING:
1138 mquaffmsg(mtmp, otmp);
1139 i = d(6 + 2 * bcsign(otmp), 4);
1141 if (mtmp->mhp > mtmp->mhpmax)
1142 mtmp->mhp = ++mtmp->mhpmax;
1143 if (!otmp->cursed && !mtmp->mcansee)
1144 mcureblindness(mtmp, vismon);
1147 pline("%s looks better.", Monnam(mtmp));
1149 pline("%s
\82Í
\8bC
\95ª
\82ª
\82æ
\82
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mtmp));
1151 makeknown(POT_HEALING);
1152 m_useup(mtmp, otmp);
1154 case MUSE_POT_EXTRA_HEALING:
1155 mquaffmsg(mtmp, otmp);
1156 i = d(6 + 2 * bcsign(otmp), 8);
1158 if (mtmp->mhp > mtmp->mhpmax)
1159 mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2));
1161 mcureblindness(mtmp, vismon);
1164 pline("%s looks much better.", Monnam(mtmp));
1166 pline("%s
\82Í
\82Æ
\82Ä
\82à
\8bC
\95ª
\82ª
\82æ
\82
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mtmp));
1168 makeknown(POT_EXTRA_HEALING);
1169 m_useup(mtmp, otmp);
1171 case MUSE_POT_FULL_HEALING:
1172 mquaffmsg(mtmp, otmp);
1173 if (otmp->otyp == POT_SICKNESS)
1174 unbless(otmp); /* Pestilence */
1175 mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 8 : 4));
1176 if (!mtmp->mcansee && otmp->otyp != POT_SICKNESS)
1177 mcureblindness(mtmp, vismon);
1180 pline("%s looks completely healed.", Monnam(mtmp));
1182 pline("%s
\82Í
\8a®
\91S
\82É
\89ñ
\95\9c\82µ
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mtmp));
1184 makeknown(otmp->otyp);
1185 m_useup(mtmp, otmp);
1187 case MUSE_LIZARD_CORPSE:
1188 /* not actually called for its unstoning effect */
1189 mon_consume_unstone(mtmp, otmp, FALSE, FALSE);
1192 return 0; /* i.e. an exploded wand */
1194 impossible("%s wanted to perform action %d?", Monnam(mtmp),
1203 rnd_defensive_item(mtmp)
1206 struct permonst *pm = mtmp->data;
1207 int difficulty = mons[(monsndx(pm))].difficulty;
1210 if (is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1211 || pm->mlet == S_GHOST || pm->mlet == S_KOP)
1214 switch (rn2(8 + (difficulty > 3) + (difficulty > 6) + (difficulty > 8))) {
1217 if (level.flags.noteleport && ++trycnt < 2)
1220 return WAN_TELEPORTATION;
1224 return SCR_TELEPORTATION;
1228 return WAN_CREATE_MONSTER;
1231 return SCR_CREATE_MONSTER;
1235 return POT_EXTRA_HEALING;
1237 return (mtmp->data != &mons[PM_PESTILENCE]) ? POT_FULL_HEALING
1240 if (is_floater(pm) || mtmp->isshk || mtmp->isgd || mtmp->ispriest)
1249 #define MUSE_WAN_DEATH 1
1250 #define MUSE_WAN_SLEEP 2
1251 #define MUSE_WAN_FIRE 3
1252 #define MUSE_WAN_COLD 4
1253 #define MUSE_WAN_LIGHTNING 5
1254 #define MUSE_WAN_MAGIC_MISSILE 6
1255 #define MUSE_WAN_STRIKING 7
1256 #define MUSE_SCR_FIRE 8
1257 #define MUSE_POT_PARALYSIS 9
1258 #define MUSE_POT_BLINDNESS 10
1259 #define MUSE_POT_CONFUSION 11
1260 #define MUSE_FROST_HORN 12
1261 #define MUSE_FIRE_HORN 13
1262 #define MUSE_POT_ACID 14
1263 /*#define MUSE_WAN_TELEPORTATION 15*/
1264 #define MUSE_POT_SLEEPING 16
1265 #define MUSE_SCR_EARTH 17
1267 /* Select an offensive item/action for a monster. Returns TRUE iff one is
1271 find_offensive(mtmp)
1274 register struct obj *obj;
1275 boolean reflection_skip = (Reflecting && rn2(2));
1276 struct obj *helmet = which_armor(mtmp, W_ARMH);
1278 m.offensive = (struct obj *) 0;
1280 if (mtmp->mpeaceful || is_animal(mtmp->data) || mindless(mtmp->data)
1281 || nohands(mtmp->data))
1285 if (in_your_sanctuary(mtmp, 0, 0))
1287 if (dmgtype(mtmp->data, AD_HEAL)
1288 && !uwep && !uarmu && !uarm && !uarmh
1289 && !uarms && !uarmg && !uarmc && !uarmf)
1291 /* all offensive items require orthogonal or diagonal targetting */
1292 if (!lined_up(mtmp))
1295 #define nomore(x) if (m.has_offense == x) continue;
1296 /* this picks the last viable item rather than prioritizing choices */
1297 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
1298 if (!reflection_skip) {
1299 nomore(MUSE_WAN_DEATH);
1300 if (obj->otyp == WAN_DEATH && obj->spe > 0) {
1302 m.has_offense = MUSE_WAN_DEATH;
1304 nomore(MUSE_WAN_SLEEP);
1305 if (obj->otyp == WAN_SLEEP && obj->spe > 0 && multi >= 0) {
1307 m.has_offense = MUSE_WAN_SLEEP;
1309 nomore(MUSE_WAN_FIRE);
1310 if (obj->otyp == WAN_FIRE && obj->spe > 0) {
1312 m.has_offense = MUSE_WAN_FIRE;
1314 nomore(MUSE_FIRE_HORN);
1315 if (obj->otyp == FIRE_HORN && obj->spe > 0 && can_blow(mtmp)) {
1317 m.has_offense = MUSE_FIRE_HORN;
1319 nomore(MUSE_WAN_COLD);
1320 if (obj->otyp == WAN_COLD && obj->spe > 0) {
1322 m.has_offense = MUSE_WAN_COLD;
1324 nomore(MUSE_FROST_HORN);
1325 if (obj->otyp == FROST_HORN && obj->spe > 0 && can_blow(mtmp)) {
1327 m.has_offense = MUSE_FROST_HORN;
1329 nomore(MUSE_WAN_LIGHTNING);
1330 if (obj->otyp == WAN_LIGHTNING && obj->spe > 0) {
1332 m.has_offense = MUSE_WAN_LIGHTNING;
1334 nomore(MUSE_WAN_MAGIC_MISSILE);
1335 if (obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) {
1337 m.has_offense = MUSE_WAN_MAGIC_MISSILE;
1340 nomore(MUSE_WAN_STRIKING);
1341 if (obj->otyp == WAN_STRIKING && obj->spe > 0) {
1343 m.has_offense = MUSE_WAN_STRIKING;
1345 #if 0 /* use_offensive() has had some code to support wand of teleportation
1346 * for a long time, but find_offensive() never selected one;
1347 * so for the time being, this is still disabled */
1348 nomore(MUSE_WAN_TELEPORTATION);
1349 if (obj->otyp == WAN_TELEPORTATION && obj->spe > 0
1350 /* don't give controlled hero a free teleport */
1351 && !Teleport_control
1352 /* do try to move hero to a more vulnerable spot */
1353 && (onscary(u.ux, u.uy, mtmp)
1354 || (u.ux == xupstair && u.uy == yupstair)
1355 || (u.ux == xdnstair && u.uy == ydnstair)
1356 || (u.ux == sstairs.sx && u.uy == sstairs.sy)
1357 || (u.ux == xupladder && u.uy == yupladder)
1358 || (u.ux == xdnladder && u.uy == ydnladder))) {
1360 m.has_offense = MUSE_WAN_TELEPORTATION;
1363 nomore(MUSE_POT_PARALYSIS);
1364 if (obj->otyp == POT_PARALYSIS && multi >= 0) {
1366 m.has_offense = MUSE_POT_PARALYSIS;
1368 nomore(MUSE_POT_BLINDNESS);
1369 if (obj->otyp == POT_BLINDNESS && !attacktype(mtmp->data, AT_GAZE)) {
1371 m.has_offense = MUSE_POT_BLINDNESS;
1373 nomore(MUSE_POT_CONFUSION);
1374 if (obj->otyp == POT_CONFUSION) {
1376 m.has_offense = MUSE_POT_CONFUSION;
1378 nomore(MUSE_POT_SLEEPING);
1379 if (obj->otyp == POT_SLEEPING) {
1381 m.has_offense = MUSE_POT_SLEEPING;
1383 nomore(MUSE_POT_ACID);
1384 if (obj->otyp == POT_ACID) {
1386 m.has_offense = MUSE_POT_ACID;
1388 /* we can safely put this scroll here since the locations that
1389 * are in a 1 square radius are a subset of the locations that
1390 * are in wand or throwing range (in other words, always lined_up())
1392 nomore(MUSE_SCR_EARTH);
1393 if (obj->otyp == SCR_EARTH
1394 && ((helmet && is_metallic(helmet)) || mtmp->mconf
1395 || amorphous(mtmp->data) || passes_walls(mtmp->data)
1396 || noncorporeal(mtmp->data) || unsolid(mtmp->data)
1398 && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 2
1399 && mtmp->mcansee && haseyes(mtmp->data)
1400 && !Is_rogue_level(&u.uz)
1401 && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) {
1403 m.has_offense = MUSE_SCR_EARTH;
1406 nomore(MUSE_SCR_FIRE);
1407 if (obj->otyp == SCR_FIRE && resists_fire(mtmp)
1408 && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 2
1409 && mtmp->mcansee && haseyes(mtmp->data)) {
1411 m.has_offense = MUSE_SCR_FIRE;
1415 return (boolean) !!m.has_offense;
1422 register struct monst *mtmp;
1423 register struct obj *otmp;
1426 boolean reveal_invis = FALSE;
1428 if (mtmp != &youmonst) {
1429 mtmp->msleeping = 0;
1430 if (mtmp->m_ap_type)
1433 switch (otmp->otyp) {
1435 reveal_invis = TRUE;
1436 if (mtmp == &youmonst) {
1438 makeknown(WAN_STRIKING);
1440 shieldeff(u.ux, u.uy);
1444 pline("
\83{
\83C
\83\93\81I");
1445 } else if (rnd(20) < 10 + u.uac) {
1447 pline_The("wand hits you!");
1449 pline("
\8fñ
\82Í
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I");
1451 if (Half_spell_damage)
1452 tmp = (tmp + 1) / 2;
1454 losehp(tmp, "wand", KILLED_BY_AN);
1456 losehp(tmp, "
\8fÕ
\8c\82\82Ì
\8fñ
\82É
\82æ
\82Á
\82Ä", KILLED_BY_AN);
1459 pline_The("wand misses you.");
1461 pline("
\8fñ
\82Í
\82Í
\82¸
\82ê
\82½
\81D");
1464 } else if (resists_magm(mtmp)) {
1465 shieldeff(mtmp->mx, mtmp->my);
1469 pline("
\83{
\83C
\83\93\81I");
1470 } else if (rnd(20) < 10 + find_mac(mtmp)) {
1473 hit("wand", mtmp, exclam(tmp));
1475 hit("
\8fñ", mtmp, exclam(tmp));
1476 (void) resist(mtmp, otmp->oclass, tmp, TELL);
1477 if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
1478 makeknown(WAN_STRIKING);
1484 if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
1485 makeknown(WAN_STRIKING);
1488 #if 0 /* disabled because find_offensive() never picks WAN_TELEPORTATION */
1489 case WAN_TELEPORTATION:
1490 if (mtmp == &youmonst) {
1492 makeknown(WAN_TELEPORTATION);
1495 /* for consistency with zap.c, don't identify */
1496 if (mtmp->ispriest && *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
1497 if (cansee(mtmp->mx, mtmp->my))
1499 pline("%s resists the magic!", Monnam(mtmp));
1501 pline("%s
\82Í
\96\82\96@
\82ð
\96h
\82¢
\82¾
\81I", Monnam(mtmp));
1502 } else if (!tele_restrict(mtmp))
1503 (void) rloc(mtmp, TRUE);
1507 case WAN_CANCELLATION:
1508 case SPE_CANCELLATION:
1509 (void) cancel_monst(mtmp, otmp, FALSE, TRUE, FALSE);
1513 if (!DEADMONSTER(mtmp) && cansee(bhitpos.x, bhitpos.y)
1514 && !canspotmon(mtmp))
1515 map_invisible(bhitpos.x, bhitpos.y);
1520 /* A modified bhit() for monsters. Based on bhit() in zap.c. Unlike
1521 * buzz(), bhit() doesn't take into account the possibility of a monster
1522 * zapping you, so we need a special function for it. (Unless someone wants
1523 * to merge the two functions...)
1526 mbhit(mon, range, fhitm, fhito, obj)
1527 struct monst *mon; /* monster shooting the wand */
1528 register int range; /* direction and range */
1529 int FDECL((*fhitm), (MONST_P, OBJ_P));
1530 int FDECL((*fhito), (OBJ_P, OBJ_P)); /* fns called when mon/obj hit */
1531 struct obj *obj; /* 2nd arg to fhitm/fhito */
1533 register struct monst *mtmp;
1534 register struct obj *otmp;
1538 bhitpos.x = mon->mx;
1539 bhitpos.y = mon->my;
1540 ddx = sgn(mon->mux - mon->mx);
1541 ddy = sgn(mon->muy - mon->my);
1543 while (range-- > 0) {
1556 if (find_drawbridge(&x, &y))
1557 switch (obj->otyp) {
1559 destroy_drawbridge(x, y);
1561 if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
1562 (*fhitm)(&youmonst, obj);
1564 } else if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) {
1565 if (cansee(bhitpos.x, bhitpos.y) && !canspotmon(mtmp))
1566 map_invisible(bhitpos.x, bhitpos.y);
1567 (*fhitm)(mtmp, obj);
1570 /* modified by GAN to hit all objects */
1572 int hitanything = 0;
1573 register struct obj *next_obj;
1575 for (otmp = level.objects[bhitpos.x][bhitpos.y]; otmp;
1577 /* Fix for polymorph bug, Tim Wright */
1578 next_obj = otmp->nexthere;
1579 hitanything += (*fhito)(otmp, obj);
1584 typ = levl[bhitpos.x][bhitpos.y].typ;
1585 if (IS_DOOR(typ) || typ == SDOOR) {
1586 switch (obj->otyp) {
1587 /* note: monsters don't use opening or locking magic
1588 at present, but keep these as placeholders */
1592 if (doorlock(obj, bhitpos.x, bhitpos.y)) {
1594 makeknown(obj->otyp);
1595 /* if a shop door gets broken, add it to
1596 the shk's fix list (no cost to player) */
1597 if (levl[bhitpos.x][bhitpos.y].doormask == D_BROKEN
1598 && *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE))
1599 add_damage(bhitpos.x, bhitpos.y, 0L);
1605 || (IS_DOOR(typ) && (levl[bhitpos.x][bhitpos.y].doormask
1606 & (D_LOCKED | D_CLOSED)))) {
1614 /* Perform an offensive action for a monster. Must be called immediately
1615 * after find_offensive(). Return values are same as use_defensive().
1622 struct obj *otmp = m.offensive;
1625 /* offensive potions are not drunk, they're thrown */
1626 if (otmp->oclass != POTION_CLASS && (i = precheck(mtmp, otmp)) != 0)
1628 oseen = otmp && canseemon(mtmp);
1630 switch (m.has_offense) {
1631 case MUSE_WAN_DEATH:
1632 case MUSE_WAN_SLEEP:
1635 case MUSE_WAN_LIGHTNING:
1636 case MUSE_WAN_MAGIC_MISSILE:
1637 mzapwand(mtmp, otmp, FALSE);
1639 makeknown(otmp->otyp);
1641 buzz((int) (-30 - (otmp->otyp - WAN_MAGIC_MISSILE)),
1642 (otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6, mtmp->mx, mtmp->my,
1643 sgn(mtmp->mux - mtmp->mx), sgn(mtmp->muy - mtmp->my));
1645 return (DEADMONSTER(mtmp)) ? 1 : 2;
1646 case MUSE_FIRE_HORN:
1647 case MUSE_FROST_HORN:
1648 mplayhorn(mtmp, otmp, FALSE);
1650 buzz(-30 - ((otmp->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1),
1651 rn1(6, 6), mtmp->mx, mtmp->my, sgn(mtmp->mux - mtmp->mx),
1652 sgn(mtmp->muy - mtmp->my));
1654 return (DEADMONSTER(mtmp)) ? 1 : 2;
1655 case MUSE_WAN_TELEPORTATION:
1656 case MUSE_WAN_STRIKING:
1658 mzapwand(mtmp, otmp, FALSE);
1660 mbhit(mtmp, rn1(8, 6), mbhitm, bhito, otmp);
1663 case MUSE_SCR_EARTH: {
1664 /* TODO: handle steeds */
1666 /* don't use monster fields after killing it */
1667 boolean confused = (mtmp->mconf ? TRUE : FALSE);
1668 int mmx = mtmp->mx, mmy = mtmp->my;
1669 boolean is_cursed = otmp->cursed;
1671 mreadmsg(mtmp, otmp);
1672 /* Identify the scroll */
1673 if (canspotmon(mtmp)) {
1675 pline_The("%s rumbles %s %s!", ceiling(mtmp->mx, mtmp->my),
1676 otmp->blessed ? "around" : "above", mon_nam(mtmp));
1678 pline("%s
\82Ì%s
\82Ì%s
\82©
\82ç
\83S
\83\8d\83S
\83\8d\82Æ
\89¹
\82ª
\95·
\82±
\82¦
\82Ä
\82«
\82½
\81D",
1680 otmp->blessed ? "
\82Ü
\82í
\82è" : "
\90^
\8fã",
1681 ceiling(mtmp->mx, mtmp->my));
1684 makeknown(otmp->otyp);
1685 } else if (cansee(mtmp->mx, mtmp->my)) {
1687 pline_The("%s rumbles in the middle of nowhere!",
1689 pline_The("
\82Ç
\82±
\82©
\82Ì%s
\82©
\82ç
\83S
\83\8d\83S
\83\8d\82Æ
\89¹
\82ª
\95·
\82±
\82¦
\82Ä
\82«
\82½
\81D",
1690 ceiling(mtmp->mx, mtmp->my));
1692 map_invisible(mtmp->mx, mtmp->my);
1694 makeknown(otmp->otyp);
1697 /* Loop through the surrounding squares */
1698 for (x = mmx - 1; x <= mmx + 1; x++) {
1699 for (y = mmy - 1; y <= mmy + 1; y++) {
1700 /* Is this a suitable spot? */
1701 if (isok(x, y) && !closed_door(x, y)
1702 && !IS_ROCK(levl[x][y].typ) && !IS_AIR(levl[x][y].typ)
1703 && (((x == mmx) && (y == mmy)) ? !otmp->blessed
1705 && (x != u.ux || y != u.uy)) {
1706 (void) drop_boulder_on_monster(x, y, confused, FALSE);
1710 m_useup(mtmp, otmp);
1711 /* Attack the player */
1712 if (distmin(mmx, mmy, u.ux, u.uy) == 1 && !is_cursed) {
1713 drop_boulder_on_player(confused, !is_cursed, FALSE, TRUE);
1716 return (DEADMONSTER(mtmp)) ? 1 : 2;
1719 case MUSE_SCR_FIRE: {
1720 boolean vis = cansee(mtmp->mx, mtmp->my);
1722 mreadmsg(mtmp, otmp);
1726 pline("Oh, what a pretty fire!");
1728 pline("
\82í
\82\9f\81C
\82«
\82ê
\82¢
\82È
\89\8a\82¾
\81I");
1730 struct monst *mtmp2;
1735 pline_The("scroll erupts in a tower of flame!");
1737 pline("
\8aª
\95¨
\82©
\82ç
\89Î
\92\8c\82ª
\97§
\82¿
\8f¸
\82Á
\82½
\81I");
1738 shieldeff(mtmp->mx, mtmp->my);
1740 pline("%s is uninjured.", Monnam(mtmp));
1742 pline("%s
\82Í
\8f\9d\82Â
\82©
\82È
\82©
\82Á
\82½
\81D", Monnam(mtmp));
1743 (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
1744 (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
1745 (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
1746 num = (2 * (rn1(3, 3) + 2 * bcsign(otmp)) + 1) / 3;
1747 if (Fire_resistance)
1749 You("are not harmed.");
1751 You("
\8f\9d\82Â
\82©
\82È
\82©
\82Á
\82½
\81D");
1753 if (Half_spell_damage)
1754 num = (num + 1) / 2;
1757 losehp(num, "scroll of fire", KILLED_BY_AN);
1759 losehp(num, "
\89\8a\82Ì
\8aª
\95¨
\82Å", KILLED_BY_AN);
1760 for (mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) {
1761 if (DEADMONSTER(mtmp2))
1765 if (dist2(mtmp2->mx, mtmp2->my, mtmp->mx, mtmp->my) < 3) {
1766 if (resists_fire(mtmp2))
1769 if (resists_cold(mtmp2))
1770 mtmp2->mhp -= 3 * num;
1771 if (DEADMONSTER(mtmp2)) {
1781 case MUSE_POT_PARALYSIS:
1782 case MUSE_POT_BLINDNESS:
1783 case MUSE_POT_CONFUSION:
1784 case MUSE_POT_SLEEPING:
1786 /* Note: this setting of dknown doesn't suffice. A monster
1787 * which is out of sight might throw and it hits something _in_
1788 * sight, a problem not existing with wands because wand rays
1789 * are not objects. Also set dknown in mthrowu.c.
1791 if (cansee(mtmp->mx, mtmp->my)) {
1794 pline("%s hurls %s!", Monnam(mtmp), singular(otmp, doname));
1796 pline("%s
\82Í%s
\82ð
\8b
\82
\93\8a\82°
\82Â
\82¯
\82½
\81I", Monnam(mtmp), singular(otmp, doname));
1798 m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux - mtmp->mx),
1799 sgn(mtmp->muy - mtmp->my),
1800 distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy), otmp);
1803 return 0; /* i.e. an exploded wand */
1805 impossible("%s wanted to perform action %d?", Monnam(mtmp),
1813 rnd_offensive_item(mtmp)
1816 struct permonst *pm = mtmp->data;
1817 int difficulty = mons[(monsndx(pm))].difficulty;
1819 if (is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
1820 || pm->mlet == S_GHOST || pm->mlet == S_KOP)
1822 if (difficulty > 7 && !rn2(35))
1824 switch (rn2(9 - (difficulty < 4) + 4 * (difficulty > 6))) {
1826 struct obj *helmet = which_armor(mtmp, W_ARMH);
1828 if ((helmet && is_metallic(helmet)) || amorphous(pm)
1829 || passes_walls(pm) || noncorporeal(pm) || unsolid(pm))
1831 } /* fall through */
1833 return WAN_STRIKING;
1837 return POT_CONFUSION;
1839 return POT_BLINDNESS;
1841 return POT_SLEEPING;
1843 return POT_PARALYSIS;
1846 return WAN_MAGIC_MISSILE;
1854 return WAN_LIGHTNING;
1860 #define MUSE_POT_GAIN_LEVEL 1
1861 #define MUSE_WAN_MAKE_INVISIBLE 2
1862 #define MUSE_POT_INVISIBILITY 3
1863 #define MUSE_POLY_TRAP 4
1864 #define MUSE_WAN_POLYMORPH 5
1865 #define MUSE_POT_SPEED 6
1866 #define MUSE_WAN_SPEED_MONSTER 7
1867 #define MUSE_BULLWHIP 8
1868 #define MUSE_POT_POLYMORPH 9
1874 register struct obj *obj;
1875 struct permonst *mdat = mtmp->data;
1876 int x = mtmp->mx, y = mtmp->my;
1878 int xx, yy, pmidx = NON_PM;
1879 boolean immobile = (mdat->mmove == 0);
1880 boolean stuck = (mtmp == u.ustuck);
1882 m.misc = (struct obj *) 0;
1884 if (is_animal(mdat) || mindless(mdat))
1886 if (u.uswallow && stuck)
1889 /* We arbitrarily limit to times when a player is nearby for the
1890 * same reason as Junior Pac-Man doesn't have energizers eaten until
1891 * you can see them...
1893 if (dist2(x, y, mtmp->mux, mtmp->muy) > 36)
1896 if (!stuck && !immobile && (mtmp->cham == NON_PM)
1897 && mons[(pmidx = monsndx(mdat))].difficulty < 6) {
1898 boolean ignore_boulders = (verysmall(mdat) || throws_rocks(mdat)
1899 || passes_walls(mdat)),
1900 diag_ok = !NODIAG(pmidx);
1902 for (xx = x - 1; xx <= x + 1; xx++)
1903 for (yy = y - 1; yy <= y + 1; yy++)
1904 if (isok(xx, yy) && (xx != u.ux || yy != u.uy)
1905 && (diag_ok || xx == x || yy == y)
1906 && ((xx == x && yy == y) || !level.monsters[xx][yy]))
1907 if ((t = t_at(xx, yy)) != 0
1908 && (ignore_boulders || !sobj_at(BOULDER, xx, yy))
1909 && !onscary(xx, yy, mtmp)) {
1910 /* use trap if it's the correct type */
1911 if (t->ttyp == POLY_TRAP) {
1914 m.has_misc = MUSE_POLY_TRAP;
1922 #define nomore(x) if (m.has_misc == x) continue
1924 * [bug?] Choice of item is not prioritized; the last viable one
1925 * in the monster's inventory will be chosen.
1926 * 'nomore()' is nearly worthless because it only screens checking
1927 * of duplicates when there is no alternate type in between them.
1929 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
1930 /* Monsters shouldn't recognize cursed items; this kludge is
1931 necessary to prevent serious problems though... */
1932 if (obj->otyp == POT_GAIN_LEVEL
1934 || (!mtmp->isgd && !mtmp->isshk && !mtmp->ispriest))) {
1936 m.has_misc = MUSE_POT_GAIN_LEVEL;
1938 nomore(MUSE_BULLWHIP);
1939 if (obj->otyp == BULLWHIP && !mtmp->mpeaceful
1940 /* the random test prevents whip-wielding
1941 monster from attempting disarm every turn */
1942 && uwep && !rn2(5) && obj == MON_WEP(mtmp)
1943 /* hero's location must be known and adjacent */
1944 && mtmp->mux == u.ux && mtmp->muy == u.uy
1945 && distu(mtmp->mx, mtmp->my) <= 2
1946 /* don't bother if it can't work (this doesn't
1947 prevent cursed weapons from being targetted) */
1948 && (canletgo(uwep, "")
1949 || (u.twoweap && canletgo(uswapwep, "")))) {
1951 m.has_misc = MUSE_BULLWHIP;
1953 /* Note: peaceful/tame monsters won't make themselves
1954 * invisible unless you can see them. Not really right, but...
1956 nomore(MUSE_WAN_MAKE_INVISIBLE);
1957 if (obj->otyp == WAN_MAKE_INVISIBLE && obj->spe > 0 && !mtmp->minvis
1958 && !mtmp->invis_blkd && (!mtmp->mpeaceful || See_invisible)
1959 && (!attacktype(mtmp->data, AT_GAZE) || mtmp->mcan)) {
1961 m.has_misc = MUSE_WAN_MAKE_INVISIBLE;
1963 nomore(MUSE_POT_INVISIBILITY);
1964 if (obj->otyp == POT_INVISIBILITY && !mtmp->minvis
1965 && !mtmp->invis_blkd && (!mtmp->mpeaceful || See_invisible)
1966 && (!attacktype(mtmp->data, AT_GAZE) || mtmp->mcan)) {
1968 m.has_misc = MUSE_POT_INVISIBILITY;
1970 nomore(MUSE_WAN_SPEED_MONSTER);
1971 if (obj->otyp == WAN_SPEED_MONSTER && obj->spe > 0
1972 && mtmp->mspeed != MFAST && !mtmp->isgd) {
1974 m.has_misc = MUSE_WAN_SPEED_MONSTER;
1976 nomore(MUSE_POT_SPEED);
1977 if (obj->otyp == POT_SPEED && mtmp->mspeed != MFAST && !mtmp->isgd) {
1979 m.has_misc = MUSE_POT_SPEED;
1981 nomore(MUSE_WAN_POLYMORPH);
1982 if (obj->otyp == WAN_POLYMORPH && obj->spe > 0
1983 && (mtmp->cham == NON_PM) && mons[monsndx(mdat)].difficulty < 6) {
1985 m.has_misc = MUSE_WAN_POLYMORPH;
1987 nomore(MUSE_POT_POLYMORPH);
1988 if (obj->otyp == POT_POLYMORPH && (mtmp->cham == NON_PM)
1989 && mons[monsndx(mdat)].difficulty < 6) {
1991 m.has_misc = MUSE_POT_POLYMORPH;
1994 return (boolean) !!m.has_misc;
1998 /* type of monster to polymorph into; defaults to one suitable for the
1999 current level rather than the totally arbitrary choice of newcham() */
2000 static struct permonst *
2001 muse_newcham_mon(mon)
2006 if ((m_armr = which_armor(mon, W_ARM)) != 0) {
2007 if (Is_dragon_scales(m_armr))
2008 return Dragon_scales_to_pm(m_armr);
2009 else if (Is_dragon_mail(m_armr))
2010 return Dragon_mail_to_pm(m_armr);
2020 struct obj *otmp = m.misc;
2021 boolean vis, vismon, oseen;
2024 if ((i = precheck(mtmp, otmp)) != 0)
2026 vis = cansee(mtmp->mx, mtmp->my);
2027 vismon = canseemon(mtmp);
2028 oseen = otmp && vismon;
2030 switch (m.has_misc) {
2031 case MUSE_POT_GAIN_LEVEL:
2032 mquaffmsg(mtmp, otmp);
2034 if (Can_rise_up(mtmp->mx, mtmp->my, &u.uz)) {
2035 register int tolev = depth(&u.uz) - 1;
2038 get_level(&tolevel, tolev);
2039 /* insurance against future changes... */
2040 if (on_level(&tolevel, &u.uz))
2044 pline("%s rises up, through the %s!", Monnam(mtmp),
2045 ceiling(mtmp->mx, mtmp->my));
2047 pline("%s
\82Í%s
\82ð
\93Ë
\82«
\94²
\82¯
\82½
\81I", Monnam(mtmp),
2048 ceiling(mtmp->mx, mtmp->my));
2050 if (!objects[POT_GAIN_LEVEL].oc_name_known
2051 && !objects[POT_GAIN_LEVEL].oc_uname)
2054 m_useup(mtmp, otmp);
2055 migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM,
2062 pline("%s looks uneasy.", Monnam(mtmp));
2064 pline("%s
\82Í
\95s
\88À
\82°
\82É
\8c©
\82¦
\82é
\81D", Monnam(mtmp));
2065 if (!objects[POT_GAIN_LEVEL].oc_name_known
2066 && !objects[POT_GAIN_LEVEL].oc_uname)
2069 m_useup(mtmp, otmp);
2075 pline("%s seems more experienced.", Monnam(mtmp));
2077 pline("%s
\82Í
\8co
\8c±
\82ð
\90Ï
\82ñ
\82¾
\82æ
\82¤
\82É
\8c©
\82¦
\82é
\81D", Monnam(mtmp));
2079 makeknown(POT_GAIN_LEVEL);
2080 m_useup(mtmp, otmp);
2081 if (!grow_up(mtmp, (struct monst *) 0))
2083 /* grew into genocided monster */
2085 case MUSE_WAN_MAKE_INVISIBLE:
2086 case MUSE_POT_INVISIBILITY:
2087 if (otmp->otyp == WAN_MAKE_INVISIBLE) {
2088 mzapwand(mtmp, otmp, TRUE);
2090 mquaffmsg(mtmp, otmp);
2091 /* format monster's name before altering its visibility */
2092 Strcpy(nambuf, mon_nam(mtmp));
2093 mon_set_minvis(mtmp);
2094 if (vismon && mtmp->minvis) { /* was seen, now invisible */
2095 if (canspotmon(mtmp)) {
2097 pline("%s body takes on a %s transparency.",
2098 upstart(s_suffix(nambuf)),
2099 Hallucination ? "normal" : "strange");
2101 pline("%s%s
\82Ì
\91Ì
\82Í
\93§
\89ß
\90«
\82ð
\82à
\82Á
\82½
\81D",
2102 Hallucination ? "
\82 \82½
\82è
\82Ü
\82¦
\82È
\82±
\82Æ
\82¾
\82ª" : "
\8aï
\96
\82È
\82±
\82Æ
\82É",
2107 pline("Suddenly you cannot see %s.", nambuf);
2109 pline("%s
\82Í
\93Ë
\91R
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81D", nambuf);
2111 map_invisible(mtmp->mx, mtmp->my);
2114 makeknown(otmp->otyp);
2116 if (otmp->otyp == POT_INVISIBILITY) {
2118 you_aggravate(mtmp);
2119 m_useup(mtmp, otmp);
2122 case MUSE_WAN_SPEED_MONSTER:
2123 mzapwand(mtmp, otmp, TRUE);
2124 mon_adjust_speed(mtmp, 1, otmp);
2126 case MUSE_POT_SPEED:
2127 mquaffmsg(mtmp, otmp);
2128 /* note difference in potion effect due to substantially
2129 different methods of maintaining speed ratings:
2130 player's character becomes "very fast" temporarily;
2131 monster becomes "one stage faster" permanently */
2132 mon_adjust_speed(mtmp, 1, otmp);
2133 m_useup(mtmp, otmp);
2135 case MUSE_WAN_POLYMORPH:
2136 mzapwand(mtmp, otmp, TRUE);
2137 (void) newcham(mtmp, muse_newcham_mon(mtmp), TRUE, FALSE);
2139 makeknown(WAN_POLYMORPH);
2141 case MUSE_POT_POLYMORPH:
2142 mquaffmsg(mtmp, otmp);
2145 pline("%s suddenly mutates!", Monnam(mtmp));
2147 pline("%s
\82Í
\93Ë
\91R
\95Ï
\89»
\82µ
\82½
\81I", Monnam(mtmp));
2148 (void) newcham(mtmp, muse_newcham_mon(mtmp), FALSE, FALSE);
2150 makeknown(POT_POLYMORPH);
2151 m_useup(mtmp, otmp);
2153 case MUSE_POLY_TRAP:
2155 const char *Mnam = Monnam(mtmp);
2158 pline("%s deliberately %s onto a polymorph trap!", Mnam,
2159 vtense(fakename[0], locomotion(mtmp->data, "jump")));
2161 pline("%s
\82Í
\82í
\82´
\82Æ
\95Ï
\89»
\82Ìã©
\82É
\94ò
\82Ñ
\82±
\82ñ
\82¾
\81I", Mnam);
2165 seetrap(t_at(trapx, trapy));
2167 /* don't use rloc() due to worms */
2168 remove_monster(mtmp->mx, mtmp->my);
2169 newsym(mtmp->mx, mtmp->my);
2170 place_monster(mtmp, trapx, trapy);
2173 newsym(trapx, trapy);
2175 (void) newcham(mtmp, (struct permonst *) 0, FALSE, FALSE);
2178 /* attempt to disarm hero */
2181 const char *The_whip = vismon ? "The bullwhip" : "A whip";
2183 const char *The_whip = vismon ? "
\95Ú" : "
\95Ú";
2184 int where_to = rn2(4);
2185 struct obj *obj = uwep;
2187 char the_weapon[BUFSZ];
2189 if (!obj || !canletgo(obj, "")
2190 || (u.twoweap && canletgo(uswapwep, "") && rn2(2)))
2193 break; /* shouldn't happen after find_misc() */
2195 Strcpy(the_weapon, the(xname(obj)));
2196 hand = body_part(HAND);
2198 hand = makeplural(hand);
2202 pline("%s flicks a bullwhip towards your %s!", Monnam(mtmp),
2205 pline("%s
\82Í
\82 \82È
\82½
\82Ì%s
\82É
\8cü
\82©
\82Á
\82Ä
\95Ú
\82ð
\91Å
\82Á
\82½
\81I", Monnam(mtmp),
2208 if (obj->otyp == HEAVY_IRON_BALL) {
2210 pline("%s fails to wrap around %s.", The_whip, the_weapon);
2212 pline("%s
\82Í%s
\82É
\82Í
\82©
\82ç
\82Ý
\82Â
\82©
\82È
\82©
\82Á
\82½
\81D", The_whip, the_weapon);
2216 pline("%s wraps around %s you're wielding!", The_whip,
2219 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\91\95\94õ
\82µ
\82Ä
\82¢
\82é%s
\82É
\82©
\82ç
\82Ý
\82Â
\82¢
\82½
\81I", The_whip,
2224 pline("%s welded to your %s%c",
2225 !is_plural(obj) ? "It is" : "They are", hand,
2226 !obj->bknown ? '!' : '.');
2228 pline("
\82µ
\82©
\82µ
\81C
\82»
\82ê
\82Í
\82Ü
\82¾
\82 \82È
\82½
\82Ì%s
\82Ì
\92\86\82É
\82 \82é%s",
2230 !obj->bknown ? "
\81I" : "
\81D");
2232 /* obj->bknown = 1; */ /* welded() takes care of this */
2237 pline_The("whip slips free."); /* not `The_whip' */
2239 pline("
\95Ú
\82Í
\82Ù
\82Ç
\82¯
\82½
\81D"); /* not `The_whip' */
2242 } else if (where_to == 3 && mon_hates_silver(mtmp)
2243 && objects[obj->otyp].oc_material == SILVER) {
2244 /* this monster won't want to catch a silver
2245 weapon; drop it at hero's feet instead */
2248 remove_worn_item(obj, FALSE);
2251 case 1: /* onto floor beneath mon */
2253 pline("%s yanks %s from your %s!", Monnam(mtmp), the_weapon,
2256 pline("%s
\82Í%s
\82ð
\82 \82È
\82½
\82Ì%s
\82©
\82ç
\82®
\82¢
\82Æ
\82Ð
\82Á
\82Ï
\82Á
\82½
\81I", Monnam(mtmp), the_weapon,
2259 place_object(obj, mtmp->mx, mtmp->my);
2261 case 2: /* onto floor beneath you */
2263 pline("%s yanks %s to the %s!", Monnam(mtmp), the_weapon,
2264 surface(u.ux, u.uy));
2266 pline("%s
\82Í%s
\82ð%s
\82É
\88ø
\82«
\97\8e\82µ
\82½
\81I", Monnam(mtmp), the_weapon,
2267 surface(u.ux, u.uy));
2271 case 3: /* into mon's inventory */
2273 pline("%s snatches %s!", Monnam(mtmp), the_weapon);
2275 pline("%s
\82Í%s
\82ð
\92D
\82Á
\82½
\81I", Monnam(mtmp), the_weapon);
2276 (void) mpickobj(mtmp, obj);
2283 return 0; /* i.e. an exploded wand */
2285 impossible("%s wanted to perform action %d?", Monnam(mtmp),
2297 pline("For some reason, %s presence is known to you.",
2298 s_suffix(noit_mon_nam(mtmp)));
2300 pline("
\82È
\82º
\82©
\81C
\82 \82È
\82½
\82Í%s
\82Ì
\91¶
\8dÝ
\82É
\8bC
\82ª
\82Â
\82¢
\82½
\81D",
2301 noit_mon_nam(mtmp));
2305 cliparound(mtmp->mx, mtmp->my);
2307 show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp, rn2_on_display_rng));
2310 You_feel("aggravated at %s.", noit_mon_nam(mtmp));
2312 You("%s
\82É
\95 \82ª
\82½
\82Á
\82½
\81D", mon_nam(mtmp));
2313 display_nhwindow(WIN_MAP, TRUE);
2315 if (unconscious()) {
2318 nomovemsg = "Aggravated, you are jolted into full consciousness.";
2320 nomovemsg = "
\95 \82ª
\82½
\82Á
\82Ä
\82¢
\82Ä
\81C
\83s
\83\8a\83s
\83\8a\82µ
\82Ä
\82¢
\82é
\81D";
2322 newsym(mtmp->mx, mtmp->my);
2323 if (!canspotmon(mtmp))
2324 map_invisible(mtmp->mx, mtmp->my);
2331 struct permonst *pm = mtmp->data;
2332 int difficulty = mons[(monsndx(pm))].difficulty;
2334 if (is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
2335 || pm->mlet == S_GHOST || pm->mlet == S_KOP)
2337 /* Unlike other rnd_item functions, we only allow _weak_ monsters
2338 * to have this item; after all, the item will be used to strengthen
2339 * the monster and strong monsters won't use it at all...
2341 if (difficulty < 6 && !rn2(30))
2342 return rn2(6) ? POT_POLYMORPH : WAN_POLYMORPH;
2344 if (!rn2(40) && !nonliving(pm) && !is_vampshifter(mtmp))
2345 return AMULET_OF_LIFE_SAVING;
2351 return rn2(6) ? POT_SPEED : WAN_SPEED_MONSTER;
2353 if (mtmp->mpeaceful && !See_invisible)
2355 return rn2(6) ? POT_INVISIBILITY : WAN_MAKE_INVISIBLE;
2357 return POT_GAIN_LEVEL;
2364 searches_for_item(mon, obj)
2368 int typ = obj->otyp;
2370 if (is_animal(mon->data) || mindless(mon->data)
2371 || mon->data == &mons[PM_GHOST]) /* don't loot bones piles */
2374 if (typ == WAN_MAKE_INVISIBLE || typ == POT_INVISIBILITY)
2375 return (boolean) (!mon->minvis && !mon->invis_blkd
2376 && !attacktype(mon->data, AT_GAZE));
2377 if (typ == WAN_SPEED_MONSTER || typ == POT_SPEED)
2378 return (boolean) (mon->mspeed != MFAST);
2380 switch (obj->oclass) {
2384 if (typ == WAN_DIGGING)
2385 return (boolean) !is_floater(mon->data);
2386 if (typ == WAN_POLYMORPH)
2387 return (boolean) (mons[monsndx(mon->data)].difficulty < 6);
2388 if (objects[typ].oc_dir == RAY || typ == WAN_STRIKING
2389 || typ == WAN_TELEPORTATION || typ == WAN_CREATE_MONSTER)
2393 if (typ == POT_HEALING || typ == POT_EXTRA_HEALING
2394 || typ == POT_FULL_HEALING || typ == POT_POLYMORPH
2395 || typ == POT_GAIN_LEVEL || typ == POT_PARALYSIS
2396 || typ == POT_SLEEPING || typ == POT_ACID || typ == POT_CONFUSION)
2398 if (typ == POT_BLINDNESS && !attacktype(mon->data, AT_GAZE))
2402 if (typ == SCR_TELEPORTATION || typ == SCR_CREATE_MONSTER
2403 || typ == SCR_EARTH || typ == SCR_FIRE)
2407 if (typ == AMULET_OF_LIFE_SAVING)
2408 return (boolean) !(nonliving(mon->data) || is_vampshifter(mon));
2409 if (typ == AMULET_OF_REFLECTION)
2413 if (typ == PICK_AXE)
2414 return (boolean) needspick(mon->data);
2415 if (typ == UNICORN_HORN)
2416 return (boolean) (!obj->cursed && !is_unicorn(mon->data));
2417 if (typ == FROST_HORN || typ == FIRE_HORN)
2418 return (obj->spe > 0 && can_blow(mon));
2422 return (boolean) (((mon->misc_worn_check & W_ARMG) != 0L
2423 && touch_petrifies(&mons[obj->corpsenm]))
2424 || (!resists_ston(mon)
2425 && cures_stoning(mon, obj, FALSE)));
2427 return (boolean) (mcould_eat_tin(mon)
2428 && (!resists_ston(mon)
2429 && cures_stoning(mon, obj, TRUE)));
2431 return (boolean) touch_petrifies(&mons[obj->corpsenm]);
2441 mon_reflects(mon, str)
2445 struct obj *orefl = which_armor(mon, W_ARMS);
2447 if (orefl && orefl->otyp == SHIELD_OF_REFLECTION) {
2450 pline(str, s_suffix(mon_nam(mon)), "shield");
2452 pline(str, mon_nam(mon), "
\8f\82");
2453 makeknown(SHIELD_OF_REFLECTION);
2456 } else if (arti_reflects(MON_WEP(mon))) {
2457 /* due to wielded artifact weapon */
2460 pline(str, s_suffix(mon_nam(mon)), "weapon");
2462 pline(str, mon_nam(mon), "
\95\90\8aí");
2464 } else if ((orefl = which_armor(mon, W_AMUL))
2465 && orefl->otyp == AMULET_OF_REFLECTION) {
2468 pline(str, s_suffix(mon_nam(mon)), "amulet");
2470 pline(str, mon_nam(mon), "
\96\82\8f\9c\82¯");
2471 makeknown(AMULET_OF_REFLECTION);
2474 } else if ((orefl = which_armor(mon, W_ARM))
2475 && (orefl->otyp == SILVER_DRAGON_SCALES
2476 || orefl->otyp == SILVER_DRAGON_SCALE_MAIL)) {
2479 pline(str, s_suffix(mon_nam(mon)), "armor");
2481 pline(str, mon_nam(mon), "
\8aZ");
2483 } else if (mon->data == &mons[PM_SILVER_DRAGON]
2484 || mon->data == &mons[PM_CHROMATIC_DRAGON]) {
2485 /* Silver dragons only reflect when mature; babies do not */
2488 pline(str, s_suffix(mon_nam(mon)), "scales");
2490 pline(str, mon_nam(mon), "
\97Ø");
2498 const char *fmt, *str;
2500 /* Check from outermost to innermost objects */
2501 if (EReflecting & W_ARMS) {
2504 pline(fmt, str, "shield");
2506 pline(fmt, str, "
\8f\82");
2507 makeknown(SHIELD_OF_REFLECTION);
2510 } else if (EReflecting & W_WEP) {
2511 /* Due to wielded artifact weapon */
2514 pline(fmt, str, "weapon");
2516 pline(fmt, str, "
\95\90\8aí");
2518 } else if (EReflecting & W_AMUL) {
2521 pline(fmt, str, "medallion");
2523 pline(fmt, str, "
\83\81\83_
\83\8a\83I
\83\93");
2524 makeknown(AMULET_OF_REFLECTION);
2527 } else if (EReflecting & W_ARM) {
2530 pline(fmt, str, uskin ? "luster" : "armor");
2532 pline(fmt, str, uskin ? "
\82Â
\82â" : "
\8aZ");
2534 } else if (youmonst.data == &mons[PM_SILVER_DRAGON]) {
2537 pline(fmt, str, "scales");
2539 pline(fmt, str, "
\97Ø");
2545 /* cure mon's blindness (use_defensive, dog_eat, meatobj) */
2547 mcureblindness(mon, verbos)
2551 if (!mon->mcansee) {
2554 if (verbos && haseyes(mon->data))
2556 pline("%s can see again.", Monnam(mon));
2558 pline("%s
\82Í
\82Ü
\82½
\8c©
\82¦
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D", Monnam(mon));
2562 /* TRUE if the monster ate something */
2564 munstone(mon, by_you)
2571 if (resists_ston(mon))
2573 if (mon->meating || !mon->mcanmove || mon->msleeping)
2575 mon->mstrategy &= ~STRAT_WAITFORU;
2577 tinok = mcould_eat_tin(mon);
2578 for (obj = mon->minvent; obj; obj = obj->nobj) {
2579 if (cures_stoning(mon, obj, tinok)) {
2580 mon_consume_unstone(mon, obj, by_you, TRUE);
2588 mon_consume_unstone(mon, obj, by_you, stoning)
2592 boolean stoning; /* True: stop petrification, False: cure stun && confusion */
2594 boolean vis = canseemon(mon), tinned = obj->otyp == TIN,
2595 food = obj->otyp == CORPSE || tinned,
2596 acid = obj->otyp == POT_ACID
2597 || (food && acidic(&mons[obj->corpsenm])),
2598 lizard = food && obj->corpsenm == PM_LIZARD;
2599 int nutrit = food ? dog_nutrition(mon, obj) : 0; /* also sets meating */
2601 /* give a "<mon> is slowing down" message and also remove
2602 intrinsic speed (comparable to similar effect on the hero) */
2604 mon_adjust_speed(mon, -3, (struct obj *) 0);
2607 long save_quan = obj->quan;
2611 pline("%s %s %s.", Monnam(mon),
2612 (obj->oclass == POTION_CLASS)
2614 : (obj->otyp == TIN) ? "opens and eats the contents of"
2616 distant_name(obj, doname));
2618 pline("%s
\82Í%s
\82ð%s
\81D", Monnam(mon),
2619 distant_name(obj, doname),
2620 (obj->oclass == POTION_CLASS)
2622 : (obj->otyp == TIN) ? "
\8aJ
\82¯
\82Ä
\92\86\90g
\82ð
\90H
\82×
\82½"
2625 obj->quan = save_quan;
2629 (obj->oclass == POTION_CLASS) ? "drinking" : "chewing");
2631 You_hear("%s
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D",
2632 (obj->otyp == POT_ACID) ? "
\83S
\83N
\83\93" : "
\83N
\83`
\83\83\83N
\83`
\83\83");
2636 /* obj is now gone */
2638 if (acid && !tinned && !resists_acid(mon)) {
2639 mon->mhp -= rnd(15);
2642 pline("%s has a very bad case of stomach acid.", Monnam(mon));
2644 pline("%s
\82Í
\88Ý
\8e_
\82Ì
\92²
\8eq
\82ª
\82Æ
\82Ä
\82à
\88«
\82¢
\81D", Monnam(mon));
2645 if (DEADMONSTER(mon)) {
2647 pline("%s dies!", Monnam(mon));
2649 pline("%s
\82Í
\8e\80\82ñ
\82¾
\81I", Monnam(mon));
2651 /* hero gets credit (experience) and blame (possible loss
2652 of alignment and/or luck and/or telepathy depending on
2653 mon) for the kill but does not break pacifism conduct */
2654 xkilled(mon, XKILL_NOMSG | XKILL_NOCONDUCT);
2660 if (stoning && vis) {
2663 pline("What a pity - %s just ruined a future piece of art!",
2665 pline("
\82È
\82ñ
\82Ä
\82±
\82Æ
\82¾
\81I%s
\82Í
\8c|
\8fp
\8dì
\95i
\82É
\82È
\82ê
\82½
\82©
\82à
\82µ
\82ê
\82È
\82¢
\82Ì
\82É
\81I",
2669 pline("%s seems limber!", Monnam(mon));
2671 pline("%s
\82Í
\91Ì
\82ª
\8f_
\82ç
\82©
\82
\82È
\82Á
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82é
\81I", Monnam(mon));
2673 if (lizard && (mon->mconf || mon->mstun)) {
2676 if (vis && !is_bat(mon->data) && mon->data != &mons[PM_STALKER])
2678 pline("%s seems steadier now.", Monnam(mon));
2680 pline("%s
\82Í
\82æ
\82è
\8fä
\95v
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D", Monnam(mon));
2682 if (mon->mtame && !mon->isminion && nutrit > 0) {
2683 struct edog *edog = EDOG(mon);
2685 if (edog->hungrytime < monstermoves)
2686 edog->hungrytime = monstermoves;
2687 edog->hungrytime += nutrit;
2690 /* use up monster's next move */
2691 mon->movement -= NORMAL_SPEED;
2692 mon->mlstmv = monstermoves;
2695 /* decide whether obj can cure petrification; also used when picking up */
2697 cures_stoning(mon, obj, tinok)
2702 if (obj->otyp == POT_ACID)
2704 if (obj->otyp != CORPSE && (obj->otyp != TIN || !tinok))
2706 /* corpse, or tin that mon can open */
2707 if (obj->corpsenm == NON_PM) /* empty/special tin */
2709 return (boolean) (obj->corpsenm == PM_LIZARD
2710 || (acidic(&mons[obj->corpsenm])
2711 && (obj->corpsenm != PM_GREEN_SLIME
2712 || slimeproof(mon->data))));
2719 struct obj *obj, *mwep;
2722 /* monkeys who manage to steal tins can't open and eat them
2723 even if they happen to also have the appropriate tool */
2724 if (is_animal(mon->data))
2727 mwep = MON_WEP(mon);
2728 welded_wep = mwep && mwelded(mwep);
2729 /* this is different from the player; tin opener or dagger doesn't
2730 have to be wielded, and knife can be used instead of dagger */
2731 for (obj = mon->minvent; obj; obj = obj->nobj) {
2732 /* if stuck with a cursed weapon, don't check rest of inventory */
2733 if (welded_wep && obj != mwep)
2736 if (obj->otyp == TIN_OPENER
2737 || (obj->oclass == WEAPON_CLASS
2738 && (objects[obj->otyp].oc_skill == P_DAGGER
2739 || objects[obj->otyp].oc_skill == P_KNIFE)))
2745 /* TRUE if monster does something to avoid turning into green slime */
2747 munslime(mon, by_you)
2751 struct obj *obj, odummy;
2752 struct permonst *mptr = mon->data;
2755 * muse_unslime() gives "mon starts turning green", "mon zaps
2756 * itself with a wand of fire", and "mon's slime burns away"
2757 * messages. Monsters who don't get any chance at that just have
2758 * (via our caller) newcham()'s "mon turns into slime" feedback.
2761 if (slimeproof(mptr))
2763 if (mon->meating || !mon->mcanmove || mon->msleeping)
2765 mon->mstrategy &= ~STRAT_WAITFORU;
2767 /* if monster can breathe fire, do so upon self; a monster who deals
2768 fire damage by biting, clawing, gazing, and especially exploding
2769 isn't able to cure itself of green slime with its own attack
2770 [possible extension: monst capable of casting high level clerical
2771 spells could toss pillar of fire at self--probably too suicidal] */
2772 if (!mon->mcan && !mon->mspec_used
2773 && attacktype_fordmg(mptr, AT_BREA, AD_FIRE)) {
2774 odummy = zeroobj; /* otyp == STRANGE_OBJECT */
2775 return muse_unslime(mon, &odummy, (struct trap *) 0, by_you);
2778 /* same MUSE criteria as use_defensive() */
2779 if (!is_animal(mptr) && !mindless(mptr)) {
2782 for (obj = mon->minvent; obj; obj = obj->nobj)
2783 if (cures_sliming(mon, obj))
2784 return muse_unslime(mon, obj, (struct trap *) 0, by_you);
2786 if (((t = t_at(mon->mx, mon->my)) == 0 || t->ttyp != FIRE_TRAP)
2787 && mptr->mmove && !mon->mtrapped) {
2788 int xy[2][8], x, y, idx, ridx, nxy = 0;
2790 for (x = mon->mx - 1; x <= mon->mx + 1; ++x)
2791 for (y = mon->my - 1; y <= mon->my + 1; ++y)
2792 if (isok(x, y) && accessible(x, y)
2793 && !m_at(x, y) && (x != u.ux || y != u.uy)) {
2794 xy[0][nxy] = x, xy[1][nxy] = y;
2797 for (idx = 0; idx < nxy; ++idx) {
2798 ridx = rn1(nxy - idx, idx);
2801 xy[0][idx] = xy[0][ridx];
2804 xy[1][idx] = xy[1][ridx];
2807 if ((t = t_at(xy[0][idx], xy[1][idx])) != 0
2808 && t->ttyp == FIRE_TRAP)
2812 if (t && t->ttyp == FIRE_TRAP)
2813 return muse_unslime(mon, (struct obj *) &zeroobj, t, by_you);
2820 /* mon uses an item--selected by caller--to burn away incipient slime */
2822 muse_unslime(mon, obj, trap, by_you)
2826 boolean by_you; /* true: if mon kills itself, hero gets credit/blame */
2827 { /* [by_you not honored if 'mon' triggers fire trap]. */
2828 struct obj *odummyp;
2829 int otyp = obj->otyp, dmg = 0;
2830 boolean vis = canseemon(mon), res = TRUE;
2834 pline("%s starts turning %s.", Monnam(mon),
2835 green_mon(mon) ? "into ooze" : hcolor(NH_GREEN));
2837 pline("%s
\82Í%s
\82É
\82È
\82è
\82Í
\82¶
\82ß
\82½
\81D", Monnam(mon),
2838 green_mon(mon) ? "
\83X
\83\89\83C
\83\80" : hcolor(NH_GREEN));
2840 /* -4 => sliming, causes quiet loss of enhanced speed */
2841 mon_adjust_speed(mon, -4, (struct obj *) 0);
2844 const char *Mnam = vis ? Monnam(mon) : 0;
2846 if (mon->mx == trap->tx && mon->my == trap->ty) {
2849 pline("%s triggers %s fire trap!", Mnam,
2850 trap->tseen ? "the" : "a");
2852 pline("%s
\82Í
\89\8a\82Ìã©
\82ð
\94
\93®
\82³
\82¹
\82½
\81I", Mnam);
2855 remove_monster(mon->mx, mon->my);
2856 newsym(mon->mx, mon->my);
2857 place_monster(mon, trap->tx, trap->ty);
2858 if (mon->wormno) /* won't happen; worms don't MUSE to unslime */
2860 newsym(mon->mx, mon->my);
2863 pline("%s %s %s %s fire trap!", Mnam,
2864 vtense(fakename[0], locomotion(mon->data, "move")),
2865 is_floater(mon->data) ? "over" : "onto",
2866 trap->tseen ? "the" : "a");
2868 pline("%s
\82Í
\89\8a\82Ìã©
\82É
\94ò
\82Ñ
\8d\9e\82ñ
\82¾
\81I", Mnam);
2871 /* hack to avoid mintrap()'s chance of avoiding known trap */
2872 mon->mtrapseen &= ~(1 << (FIRE_TRAP - 1));
2874 } else if (otyp == STRANGE_OBJECT) {
2875 /* monster is using fire breath on self */
2878 pline("%s breathes fire on %sself.", Monnam(mon), mhim(mon));
2880 pline("%s
\82Í
\89Î
\82ð
\82Í
\82¢
\82½
\81D", Monnam(mon));
2882 mon->mspec_used = rn1(10, 5);
2883 /* -21 => monster's fire breath; 1 => # of damage dice */
2884 dmg = zhitm(mon, by_you ? 21 : -21, 1, &odummyp);
2885 } else if (otyp == SCR_FIRE) {
2888 if (cansee(mon->mx, mon->my))
2890 pline("Oh, what a pretty fire!");
2892 pline("
\82 \82ç
\81A
\82È
\82ñ
\82Ä
\82©
\82í
\82¢
\82¢
\89Î
\82¾
\81I");
2893 if (vis && !objects[otyp].oc_name_known
2894 && !objects[otyp].oc_uname)
2896 m_useup(mon, obj); /* after docall() */
2897 vis = FALSE; /* skip makeknown() below */
2898 res = FALSE; /* failed to cure sliming */
2900 dmg = (2 * (rn1(3, 3) + 2 * bcsign(obj)) + 1) / 3;
2901 m_useup(mon, obj); /* before explode() */
2902 /* -11 => monster's fireball */
2903 explode(mon->mx, mon->my, -11, dmg, SCROLL_CLASS,
2904 /* by_you: override -11 for mon but not others */
2905 by_you ? -EXPL_FIERY : EXPL_FIERY);
2906 dmg = 0; /* damage has been applied by explode() */
2908 } else { /* wand/horn of fire w/ positive charge count */
2909 if (obj->otyp == FIRE_HORN)
2910 mplayhorn(mon, obj, TRUE);
2912 mzapwand(mon, obj, TRUE);
2913 /* -1 => monster's wand of fire; 2 => # of damage dice */
2914 dmg = zhitm(mon, by_you ? 1 : -1, 2, &odummyp);
2918 /* zhitm() applies damage but doesn't kill creature off;
2919 for fire breath, dmg is going to be 0 (fire breathers are
2920 immune to fire damage) but for wand of fire or fire horn,
2921 'mon' could have taken damage so might die */
2922 if (DEADMONSTER(mon)) {
2924 /* mon killed self but hero gets credit and blame (except
2925 for pacifist conduct); xkilled()'s message would say
2926 "You killed/destroyed <mon>" so give our own message */
2929 pline("%s is %s by the fire!", Monnam(mon),
2930 nonliving(mon->data) ? "destroyed" : "killed");
2932 pline("%s
\82Í
\89Î
\82Å%s
\82³
\82ê
\82½
\81I", Monnam(mon),
2933 nonliving(mon->data) ? "
\93|" : "
\8eE");
2935 xkilled(mon, XKILL_NOMSG | XKILL_NOCONDUCT);
2938 monkilled(mon, "fire", AD_FIRE);
2940 monkilled(mon, "
\89Î", AD_FIRE);
2942 /* non-fatal damage occurred */
2945 pline("%s is burned%s", Monnam(mon), exclam(dmg));
2947 pline("%s
\82Í
\94R
\82¦
\82½%s", Monnam(mon), exclam(dmg));
2951 if (res && !DEADMONSTER(mon))
2953 pline("%s slime is burned away!", s_suffix(Monnam(mon)));
2955 pline("%s
\82Ì
\83X
\83\89\83C
\83\80\82Í
\94R
\82¦
\82Â
\82«
\82½
\81I", Monnam(mon));
2956 if (otyp != STRANGE_OBJECT)
2959 /* use up monster's next move */
2960 mon->movement -= NORMAL_SPEED;
2961 mon->mlstmv = monstermoves;
2965 /* decide whether obj can be used to cure green slime */
2967 cures_sliming(mon, obj)
2971 /* scroll of fire, non-empty wand or horn of fire */
2972 if (obj->otyp == SCR_FIRE)
2973 return (haseyes(mon->data) && mon->mcansee);
2974 /* hero doesn't need hands or even limbs to zap, so mon doesn't either */
2975 return ((obj->otyp == WAN_FIRE
2976 || (obj->otyp == FIRE_HORN && can_blow(mon)))
2980 /* TRUE if monster appears to be green; for active TEXTCOLOR, we go by
2981 the display color, otherwise we just pick things that seem plausibly
2982 green (which doesn't necessarily match the TEXTCOLOR categorization) */
2987 struct permonst *ptr = mon->data;
2992 if (iflags.use_color)
2993 return (ptr->mcolor == CLR_GREEN || ptr->mcolor == CLR_BRIGHT_GREEN);
2997 if (strstri(ptr->mname, "green"))
2999 if (strstri(ptr->mname, "
\97Î"))
3002 switch (monsndx(ptr)) {
3003 case PM_FOREST_CENTAUR:
3004 case PM_GARTER_SNAKE:
3015 if (is_elf(ptr) && !is_prince(ptr) && !is_lord(ptr)
3016 && ptr != &mons[PM_GREY_ELF])