1 /* NetHack 3.6 muse.c $NHDT-Date: 1469840918 2016/07/30 01:08:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.78 $ */
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_DCL boolean
FDECL(m_use_healing
, (struct monst
*));
27 STATIC_PTR
int FDECL(mbhitm
, (struct monst
*, struct obj
*));
28 STATIC_DCL
void FDECL(mbhit
, (struct monst
*, int,
29 int FDECL((*), (MONST_P
, OBJ_P
)),
30 int FDECL((*), (OBJ_P
, OBJ_P
)), struct obj
*));
31 STATIC_DCL
void FDECL(you_aggravate
, (struct monst
*));
32 STATIC_DCL
void FDECL(mon_consume_unstone
, (struct monst
*, struct obj
*,
33 BOOLEAN_P
, BOOLEAN_P
));
34 STATIC_DCL boolean
FDECL(cures_stoning
, (struct monst
*, struct obj
*,
36 STATIC_DCL boolean
FDECL(mcould_eat_tin
, (struct monst
*));
37 STATIC_DCL boolean
FDECL(muse_unslime
, (struct monst
*, struct obj
*,
38 struct trap
*, BOOLEAN_P
));
39 STATIC_DCL
int FDECL(cures_sliming
, (struct monst
*, struct obj
*));
40 STATIC_DCL boolean
FDECL(green_mon
, (struct monst
*));
42 static struct musable
{
43 struct obj
*offensive
;
44 struct obj
*defensive
;
46 int has_offense
, has_defense
, has_misc
;
47 /* =0, no capability; otherwise, different numbers.
48 * If it's an object, the object is also set (it's 0 otherwise).
51 static int trapx
, trapy
;
52 static boolean zap_oseen
; /* for wands which use mbhitm and are zapped at
53 * players. We usually want an oseen local to
54 * the function, but this is impossible since the
55 * function mbhitm has to be compatible with the
56 * normal zap routines, and those routines don't
57 * remember who zapped the wand. */
59 /* Any preliminary checks which may result in the monster being unable to use
60 * the item. Returns 0 if nothing happened, 2 if the monster can't do
61 * anything (i.e. it teleported) and 1 if it's dead.
72 vis
= cansee(mon
->mx
, mon
->my
);
74 if (obj
->oclass
== POTION_CLASS
) {
76 static const char *empty
= "The potion turns out to be empty.";
77 const char *potion_descr
;
80 potion_descr
= OBJ_DESCR(objects
[obj
->otyp
]);
81 if (potion_descr
&& !strcmp(potion_descr
, "milky")) {
82 if (!(mvitals
[PM_GHOST
].mvflags
& G_GONE
)
83 && !rn2(POTION_OCCUPANT_CHANCE(mvitals
[PM_GHOST
].born
))) {
84 if (!enexto(&cc
, mon
->mx
, mon
->my
, &mons
[PM_GHOST
]))
88 mtmp
= makemon(&mons
[PM_GHOST
], cc
.x
, cc
.y
, NO_MM_FLAGS
);
95 "As %s opens the bottle, an enormous %s emerges!",
97 Hallucination
? rndmonnam(NULL
)
98 : (const char *) "ghost");
99 pline("%s is frightened to death, and unable to move.",
102 paralyze_monst(mon
, 3);
107 if (potion_descr
&& !strcmp(potion_descr
, "smoky")
108 && !(mvitals
[PM_DJINNI
].mvflags
& G_GONE
)
109 && !rn2(POTION_OCCUPANT_CHANCE(mvitals
[PM_DJINNI
].born
))) {
110 if (!enexto(&cc
, mon
->mx
, mon
->my
, &mons
[PM_DJINNI
]))
114 mtmp
= makemon(&mons
[PM_DJINNI
], cc
.x
, cc
.y
, NO_MM_FLAGS
);
120 pline("In a cloud of smoke, %s emerges!", a_monnam(mtmp
));
121 pline("%s speaks.", vis
? Monnam(mtmp
) : Something
);
122 /* I suspect few players will be upset that monsters */
123 /* can't wish for wands of death here.... */
125 verbalize("You freed me!");
129 verbalize("It is about time.");
131 pline("%s vanishes.", Monnam(mtmp
));
138 if (obj
->oclass
== WAND_CLASS
&& obj
->cursed
139 && !rn2(WAND_BACKFIRE_CHANCE
)) {
140 int dam
= d(obj
->spe
+ 2, 6);
142 /* 3.6.1: no Deaf filter; 'if' message doesn't warrant it, 'else'
143 message doesn't need it since You_hear() has one of its own */
145 pline("%s zaps %s, which suddenly explodes!", Monnam(mon
),
148 /* same near/far threshold as mzapmsg() */
149 int range
= couldsee(mon
->mx
, mon
->my
) /* 9 or 5 */
150 ? (BOLT_LIM
+ 1) : (BOLT_LIM
- 3);
152 You_hear("a zap and an explosion %s.",
153 (distu(mon
->mx
, mon
->my
) <= range
* range
)
154 ? "nearby" : "in the distance");
159 monkilled(mon
, "", AD_RBRE
);
162 m
.has_defense
= m
.has_offense
= m
.has_misc
= 0;
163 /* Only one needed to be set to 0 but the others are harmless */
169 mzapmsg(mtmp
, otmp
, self
)
174 if (!canseemon(mtmp
)) {
175 int range
= couldsee(mtmp
->mx
, mtmp
->my
) /* 9 or 5 */
176 ? (BOLT_LIM
+ 1) : (BOLT_LIM
- 3);
178 You_hear("a %s zap.", (distu(mtmp
->mx
, mtmp
->my
) <= range
* range
)
179 ? "nearby" : "distant");
181 pline("%s zaps %sself with %s!", Monnam(mtmp
), mhim(mtmp
),
184 pline("%s zaps %s!", Monnam(mtmp
), an(xname(otmp
)));
194 boolean vismon
= canseemon(mtmp
);
200 return; /* no feedback */
202 otmp
->dknown
= 1; /* seeing or hearing it read reveals its label */
203 /* shouldn't be able to hear curse/bless status of unseen scrolls;
204 for priest characters, bknown will always be set during naming */
205 savebknown
= otmp
->bknown
;
206 saverole
= Role_switch
;
209 if (Role_if(PM_PRIEST
))
212 Strcpy(onambuf
, singular(otmp
, doname
));
213 Role_switch
= saverole
;
214 otmp
->bknown
= savebknown
;
217 pline("%s reads %s!", Monnam(mtmp
), onambuf
);
219 You_hear("%s reading %s.",
220 x_monnam(mtmp
, ARTICLE_A
, (char *) 0,
221 (SUPPRESS_IT
| SUPPRESS_INVISIBLE
| SUPPRESS_SADDLE
),
226 pline("Being confused, %s mispronounces the magic words...",
227 vismon
? mon_nam(mtmp
) : mhe(mtmp
));
231 mquaffmsg(mtmp
, otmp
)
235 if (canseemon(mtmp
)) {
237 pline("%s drinks %s!", Monnam(mtmp
), singular(otmp
, doname
));
239 You_hear("a chugging sound.");
242 /* Defines for various types of stuff. The order in which monsters prefer
243 * to use them is determined by the order of the code logic, not the
244 * numerical order in which they are defined.
246 #define MUSE_SCR_TELEPORTATION 1
247 #define MUSE_WAN_TELEPORTATION_SELF 2
248 #define MUSE_POT_HEALING 3
249 #define MUSE_POT_EXTRA_HEALING 4
250 #define MUSE_WAN_DIGGING 5
251 #define MUSE_TRAPDOOR 6
252 #define MUSE_TELEPORT_TRAP 7
253 #define MUSE_UPSTAIRS 8
254 #define MUSE_DOWNSTAIRS 9
255 #define MUSE_WAN_CREATE_MONSTER 10
256 #define MUSE_SCR_CREATE_MONSTER 11
257 #define MUSE_UP_LADDER 12
258 #define MUSE_DN_LADDER 13
259 #define MUSE_SSTAIRS 14
260 #define MUSE_WAN_TELEPORTATION 15
261 #define MUSE_BUGLE 16
262 #define MUSE_UNICORN_HORN 17
263 #define MUSE_POT_FULL_HEALING 18
264 #define MUSE_LIZARD_CORPSE 19
266 #define MUSE_INNATE_TPT 9999
267 * We cannot use this. Since monsters get unlimited teleportation, if they
268 * were allowed to teleport at will you could never catch them. Instead,
269 * assume they only teleport at random times, despite the inconsistency
270 * that if you polymorph into one you teleport at will.
278 if ((obj
= m_carrying(mtmp
, POT_FULL_HEALING
)) != 0) {
280 m
.has_defense
= MUSE_POT_FULL_HEALING
;
283 if ((obj
= m_carrying(mtmp
, POT_EXTRA_HEALING
)) != 0) {
285 m
.has_defense
= MUSE_POT_EXTRA_HEALING
;
288 if ((obj
= m_carrying(mtmp
, POT_HEALING
)) != 0) {
290 m
.has_defense
= MUSE_POT_HEALING
;
296 /* Select a defensive item/action for a monster. Returns TRUE iff one is
302 register struct obj
*obj
= 0;
304 int x
= mtmp
->mx
, y
= mtmp
->my
;
305 boolean stuck
= (mtmp
== u
.ustuck
);
306 boolean immobile
= (mtmp
->data
->mmove
== 0);
309 if (is_animal(mtmp
->data
) || mindless(mtmp
->data
))
311 if (dist2(x
, y
, mtmp
->mux
, mtmp
->muy
) > 25)
313 if (u
.uswallow
&& stuck
)
316 m
.defensive
= (struct obj
*) 0;
319 /* since unicorn horns don't get used up, the monster would look
320 * silly trying to use the same cursed horn round after round
322 if (mtmp
->mconf
|| mtmp
->mstun
|| !mtmp
->mcansee
) {
323 if (!is_unicorn(mtmp
->data
) && !nohands(mtmp
->data
)) {
324 for (obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
)
325 if (obj
->otyp
== UNICORN_HORN
&& !obj
->cursed
)
328 if (obj
|| is_unicorn(mtmp
->data
)) {
330 m
.has_defense
= MUSE_UNICORN_HORN
;
335 if (mtmp
->mconf
|| mtmp
->mstun
) {
336 struct obj
*liztin
= 0;
338 for (obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
) {
339 if (obj
->otyp
== CORPSE
&& obj
->corpsenm
== PM_LIZARD
) {
341 m
.has_defense
= MUSE_LIZARD_CORPSE
;
343 } else if (obj
->otyp
== TIN
&& obj
->corpsenm
== PM_LIZARD
) {
347 /* confused or stunned monster might not be able to open tin */
348 if (liztin
&& mcould_eat_tin(mtmp
) && rn2(3)) {
349 m
.defensive
= liztin
;
350 /* tin and corpse ultimately end up being handled the same */
351 m
.has_defense
= MUSE_LIZARD_CORPSE
;
356 /* It so happens there are two unrelated cases when we might want to
357 * check specifically for healing alone. The first is when the monster
358 * is blind (healing cures blindness). The second is when the monster
359 * is peaceful; then we don't want to flee the player, and by
360 * coincidence healing is all there is that doesn't involve fleeing.
361 * These would be hard to combine because of the control flow.
362 * Pestilence won't use healing even when blind.
364 if (!mtmp
->mcansee
&& !nohands(mtmp
->data
)
365 && mtmp
->data
!= &mons
[PM_PESTILENCE
]) {
366 if (m_use_healing(mtmp
))
370 fraction
= u
.ulevel
< 10 ? 5 : u
.ulevel
< 14 ? 4 : 3;
371 if (mtmp
->mhp
>= mtmp
->mhpmax
372 || (mtmp
->mhp
>= 10 && mtmp
->mhp
* fraction
>= mtmp
->mhpmax
))
375 if (mtmp
->mpeaceful
) {
376 if (!nohands(mtmp
->data
)) {
377 if (m_use_healing(mtmp
))
383 if (stuck
|| immobile
) {
384 ; /* fleeing by stairs or traps is not possible */
385 } else if (levl
[x
][y
].typ
== STAIRS
) {
386 if (x
== xdnstair
&& y
== ydnstair
) {
387 if (!is_floater(mtmp
->data
))
388 m
.has_defense
= MUSE_DOWNSTAIRS
;
389 } else if (x
== xupstair
&& y
== yupstair
) {
390 m
.has_defense
= MUSE_UPSTAIRS
;
391 } else if (sstairs
.sx
&& x
== sstairs
.sx
&& y
== sstairs
.sy
) {
392 if (sstairs
.up
|| !is_floater(mtmp
->data
))
393 m
.has_defense
= MUSE_SSTAIRS
;
395 } else if (levl
[x
][y
].typ
== LADDER
) {
396 if (x
== xupladder
&& y
== yupladder
) {
397 m
.has_defense
= MUSE_UP_LADDER
;
398 } else if (x
== xdnladder
&& y
== ydnladder
) {
399 if (!is_floater(mtmp
->data
))
400 m
.has_defense
= MUSE_DN_LADDER
;
401 } else if (sstairs
.sx
&& x
== sstairs
.sx
&& y
== sstairs
.sy
) {
402 if (sstairs
.up
|| !is_floater(mtmp
->data
))
403 m
.has_defense
= MUSE_SSTAIRS
;
406 /* Note: trap doors take precedence over teleport traps. */
407 int xx
, yy
, i
, locs
[10][2];
408 boolean ignore_boulders
= (verysmall(mtmp
->data
)
409 || throws_rocks(mtmp
->data
)
410 || passes_walls(mtmp
->data
)),
411 diag_ok
= !NODIAG(monsndx(mtmp
->data
));
413 for (i
= 0; i
< 10; ++i
) /* 10: 9 spots plus sentinel */
414 locs
[i
][0] = locs
[i
][1] = 0;
415 /* collect viable spots; monster's <mx,my> comes first */
416 locs
[0][0] = x
, locs
[0][1] = y
;
418 for (xx
= x
- 1; xx
<= x
+ 1; xx
++)
419 for (yy
= y
- 1; yy
<= y
+ 1; yy
++)
420 if (isok(xx
, yy
) && (xx
!= x
|| yy
!= y
)) {
421 locs
[i
][0] = xx
, locs
[i
][1] = yy
;
424 /* look for a suitable trap among the viable spots */
425 for (i
= 0; i
< 10; ++i
) {
426 xx
= locs
[i
][0], yy
= locs
[i
][1];
428 break; /* we've run out of spots */
429 /* skip if it's hero's location
430 or a diagonal spot and monster can't move diagonally
431 or some other monster is there */
432 if ((xx
== u
.ux
&& yy
== u
.uy
)
433 || (xx
!= x
&& yy
!= y
&& !diag_ok
)
434 || (level
.monsters
[xx
][yy
] && !(xx
== x
&& yy
== y
)))
436 /* skip if there's no trap or can't/won't move onto trap */
437 if ((t
= t_at(xx
, yy
)) == 0
438 || (!ignore_boulders
&& sobj_at(BOULDER
, xx
, yy
))
439 || onscary(xx
, yy
, mtmp
))
441 /* use trap if it's the correct type */
442 if ((t
->ttyp
== TRAPDOOR
|| t
->ttyp
== HOLE
)
443 && !is_floater(mtmp
->data
)
444 && !mtmp
->isshk
&& !mtmp
->isgd
&& !mtmp
->ispriest
445 && Can_fall_thru(&u
.uz
)) {
448 m
.has_defense
= MUSE_TRAPDOOR
;
449 break; /* no need to look at any other spots */
450 } else if (t
->ttyp
== TELEP_TRAP
) {
453 m
.has_defense
= MUSE_TELEPORT_TRAP
;
458 if (nohands(mtmp
->data
)) /* can't use objects */
461 if (is_mercenary(mtmp
->data
) && (obj
= m_carrying(mtmp
, BUGLE
)) != 0) {
465 /* Distance is arbitrary. What we really want to do is
466 * have the soldier play the bugle when it sees or
467 * remembers soldiers nearby...
469 for (xx
= x
- 3; xx
<= x
+ 3; xx
++) {
470 for (yy
= y
- 3; yy
<= y
+ 3; yy
++) {
471 if (!isok(xx
, yy
) || (xx
== x
&& yy
== y
))
473 if ((mon
= m_at(xx
, yy
)) != 0 && is_mercenary(mon
->data
)
474 && mon
->data
!= &mons
[PM_GUARD
]
475 && (mon
->msleeping
|| !mon
->mcanmove
)) {
477 m
.has_defense
= MUSE_BUGLE
;
478 goto toot
; /* double break */
486 /* use immediate physical escape prior to attempting magic */
487 if (m
.has_defense
) /* stairs, trap door or tele-trap, bugle alert */
490 /* kludge to cut down on trap destruction (particularly portals) */
492 if (t
&& (t
->ttyp
== PIT
|| t
->ttyp
== SPIKED_PIT
|| t
->ttyp
== WEB
493 || t
->ttyp
== BEAR_TRAP
))
494 t
= 0; /* ok for monster to dig here */
496 #define nomore(x) if (m.has_defense == x) continue;
497 /* selection could be improved by collecting all possibilities
498 into an array and then picking one at random */
499 for (obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
) {
500 /* don't always use the same selection pattern */
501 if (m
.has_defense
&& !rn2(3))
504 /* nomore(MUSE_WAN_DIGGING); */
505 if (m
.has_defense
== MUSE_WAN_DIGGING
)
507 if (obj
->otyp
== WAN_DIGGING
&& obj
->spe
> 0 && !stuck
&& !t
508 && !mtmp
->isshk
&& !mtmp
->isgd
&& !mtmp
->ispriest
509 && !is_floater(mtmp
->data
)
510 /* monsters digging in Sokoban can ruin things */
512 /* digging wouldn't be effective; assume they know that */
513 && !(levl
[x
][y
].wall_info
& W_NONDIGGABLE
)
514 && !(Is_botlevel(&u
.uz
) || In_endgame(&u
.uz
))
515 && !(is_ice(x
, y
) || is_pool(x
, y
) || is_lava(x
, y
))
516 && !(mtmp
->data
== &mons
[PM_VLAD_THE_IMPALER
]
517 && In_V_tower(&u
.uz
))) {
519 m
.has_defense
= MUSE_WAN_DIGGING
;
521 nomore(MUSE_WAN_TELEPORTATION_SELF
);
522 nomore(MUSE_WAN_TELEPORTATION
);
523 if (obj
->otyp
== WAN_TELEPORTATION
&& obj
->spe
> 0) {
524 /* use the TELEP_TRAP bit to determine if they know
525 * about noteleport on this level or not. Avoids
526 * ineffective re-use of teleportation. This does
527 * mean if the monster leaves the level, they'll know
528 * about teleport traps.
530 if (!level
.flags
.noteleport
531 || !(mtmp
->mtrapseen
& (1 << (TELEP_TRAP
- 1)))) {
533 m
.has_defense
= (mon_has_amulet(mtmp
))
534 ? MUSE_WAN_TELEPORTATION
535 : MUSE_WAN_TELEPORTATION_SELF
;
538 nomore(MUSE_SCR_TELEPORTATION
);
539 if (obj
->otyp
== SCR_TELEPORTATION
&& mtmp
->mcansee
540 && haseyes(mtmp
->data
)
541 && (!obj
->cursed
|| (!(mtmp
->isshk
&& inhishop(mtmp
))
542 && !mtmp
->isgd
&& !mtmp
->ispriest
))) {
543 /* see WAN_TELEPORTATION case above */
544 if (!level
.flags
.noteleport
545 || !(mtmp
->mtrapseen
& (1 << (TELEP_TRAP
- 1)))) {
547 m
.has_defense
= MUSE_SCR_TELEPORTATION
;
551 if (mtmp
->data
!= &mons
[PM_PESTILENCE
]) {
552 nomore(MUSE_POT_FULL_HEALING
);
553 if (obj
->otyp
== POT_FULL_HEALING
) {
555 m
.has_defense
= MUSE_POT_FULL_HEALING
;
557 nomore(MUSE_POT_EXTRA_HEALING
);
558 if (obj
->otyp
== POT_EXTRA_HEALING
) {
560 m
.has_defense
= MUSE_POT_EXTRA_HEALING
;
562 nomore(MUSE_WAN_CREATE_MONSTER
);
563 if (obj
->otyp
== WAN_CREATE_MONSTER
&& obj
->spe
> 0) {
565 m
.has_defense
= MUSE_WAN_CREATE_MONSTER
;
567 nomore(MUSE_POT_HEALING
);
568 if (obj
->otyp
== POT_HEALING
) {
570 m
.has_defense
= MUSE_POT_HEALING
;
572 } else { /* Pestilence */
573 nomore(MUSE_POT_FULL_HEALING
);
574 if (obj
->otyp
== POT_SICKNESS
) {
576 m
.has_defense
= MUSE_POT_FULL_HEALING
;
578 nomore(MUSE_WAN_CREATE_MONSTER
);
579 if (obj
->otyp
== WAN_CREATE_MONSTER
&& obj
->spe
> 0) {
581 m
.has_defense
= MUSE_WAN_CREATE_MONSTER
;
584 nomore(MUSE_SCR_CREATE_MONSTER
);
585 if (obj
->otyp
== SCR_CREATE_MONSTER
) {
587 m
.has_defense
= MUSE_SCR_CREATE_MONSTER
;
591 return (boolean
) !!m
.has_defense
;
595 /* Perform a defensive action for a monster. Must be called immediately
596 * after find_defensive(). Return values are 0: did something, 1: died,
597 * 2: did something and can't attack again (i.e. teleported).
603 int i
, fleetim
, how
= 0;
604 struct obj
*otmp
= m
.defensive
;
605 boolean vis
, vismon
, oseen
;
606 const char *Mnam
, *mcsa
= "%s can see again.";
608 if ((i
= precheck(mtmp
, otmp
)) != 0)
610 vis
= cansee(mtmp
->mx
, mtmp
->my
);
611 vismon
= canseemon(mtmp
);
612 oseen
= otmp
&& vismon
;
614 /* when using defensive choice to run away, we want monster to avoid
615 rushing right straight back; don't override if already scared */
616 fleetim
= !mtmp
->mflee
? (33 - (30 * mtmp
->mhp
/ mtmp
->mhpmax
)) : 0;
618 if (fleetim && !m->iswiz) { \
619 monflee(m, fleetim, FALSE, FALSE); \
622 switch (m
.has_defense
) {
623 case MUSE_UNICORN_HORN
:
626 pline("%s uses a unicorn horn!", Monnam(mtmp
));
628 pline_The("tip of %s's horn glows!", mon_nam(mtmp
));
630 if (!mtmp
->mcansee
) {
634 pline(mcsa
, Monnam(mtmp
));
635 } else if (mtmp
->mconf
|| mtmp
->mstun
) {
636 mtmp
->mconf
= mtmp
->mstun
= 0;
638 pline("%s seems steadier now.", Monnam(mtmp
));
640 impossible("No need for unicorn horn?");
644 pline("%s plays %s!", Monnam(mtmp
), doname(otmp
));
646 You_hear("a bugle playing reveille!");
647 awaken_soldiers(mtmp
);
649 case MUSE_WAN_TELEPORTATION_SELF
:
650 if ((mtmp
->isshk
&& inhishop(mtmp
)) || mtmp
->isgd
|| mtmp
->ispriest
)
653 mzapmsg(mtmp
, otmp
, TRUE
);
655 how
= WAN_TELEPORTATION
;
657 if (tele_restrict(mtmp
)) { /* mysterious force... */
658 if (vismon
&& how
) /* mentions 'teleport' */
660 /* monster learns that teleportation isn't useful here */
661 if (level
.flags
.noteleport
)
662 mtmp
->mtrapseen
|= (1 << (TELEP_TRAP
- 1));
665 if ((mon_has_amulet(mtmp
) || On_W_tower_level(&u
.uz
)) && !rn2(3)) {
667 pline("%s seems disoriented for a moment.", Monnam(mtmp
));
672 (void) rloc(mtmp
, TRUE
);
674 case MUSE_WAN_TELEPORTATION
:
676 mzapmsg(mtmp
, otmp
, FALSE
);
679 mbhit(mtmp
, rn1(8, 6), mbhitm
, bhito
, otmp
);
680 /* monster learns that teleportation isn't useful here */
681 if (level
.flags
.noteleport
)
682 mtmp
->mtrapseen
|= (1 << (TELEP_TRAP
- 1));
685 case MUSE_SCR_TELEPORTATION
: {
686 int obj_is_cursed
= otmp
->cursed
;
688 if (mtmp
->isshk
|| mtmp
->isgd
|| mtmp
->ispriest
)
691 mreadmsg(mtmp
, otmp
);
692 m_useup(mtmp
, otmp
); /* otmp might be free'ed */
693 how
= SCR_TELEPORTATION
;
694 if (obj_is_cursed
|| mtmp
->mconf
) {
698 if (mon_has_amulet(mtmp
) || In_endgame(&u
.uz
)) {
700 pline("%s seems very disoriented for a moment.",
704 nlev
= random_teleport_level();
705 if (nlev
== depth(&u
.uz
)) {
707 pline("%s shudders for a moment.", Monnam(mtmp
));
710 get_level(&flev
, nlev
);
711 migrate_to_level(mtmp
, ledger_no(&flev
), MIGR_RANDOM
,
714 makeknown(SCR_TELEPORTATION
);
719 case MUSE_WAN_DIGGING
: {
723 mzapmsg(mtmp
, otmp
, FALSE
);
726 makeknown(WAN_DIGGING
);
727 if (IS_FURNITURE(levl
[mtmp
->mx
][mtmp
->my
].typ
)
728 || IS_DRAWBRIDGE(levl
[mtmp
->mx
][mtmp
->my
].typ
)
729 || (is_drawbridge_wall(mtmp
->mx
, mtmp
->my
) >= 0)
730 || (sstairs
.sx
&& sstairs
.sx
== mtmp
->mx
731 && sstairs
.sy
== mtmp
->my
)) {
732 pline_The("digging ray is ineffective.");
735 if (!Can_dig_down(&u
.uz
) && !levl
[mtmp
->mx
][mtmp
->my
].candig
) {
737 pline_The("%s here is too hard to dig in.",
738 surface(mtmp
->mx
, mtmp
->my
));
741 ttmp
= maketrap(mtmp
->mx
, mtmp
->my
, HOLE
);
746 pline("%s has made a hole in the %s.", Monnam(mtmp
),
747 surface(mtmp
->mx
, mtmp
->my
));
748 pline("%s %s through...", Monnam(mtmp
),
749 is_flyer(mtmp
->data
) ? "dives" : "falls");
751 You_hear("%s crash through the %s.", something
,
752 surface(mtmp
->mx
, mtmp
->my
));
753 /* we made sure that there is a level for mtmp to go to */
754 migrate_to_level(mtmp
, ledger_no(&u
.uz
) + 1, MIGR_RANDOM
,
758 case MUSE_WAN_CREATE_MONSTER
: {
760 /* pm: 0 => random, eel => aquatic, croc => amphibious */
761 struct permonst
*pm
=
762 !is_pool(mtmp
->mx
, mtmp
->my
)
764 : &mons
[u
.uinwater
? PM_GIANT_EEL
: PM_CROCODILE
];
767 if (!enexto(&cc
, mtmp
->mx
, mtmp
->my
, pm
))
769 mzapmsg(mtmp
, otmp
, FALSE
);
771 mon
= makemon((struct permonst
*) 0, cc
.x
, cc
.y
, NO_MM_FLAGS
);
772 if (mon
&& canspotmon(mon
) && oseen
)
773 makeknown(WAN_CREATE_MONSTER
);
776 case MUSE_SCR_CREATE_MONSTER
: {
778 struct permonst
*pm
= 0, *fish
= 0;
781 boolean known
= FALSE
;
785 if (mtmp
->mconf
|| otmp
->cursed
)
788 pm
= fish
= &mons
[PM_ACID_BLOB
];
789 else if (is_pool(mtmp
->mx
, mtmp
->my
))
790 fish
= &mons
[u
.uinwater
? PM_GIANT_EEL
: PM_CROCODILE
];
791 mreadmsg(mtmp
, otmp
);
793 /* `fish' potentially gives bias towards water locations;
794 `pm' is what to actually create (0 => random) */
795 if (!enexto(&cc
, mtmp
->mx
, mtmp
->my
, fish
))
797 mon
= makemon(pm
, cc
.x
, cc
.y
, NO_MM_FLAGS
);
798 if (mon
&& canspotmon(mon
))
801 /* The only case where we don't use oseen. For wands, you
802 * have to be able to see the monster zap the wand to know
803 * what type it is. For teleport scrolls, you have to see
804 * the monster to know it teleported.
807 makeknown(SCR_CREATE_MONSTER
);
808 else if (!objects
[SCR_CREATE_MONSTER
].oc_name_known
809 && !objects
[SCR_CREATE_MONSTER
].oc_uname
)
815 /* trap doors on "bottom" levels of dungeons are rock-drop
816 * trap doors, not holes in the floor. We check here for
819 if (Is_botlevel(&u
.uz
))
823 struct trap
*t
= t_at(trapx
, trapy
);
826 pline("%s %s into a %s!", Mnam
,
827 vtense(Mnam
, locomotion(mtmp
->data
, "jump")),
828 (t
->ttyp
== TRAPDOOR
) ? "trap door" : "hole");
829 if (levl
[trapx
][trapy
].typ
== SCORR
) {
830 levl
[trapx
][trapy
].typ
= CORR
;
831 unblock_point(trapx
, trapy
);
833 seetrap(t_at(trapx
, trapy
));
836 /* don't use rloc_to() because worm tails must "move" */
837 remove_monster(mtmp
->mx
, mtmp
->my
);
838 newsym(mtmp
->mx
, mtmp
->my
); /* update old location */
839 place_monster(mtmp
, trapx
, trapy
);
842 newsym(trapx
, trapy
);
844 migrate_to_level(mtmp
, ledger_no(&u
.uz
) + 1, MIGR_RANDOM
,
849 if (ledger_no(&u
.uz
) == 1)
850 goto escape
; /* impossible; level 1 upstairs are SSTAIRS */
851 if (Inhell
&& mon_has_amulet(mtmp
) && !rn2(4)
852 && (dunlev(&u
.uz
) < dunlevs_in_dungeon(&u
.uz
) - 3)) {
855 "As %s climbs the stairs, a mysterious force momentarily surrounds %s...",
856 mon_nam(mtmp
), mhim(mtmp
));
857 /* simpler than for the player; this will usually be
858 the Wizard and he'll immediately go right to the
859 upstairs, so there's not much point in having any
860 chance for a random position on the current level */
861 migrate_to_level(mtmp
, ledger_no(&u
.uz
) + 1, MIGR_RANDOM
,
865 pline("%s escapes upstairs!", Monnam(mtmp
));
866 migrate_to_level(mtmp
, ledger_no(&u
.uz
) - 1, MIGR_STAIRS_DOWN
,
870 case MUSE_DOWNSTAIRS
:
873 pline("%s escapes downstairs!", Monnam(mtmp
));
874 migrate_to_level(mtmp
, ledger_no(&u
.uz
) + 1, MIGR_STAIRS_UP
,
880 pline("%s escapes up the ladder!", Monnam(mtmp
));
881 migrate_to_level(mtmp
, ledger_no(&u
.uz
) - 1, MIGR_LADDER_DOWN
,
887 pline("%s escapes down the ladder!", Monnam(mtmp
));
888 migrate_to_level(mtmp
, ledger_no(&u
.uz
) + 1, MIGR_LADDER_UP
,
893 if (ledger_no(&u
.uz
) == 1) {
895 /* Monsters without the Amulet escape the dungeon and
896 * are gone for good when they leave up the up stairs.
897 * A monster with the Amulet would leave it behind
898 * (mongone -> mdrop_special_objs) but we force any
899 * monster who manages to acquire it or the invocation
900 * tools to stick around instead of letting it escape.
902 if (mon_has_special(mtmp
))
905 pline("%s escapes the dungeon!", Monnam(mtmp
));
910 pline("%s escapes %sstairs!", Monnam(mtmp
),
911 sstairs
.up
? "up" : "down");
912 /* going from the Valley to Castle (Stronghold) has no sstairs
913 to target, but having sstairs.<sx,sy> == <0,0> will work the
914 same as specifying MIGR_RANDOM when mon_arrive() eventually
915 places the monster, so we can use MIGR_SSTAIRS unconditionally */
916 migrate_to_level(mtmp
, ledger_no(&sstairs
.tolev
), MIGR_SSTAIRS
,
919 case MUSE_TELEPORT_TRAP
:
923 pline("%s %s onto a teleport trap!", Mnam
,
924 vtense(Mnam
, locomotion(mtmp
->data
, "jump")));
925 seetrap(t_at(trapx
, trapy
));
927 /* don't use rloc_to() because worm tails must "move" */
928 remove_monster(mtmp
->mx
, mtmp
->my
);
929 newsym(mtmp
->mx
, mtmp
->my
); /* update old location */
930 place_monster(mtmp
, trapx
, trapy
);
933 newsym(trapx
, trapy
);
936 case MUSE_POT_HEALING
:
937 mquaffmsg(mtmp
, otmp
);
938 i
= d(6 + 2 * bcsign(otmp
), 4);
940 if (mtmp
->mhp
> mtmp
->mhpmax
)
941 mtmp
->mhp
= ++mtmp
->mhpmax
;
942 if (!otmp
->cursed
&& !mtmp
->mcansee
) {
946 pline(mcsa
, Monnam(mtmp
));
949 pline("%s looks better.", Monnam(mtmp
));
951 makeknown(POT_HEALING
);
954 case MUSE_POT_EXTRA_HEALING
:
955 mquaffmsg(mtmp
, otmp
);
956 i
= d(6 + 2 * bcsign(otmp
), 8);
958 if (mtmp
->mhp
> mtmp
->mhpmax
)
959 mtmp
->mhp
= (mtmp
->mhpmax
+= (otmp
->blessed
? 5 : 2));
960 if (!mtmp
->mcansee
) {
964 pline(mcsa
, Monnam(mtmp
));
967 pline("%s looks much better.", Monnam(mtmp
));
969 makeknown(POT_EXTRA_HEALING
);
972 case MUSE_POT_FULL_HEALING
:
973 mquaffmsg(mtmp
, otmp
);
974 if (otmp
->otyp
== POT_SICKNESS
)
975 unbless(otmp
); /* Pestilence */
976 mtmp
->mhp
= (mtmp
->mhpmax
+= (otmp
->blessed
? 8 : 4));
977 if (!mtmp
->mcansee
&& otmp
->otyp
!= POT_SICKNESS
) {
981 pline(mcsa
, Monnam(mtmp
));
984 pline("%s looks completely healed.", Monnam(mtmp
));
986 makeknown(otmp
->otyp
);
989 case MUSE_LIZARD_CORPSE
:
990 /* not actually called for its unstoning effect */
991 mon_consume_unstone(mtmp
, otmp
, FALSE
, FALSE
);
994 return 0; /* i.e. an exploded wand */
996 impossible("%s wanted to perform action %d?", Monnam(mtmp
),
1005 rnd_defensive_item(mtmp
)
1008 struct permonst
*pm
= mtmp
->data
;
1009 int difficulty
= monstr
[(monsndx(pm
))];
1012 if (is_animal(pm
) || attacktype(pm
, AT_EXPL
) || mindless(mtmp
->data
)
1013 || pm
->mlet
== S_GHOST
|| pm
->mlet
== S_KOP
)
1016 switch (rn2(8 + (difficulty
> 3) + (difficulty
> 6) + (difficulty
> 8))) {
1019 if (level
.flags
.noteleport
&& ++trycnt
< 2)
1022 return WAN_TELEPORTATION
;
1026 return SCR_TELEPORTATION
;
1030 return WAN_CREATE_MONSTER
;
1033 return SCR_CREATE_MONSTER
;
1037 return POT_EXTRA_HEALING
;
1039 return (mtmp
->data
!= &mons
[PM_PESTILENCE
]) ? POT_FULL_HEALING
1042 if (is_floater(pm
) || mtmp
->isshk
|| mtmp
->isgd
|| mtmp
->ispriest
)
1051 #define MUSE_WAN_DEATH 1
1052 #define MUSE_WAN_SLEEP 2
1053 #define MUSE_WAN_FIRE 3
1054 #define MUSE_WAN_COLD 4
1055 #define MUSE_WAN_LIGHTNING 5
1056 #define MUSE_WAN_MAGIC_MISSILE 6
1057 #define MUSE_WAN_STRIKING 7
1058 #define MUSE_SCR_FIRE 8
1059 #define MUSE_POT_PARALYSIS 9
1060 #define MUSE_POT_BLINDNESS 10
1061 #define MUSE_POT_CONFUSION 11
1062 #define MUSE_FROST_HORN 12
1063 #define MUSE_FIRE_HORN 13
1064 #define MUSE_POT_ACID 14
1065 /*#define MUSE_WAN_TELEPORTATION 15*/
1066 #define MUSE_POT_SLEEPING 16
1067 #define MUSE_SCR_EARTH 17
1069 /* Select an offensive item/action for a monster. Returns TRUE iff one is
1073 find_offensive(mtmp
)
1076 register struct obj
*obj
;
1077 boolean reflection_skip
= (Reflecting
&& rn2(2));
1078 struct obj
*helmet
= which_armor(mtmp
, W_ARMH
);
1080 m
.offensive
= (struct obj
*) 0;
1082 if (mtmp
->mpeaceful
|| is_animal(mtmp
->data
) || mindless(mtmp
->data
)
1083 || nohands(mtmp
->data
))
1087 if (in_your_sanctuary(mtmp
, 0, 0))
1089 if (dmgtype(mtmp
->data
, AD_HEAL
)
1090 && !uwep
&& !uarmu
&& !uarm
&& !uarmh
1091 && !uarms
&& !uarmg
&& !uarmc
&& !uarmf
)
1093 /* all offensive items require orthogonal or diagonal targetting */
1094 if (!lined_up(mtmp
))
1097 #define nomore(x) if (m.has_offense == x) continue;
1098 /* this picks the last viable item rather than prioritizing choices */
1099 for (obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
) {
1100 if (!reflection_skip
) {
1101 nomore(MUSE_WAN_DEATH
);
1102 if (obj
->otyp
== WAN_DEATH
&& obj
->spe
> 0) {
1104 m
.has_offense
= MUSE_WAN_DEATH
;
1106 nomore(MUSE_WAN_SLEEP
);
1107 if (obj
->otyp
== WAN_SLEEP
&& obj
->spe
> 0 && multi
>= 0) {
1109 m
.has_offense
= MUSE_WAN_SLEEP
;
1111 nomore(MUSE_WAN_FIRE
);
1112 if (obj
->otyp
== WAN_FIRE
&& obj
->spe
> 0) {
1114 m
.has_offense
= MUSE_WAN_FIRE
;
1116 nomore(MUSE_FIRE_HORN
);
1117 if (obj
->otyp
== FIRE_HORN
&& obj
->spe
> 0 && can_blow(mtmp
)) {
1119 m
.has_offense
= MUSE_FIRE_HORN
;
1121 nomore(MUSE_WAN_COLD
);
1122 if (obj
->otyp
== WAN_COLD
&& obj
->spe
> 0) {
1124 m
.has_offense
= MUSE_WAN_COLD
;
1126 nomore(MUSE_FROST_HORN
);
1127 if (obj
->otyp
== FROST_HORN
&& obj
->spe
> 0 && can_blow(mtmp
)) {
1129 m
.has_offense
= MUSE_FROST_HORN
;
1131 nomore(MUSE_WAN_LIGHTNING
);
1132 if (obj
->otyp
== WAN_LIGHTNING
&& obj
->spe
> 0) {
1134 m
.has_offense
= MUSE_WAN_LIGHTNING
;
1136 nomore(MUSE_WAN_MAGIC_MISSILE
);
1137 if (obj
->otyp
== WAN_MAGIC_MISSILE
&& obj
->spe
> 0) {
1139 m
.has_offense
= MUSE_WAN_MAGIC_MISSILE
;
1142 nomore(MUSE_WAN_STRIKING
);
1143 if (obj
->otyp
== WAN_STRIKING
&& obj
->spe
> 0) {
1145 m
.has_offense
= MUSE_WAN_STRIKING
;
1147 nomore(MUSE_POT_PARALYSIS
);
1148 if (obj
->otyp
== POT_PARALYSIS
&& multi
>= 0) {
1150 m
.has_offense
= MUSE_POT_PARALYSIS
;
1152 nomore(MUSE_POT_BLINDNESS
);
1153 if (obj
->otyp
== POT_BLINDNESS
&& !attacktype(mtmp
->data
, AT_GAZE
)) {
1155 m
.has_offense
= MUSE_POT_BLINDNESS
;
1157 nomore(MUSE_POT_CONFUSION
);
1158 if (obj
->otyp
== POT_CONFUSION
) {
1160 m
.has_offense
= MUSE_POT_CONFUSION
;
1162 nomore(MUSE_POT_SLEEPING
);
1163 if (obj
->otyp
== POT_SLEEPING
) {
1165 m
.has_offense
= MUSE_POT_SLEEPING
;
1167 nomore(MUSE_POT_ACID
);
1168 if (obj
->otyp
== POT_ACID
) {
1170 m
.has_offense
= MUSE_POT_ACID
;
1172 /* we can safely put this scroll here since the locations that
1173 * are in a 1 square radius are a subset of the locations that
1174 * are in wand or throwing range (in other words, always lined_up())
1176 nomore(MUSE_SCR_EARTH
);
1177 if (obj
->otyp
== SCR_EARTH
1178 && ((helmet
&& is_metallic(helmet
)) || mtmp
->mconf
1179 || amorphous(mtmp
->data
) || passes_walls(mtmp
->data
)
1180 || noncorporeal(mtmp
->data
) || unsolid(mtmp
->data
)
1182 && dist2(mtmp
->mx
, mtmp
->my
, mtmp
->mux
, mtmp
->muy
) <= 2
1183 && mtmp
->mcansee
&& haseyes(mtmp
->data
)
1184 && !Is_rogue_level(&u
.uz
)
1185 && (!In_endgame(&u
.uz
) || Is_earthlevel(&u
.uz
))) {
1187 m
.has_offense
= MUSE_SCR_EARTH
;
1190 nomore(MUSE_SCR_FIRE
);
1191 if (obj
->otyp
== SCR_FIRE
&& resists_fire(mtmp
)
1192 && dist2(mtmp
->mx
, mtmp
->my
, mtmp
->mux
, mtmp
->muy
) <= 2
1193 && mtmp
->mcansee
&& haseyes(mtmp
->data
)) {
1195 m
.has_offense
= MUSE_SCR_FIRE
;
1199 return (boolean
) !!m
.has_offense
;
1206 register struct monst
*mtmp
;
1207 register struct obj
*otmp
;
1210 boolean reveal_invis
= FALSE
;
1212 if (mtmp
!= &youmonst
) {
1213 mtmp
->msleeping
= 0;
1214 if (mtmp
->m_ap_type
)
1217 switch (otmp
->otyp
) {
1219 reveal_invis
= TRUE
;
1220 if (mtmp
== &youmonst
) {
1222 makeknown(WAN_STRIKING
);
1224 shieldeff(u
.ux
, u
.uy
);
1226 } else if (rnd(20) < 10 + u
.uac
) {
1227 pline_The("wand hits you!");
1229 if (Half_spell_damage
)
1230 tmp
= (tmp
+ 1) / 2;
1231 losehp(tmp
, "wand", KILLED_BY_AN
);
1233 pline_The("wand misses you.");
1236 } else if (resists_magm(mtmp
)) {
1237 shieldeff(mtmp
->mx
, mtmp
->my
);
1239 } else if (rnd(20) < 10 + find_mac(mtmp
)) {
1241 hit("wand", mtmp
, exclam(tmp
));
1242 (void) resist(mtmp
, otmp
->oclass
, tmp
, TELL
);
1243 if (cansee(mtmp
->mx
, mtmp
->my
) && zap_oseen
)
1244 makeknown(WAN_STRIKING
);
1247 if (cansee(mtmp
->mx
, mtmp
->my
) && zap_oseen
)
1248 makeknown(WAN_STRIKING
);
1251 case WAN_TELEPORTATION
:
1252 if (mtmp
== &youmonst
) {
1254 makeknown(WAN_TELEPORTATION
);
1257 /* for consistency with zap.c, don't identify */
1258 if (mtmp
->ispriest
&& *in_rooms(mtmp
->mx
, mtmp
->my
, TEMPLE
)) {
1259 if (cansee(mtmp
->mx
, mtmp
->my
))
1260 pline("%s resists the magic!", Monnam(mtmp
));
1261 } else if (!tele_restrict(mtmp
))
1262 (void) rloc(mtmp
, TRUE
);
1265 case WAN_CANCELLATION
:
1266 case SPE_CANCELLATION
:
1267 (void) cancel_monst(mtmp
, otmp
, FALSE
, TRUE
, FALSE
);
1271 if (mtmp
->mhp
> 0 && cansee(bhitpos
.x
, bhitpos
.y
)
1272 && !canspotmon(mtmp
))
1273 map_invisible(bhitpos
.x
, bhitpos
.y
);
1278 /* A modified bhit() for monsters. Based on bhit() in zap.c. Unlike
1279 * buzz(), bhit() doesn't take into account the possibility of a monster
1280 * zapping you, so we need a special function for it. (Unless someone wants
1281 * to merge the two functions...)
1284 mbhit(mon
, range
, fhitm
, fhito
, obj
)
1285 struct monst
*mon
; /* monster shooting the wand */
1286 register int range
; /* direction and range */
1287 int FDECL((*fhitm
), (MONST_P
, OBJ_P
));
1288 int FDECL((*fhito
), (OBJ_P
, OBJ_P
)); /* fns called when mon/obj hit */
1289 struct obj
*obj
; /* 2nd arg to fhitm/fhito */
1291 register struct monst
*mtmp
;
1292 register struct obj
*otmp
;
1296 bhitpos
.x
= mon
->mx
;
1297 bhitpos
.y
= mon
->my
;
1298 ddx
= sgn(mon
->mux
- mon
->mx
);
1299 ddy
= sgn(mon
->muy
- mon
->my
);
1301 while (range
-- > 0) {
1314 if (find_drawbridge(&x
, &y
))
1315 switch (obj
->otyp
) {
1317 destroy_drawbridge(x
, y
);
1319 if (bhitpos
.x
== u
.ux
&& bhitpos
.y
== u
.uy
) {
1320 (*fhitm
)(&youmonst
, obj
);
1322 } else if ((mtmp
= m_at(bhitpos
.x
, bhitpos
.y
)) != 0) {
1323 if (cansee(bhitpos
.x
, bhitpos
.y
) && !canspotmon(mtmp
))
1324 map_invisible(bhitpos
.x
, bhitpos
.y
);
1325 (*fhitm
)(mtmp
, obj
);
1328 /* modified by GAN to hit all objects */
1330 int hitanything
= 0;
1331 register struct obj
*next_obj
;
1333 for (otmp
= level
.objects
[bhitpos
.x
][bhitpos
.y
]; otmp
;
1335 /* Fix for polymorph bug, Tim Wright */
1336 next_obj
= otmp
->nexthere
;
1337 hitanything
+= (*fhito
)(otmp
, obj
);
1342 typ
= levl
[bhitpos
.x
][bhitpos
.y
].typ
;
1343 if (IS_DOOR(typ
) || typ
== SDOOR
) {
1344 switch (obj
->otyp
) {
1345 /* note: monsters don't use opening or locking magic
1346 at present, but keep these as placeholders */
1350 if (doorlock(obj
, bhitpos
.x
, bhitpos
.y
)) {
1352 makeknown(obj
->otyp
);
1353 /* if a shop door gets broken, add it to
1354 the shk's fix list (no cost to player) */
1355 if (levl
[bhitpos
.x
][bhitpos
.y
].doormask
== D_BROKEN
1356 && *in_rooms(bhitpos
.x
, bhitpos
.y
, SHOPBASE
))
1357 add_damage(bhitpos
.x
, bhitpos
.y
, 0L);
1363 || (IS_DOOR(typ
) && (levl
[bhitpos
.x
][bhitpos
.y
].doormask
1364 & (D_LOCKED
| D_CLOSED
)))) {
1372 /* Perform an offensive action for a monster. Must be called immediately
1373 * after find_offensive(). Return values are same as use_defensive().
1380 struct obj
*otmp
= m
.offensive
;
1383 /* offensive potions are not drunk, they're thrown */
1384 if (otmp
->oclass
!= POTION_CLASS
&& (i
= precheck(mtmp
, otmp
)) != 0)
1386 oseen
= otmp
&& canseemon(mtmp
);
1388 switch (m
.has_offense
) {
1389 case MUSE_WAN_DEATH
:
1390 case MUSE_WAN_SLEEP
:
1393 case MUSE_WAN_LIGHTNING
:
1394 case MUSE_WAN_MAGIC_MISSILE
:
1395 mzapmsg(mtmp
, otmp
, FALSE
);
1398 makeknown(otmp
->otyp
);
1400 buzz((int) (-30 - (otmp
->otyp
- WAN_MAGIC_MISSILE
)),
1401 (otmp
->otyp
== WAN_MAGIC_MISSILE
) ? 2 : 6, mtmp
->mx
, mtmp
->my
,
1402 sgn(mtmp
->mux
- mtmp
->mx
), sgn(mtmp
->muy
- mtmp
->my
));
1404 return (mtmp
->mhp
<= 0) ? 1 : 2;
1405 case MUSE_FIRE_HORN
:
1406 case MUSE_FROST_HORN
:
1408 makeknown(otmp
->otyp
);
1409 pline("%s plays a %s!", Monnam(mtmp
), xname(otmp
));
1411 You_hear("a horn being played.");
1414 buzz(-30 - ((otmp
->otyp
== FROST_HORN
) ? AD_COLD
- 1 : AD_FIRE
- 1),
1415 rn1(6, 6), mtmp
->mx
, mtmp
->my
, sgn(mtmp
->mux
- mtmp
->mx
),
1416 sgn(mtmp
->muy
- mtmp
->my
));
1418 return (mtmp
->mhp
<= 0) ? 1 : 2;
1419 case MUSE_WAN_TELEPORTATION
:
1420 case MUSE_WAN_STRIKING
:
1422 mzapmsg(mtmp
, otmp
, FALSE
);
1425 mbhit(mtmp
, rn1(8, 6), mbhitm
, bhito
, otmp
);
1428 case MUSE_SCR_EARTH
: {
1429 /* TODO: handle steeds */
1431 /* don't use monster fields after killing it */
1432 boolean confused
= (mtmp
->mconf
? TRUE
: FALSE
);
1433 int mmx
= mtmp
->mx
, mmy
= mtmp
->my
;
1434 boolean is_cursed
= otmp
->cursed
;
1436 mreadmsg(mtmp
, otmp
);
1437 /* Identify the scroll */
1438 if (canspotmon(mtmp
)) {
1439 pline_The("%s rumbles %s %s!", ceiling(mtmp
->mx
, mtmp
->my
),
1440 otmp
->blessed
? "around" : "above", mon_nam(mtmp
));
1442 makeknown(otmp
->otyp
);
1443 } else if (cansee(mtmp
->mx
, mtmp
->my
)) {
1444 pline_The("%s rumbles in the middle of nowhere!",
1445 ceiling(mtmp
->mx
, mtmp
->my
));
1447 map_invisible(mtmp
->mx
, mtmp
->my
);
1449 makeknown(otmp
->otyp
);
1452 /* Loop through the surrounding squares */
1453 for (x
= mmx
- 1; x
<= mmx
+ 1; x
++) {
1454 for (y
= mmy
- 1; y
<= mmy
+ 1; y
++) {
1455 /* Is this a suitable spot? */
1456 if (isok(x
, y
) && !closed_door(x
, y
)
1457 && !IS_ROCK(levl
[x
][y
].typ
) && !IS_AIR(levl
[x
][y
].typ
)
1458 && (((x
== mmx
) && (y
== mmy
)) ? !otmp
->blessed
1460 && (x
!= u
.ux
|| y
!= u
.uy
)) {
1461 (void) drop_boulder_on_monster(x
, y
, confused
, FALSE
);
1465 m_useup(mtmp
, otmp
);
1466 /* Attack the player */
1467 if (distmin(mmx
, mmy
, u
.ux
, u
.uy
) == 1 && !is_cursed
) {
1468 drop_boulder_on_player(confused
, !is_cursed
, FALSE
, TRUE
);
1471 return (mtmp
->mhp
<= 0) ? 1 : 2;
1474 case MUSE_SCR_FIRE
: {
1475 boolean vis
= cansee(mtmp
->mx
, mtmp
->my
);
1477 mreadmsg(mtmp
, otmp
);
1480 pline("Oh, what a pretty fire!");
1482 struct monst
*mtmp2
;
1486 pline_The("scroll erupts in a tower of flame!");
1487 shieldeff(mtmp
->mx
, mtmp
->my
);
1488 pline("%s is uninjured.", Monnam(mtmp
));
1489 (void) destroy_mitem(mtmp
, SCROLL_CLASS
, AD_FIRE
);
1490 (void) destroy_mitem(mtmp
, SPBOOK_CLASS
, AD_FIRE
);
1491 (void) destroy_mitem(mtmp
, POTION_CLASS
, AD_FIRE
);
1492 num
= (2 * (rn1(3, 3) + 2 * bcsign(otmp
)) + 1) / 3;
1493 if (Fire_resistance
)
1494 You("are not harmed.");
1496 if (Half_spell_damage
)
1497 num
= (num
+ 1) / 2;
1499 losehp(num
, "scroll of fire", KILLED_BY_AN
);
1500 for (mtmp2
= fmon
; mtmp2
; mtmp2
= mtmp2
->nmon
) {
1501 if (DEADMONSTER(mtmp2
))
1505 if (dist2(mtmp2
->mx
, mtmp2
->my
, mtmp
->mx
, mtmp
->my
) < 3) {
1506 if (resists_fire(mtmp2
))
1509 if (resists_cold(mtmp2
))
1510 mtmp2
->mhp
-= 3 * num
;
1511 if (mtmp2
->mhp
< 1) {
1521 case MUSE_POT_PARALYSIS
:
1522 case MUSE_POT_BLINDNESS
:
1523 case MUSE_POT_CONFUSION
:
1524 case MUSE_POT_SLEEPING
:
1526 /* Note: this setting of dknown doesn't suffice. A monster
1527 * which is out of sight might throw and it hits something _in_
1528 * sight, a problem not existing with wands because wand rays
1529 * are not objects. Also set dknown in mthrowu.c.
1531 if (cansee(mtmp
->mx
, mtmp
->my
)) {
1533 pline("%s hurls %s!", Monnam(mtmp
), singular(otmp
, doname
));
1535 m_throw(mtmp
, mtmp
->mx
, mtmp
->my
, sgn(mtmp
->mux
- mtmp
->mx
),
1536 sgn(mtmp
->muy
- mtmp
->my
),
1537 distmin(mtmp
->mx
, mtmp
->my
, mtmp
->mux
, mtmp
->muy
), otmp
);
1540 return 0; /* i.e. an exploded wand */
1542 impossible("%s wanted to perform action %d?", Monnam(mtmp
),
1550 rnd_offensive_item(mtmp
)
1553 struct permonst
*pm
= mtmp
->data
;
1554 int difficulty
= monstr
[(monsndx(pm
))];
1556 if (is_animal(pm
) || attacktype(pm
, AT_EXPL
) || mindless(mtmp
->data
)
1557 || pm
->mlet
== S_GHOST
|| pm
->mlet
== S_KOP
)
1559 if (difficulty
> 7 && !rn2(35))
1561 switch (rn2(9 - (difficulty
< 4) + 4 * (difficulty
> 6))) {
1563 struct obj
*helmet
= which_armor(mtmp
, W_ARMH
);
1565 if ((helmet
&& is_metallic(helmet
)) || amorphous(pm
)
1566 || passes_walls(pm
) || noncorporeal(pm
) || unsolid(pm
))
1568 } /* fall through */
1570 return WAN_STRIKING
;
1574 return POT_CONFUSION
;
1576 return POT_BLINDNESS
;
1578 return POT_SLEEPING
;
1580 return POT_PARALYSIS
;
1583 return WAN_MAGIC_MISSILE
;
1591 return WAN_LIGHTNING
;
1597 #define MUSE_POT_GAIN_LEVEL 1
1598 #define MUSE_WAN_MAKE_INVISIBLE 2
1599 #define MUSE_POT_INVISIBILITY 3
1600 #define MUSE_POLY_TRAP 4
1601 #define MUSE_WAN_POLYMORPH 5
1602 #define MUSE_POT_SPEED 6
1603 #define MUSE_WAN_SPEED_MONSTER 7
1604 #define MUSE_BULLWHIP 8
1605 #define MUSE_POT_POLYMORPH 9
1611 register struct obj
*obj
;
1612 struct permonst
*mdat
= mtmp
->data
;
1613 int x
= mtmp
->mx
, y
= mtmp
->my
;
1615 int xx
, yy
, pmidx
= NON_PM
;
1616 boolean immobile
= (mdat
->mmove
== 0);
1617 boolean stuck
= (mtmp
== u
.ustuck
);
1619 m
.misc
= (struct obj
*) 0;
1621 if (is_animal(mdat
) || mindless(mdat
))
1623 if (u
.uswallow
&& stuck
)
1626 /* We arbitrarily limit to times when a player is nearby for the
1627 * same reason as Junior Pac-Man doesn't have energizers eaten until
1628 * you can see them...
1630 if (dist2(x
, y
, mtmp
->mux
, mtmp
->muy
) > 36)
1633 if (!stuck
&& !immobile
&& (mtmp
->cham
== NON_PM
)
1634 && monstr
[(pmidx
= monsndx(mdat
))] < 6) {
1635 boolean ignore_boulders
= (verysmall(mdat
) || throws_rocks(mdat
)
1636 || passes_walls(mdat
)),
1637 diag_ok
= !NODIAG(pmidx
);
1639 for (xx
= x
- 1; xx
<= x
+ 1; xx
++)
1640 for (yy
= y
- 1; yy
<= y
+ 1; yy
++)
1641 if (isok(xx
, yy
) && (xx
!= u
.ux
|| yy
!= u
.uy
)
1642 && (diag_ok
|| xx
== x
|| yy
== y
)
1643 && ((xx
== x
&& yy
== y
) || !level
.monsters
[xx
][yy
]))
1644 if ((t
= t_at(xx
, yy
)) != 0
1645 && (ignore_boulders
|| !sobj_at(BOULDER
, xx
, yy
))
1646 && !onscary(xx
, yy
, mtmp
)) {
1647 /* use trap if it's the correct type */
1648 if (t
->ttyp
== POLY_TRAP
) {
1651 m
.has_misc
= MUSE_POLY_TRAP
;
1659 #define nomore(x) if (m.has_misc == x) continue
1661 * [bug?] Choice of item is not prioritized; the last viable one
1662 * in the monster's inventory will be chosen.
1663 * 'nomore()' is nearly worthless because it only screens checking
1664 * of duplicates when there is no alternate type in between them.
1666 for (obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
) {
1667 /* Monsters shouldn't recognize cursed items; this kludge is
1668 necessary to prevent serious problems though... */
1669 if (obj
->otyp
== POT_GAIN_LEVEL
1671 || (!mtmp
->isgd
&& !mtmp
->isshk
&& !mtmp
->ispriest
))) {
1673 m
.has_misc
= MUSE_POT_GAIN_LEVEL
;
1675 nomore(MUSE_BULLWHIP
);
1676 if (obj
->otyp
== BULLWHIP
&& !mtmp
->mpeaceful
1677 /* the random test prevents whip-wielding
1678 monster from attempting disarm every turn */
1679 && uwep
&& !rn2(5) && obj
== MON_WEP(mtmp
)
1680 /* hero's location must be known and adjacent */
1681 && mtmp
->mux
== u
.ux
&& mtmp
->muy
== u
.uy
1682 && distu(mtmp
->mx
, mtmp
->my
) <= 2
1683 /* don't bother if it can't work (this doesn't
1684 prevent cursed weapons from being targetted) */
1685 && (canletgo(uwep
, "")
1686 || (u
.twoweap
&& canletgo(uswapwep
, "")))) {
1688 m
.has_misc
= MUSE_BULLWHIP
;
1690 /* Note: peaceful/tame monsters won't make themselves
1691 * invisible unless you can see them. Not really right, but...
1693 nomore(MUSE_WAN_MAKE_INVISIBLE
);
1694 if (obj
->otyp
== WAN_MAKE_INVISIBLE
&& obj
->spe
> 0 && !mtmp
->minvis
1695 && !mtmp
->invis_blkd
&& (!mtmp
->mpeaceful
|| See_invisible
)
1696 && (!attacktype(mtmp
->data
, AT_GAZE
) || mtmp
->mcan
)) {
1698 m
.has_misc
= MUSE_WAN_MAKE_INVISIBLE
;
1700 nomore(MUSE_POT_INVISIBILITY
);
1701 if (obj
->otyp
== POT_INVISIBILITY
&& !mtmp
->minvis
1702 && !mtmp
->invis_blkd
&& (!mtmp
->mpeaceful
|| See_invisible
)
1703 && (!attacktype(mtmp
->data
, AT_GAZE
) || mtmp
->mcan
)) {
1705 m
.has_misc
= MUSE_POT_INVISIBILITY
;
1707 nomore(MUSE_WAN_SPEED_MONSTER
);
1708 if (obj
->otyp
== WAN_SPEED_MONSTER
&& obj
->spe
> 0
1709 && mtmp
->mspeed
!= MFAST
&& !mtmp
->isgd
) {
1711 m
.has_misc
= MUSE_WAN_SPEED_MONSTER
;
1713 nomore(MUSE_POT_SPEED
);
1714 if (obj
->otyp
== POT_SPEED
&& mtmp
->mspeed
!= MFAST
&& !mtmp
->isgd
) {
1716 m
.has_misc
= MUSE_POT_SPEED
;
1718 nomore(MUSE_WAN_POLYMORPH
);
1719 if (obj
->otyp
== WAN_POLYMORPH
&& obj
->spe
> 0
1720 && (mtmp
->cham
== NON_PM
) && monstr
[monsndx(mdat
)] < 6) {
1722 m
.has_misc
= MUSE_WAN_POLYMORPH
;
1724 nomore(MUSE_POT_POLYMORPH
);
1725 if (obj
->otyp
== POT_POLYMORPH
&& (mtmp
->cham
== NON_PM
)
1726 && monstr
[monsndx(mdat
)] < 6) {
1728 m
.has_misc
= MUSE_POT_POLYMORPH
;
1731 return (boolean
) !!m
.has_misc
;
1735 /* type of monster to polymorph into; defaults to one suitable for the
1736 current level rather than the totally arbitrary choice of newcham() */
1737 static struct permonst
*
1738 muse_newcham_mon(mon
)
1743 if ((m_armr
= which_armor(mon
, W_ARM
)) != 0) {
1744 if (Is_dragon_scales(m_armr
))
1745 return Dragon_scales_to_pm(m_armr
);
1746 else if (Is_dragon_mail(m_armr
))
1747 return Dragon_mail_to_pm(m_armr
);
1757 struct obj
*otmp
= m
.misc
;
1758 boolean vis
, vismon
, oseen
;
1761 if ((i
= precheck(mtmp
, otmp
)) != 0)
1763 vis
= cansee(mtmp
->mx
, mtmp
->my
);
1764 vismon
= canseemon(mtmp
);
1765 oseen
= otmp
&& vismon
;
1767 switch (m
.has_misc
) {
1768 case MUSE_POT_GAIN_LEVEL
:
1769 mquaffmsg(mtmp
, otmp
);
1771 if (Can_rise_up(mtmp
->mx
, mtmp
->my
, &u
.uz
)) {
1772 register int tolev
= depth(&u
.uz
) - 1;
1775 get_level(&tolevel
, tolev
);
1776 /* insurance against future changes... */
1777 if (on_level(&tolevel
, &u
.uz
))
1780 pline("%s rises up, through the %s!", Monnam(mtmp
),
1781 ceiling(mtmp
->mx
, mtmp
->my
));
1782 if (!objects
[POT_GAIN_LEVEL
].oc_name_known
1783 && !objects
[POT_GAIN_LEVEL
].oc_uname
)
1786 m_useup(mtmp
, otmp
);
1787 migrate_to_level(mtmp
, ledger_no(&tolevel
), MIGR_RANDOM
,
1793 pline("%s looks uneasy.", Monnam(mtmp
));
1794 if (!objects
[POT_GAIN_LEVEL
].oc_name_known
1795 && !objects
[POT_GAIN_LEVEL
].oc_uname
)
1798 m_useup(mtmp
, otmp
);
1803 pline("%s seems more experienced.", Monnam(mtmp
));
1805 makeknown(POT_GAIN_LEVEL
);
1806 m_useup(mtmp
, otmp
);
1807 if (!grow_up(mtmp
, (struct monst
*) 0))
1809 /* grew into genocided monster */
1811 case MUSE_WAN_MAKE_INVISIBLE
:
1812 case MUSE_POT_INVISIBILITY
:
1813 if (otmp
->otyp
== WAN_MAKE_INVISIBLE
) {
1814 mzapmsg(mtmp
, otmp
, TRUE
);
1817 mquaffmsg(mtmp
, otmp
);
1818 /* format monster's name before altering its visibility */
1819 Strcpy(nambuf
, mon_nam(mtmp
));
1820 mon_set_minvis(mtmp
);
1821 if (vismon
&& mtmp
->minvis
) { /* was seen, now invisible */
1822 if (canspotmon(mtmp
)) {
1823 pline("%s body takes on a %s transparency.",
1824 upstart(s_suffix(nambuf
)),
1825 Hallucination
? "normal" : "strange");
1827 pline("Suddenly you cannot see %s.", nambuf
);
1829 map_invisible(mtmp
->mx
, mtmp
->my
);
1832 makeknown(otmp
->otyp
);
1834 if (otmp
->otyp
== POT_INVISIBILITY
) {
1836 you_aggravate(mtmp
);
1837 m_useup(mtmp
, otmp
);
1840 case MUSE_WAN_SPEED_MONSTER
:
1841 mzapmsg(mtmp
, otmp
, TRUE
);
1843 mon_adjust_speed(mtmp
, 1, otmp
);
1845 case MUSE_POT_SPEED
:
1846 mquaffmsg(mtmp
, otmp
);
1847 /* note difference in potion effect due to substantially
1848 different methods of maintaining speed ratings:
1849 player's character becomes "very fast" temporarily;
1850 monster becomes "one stage faster" permanently */
1851 mon_adjust_speed(mtmp
, 1, otmp
);
1852 m_useup(mtmp
, otmp
);
1854 case MUSE_WAN_POLYMORPH
:
1855 mzapmsg(mtmp
, otmp
, TRUE
);
1857 (void) newcham(mtmp
, muse_newcham_mon(mtmp
), TRUE
, FALSE
);
1859 makeknown(WAN_POLYMORPH
);
1861 case MUSE_POT_POLYMORPH
:
1862 mquaffmsg(mtmp
, otmp
);
1864 pline("%s suddenly mutates!", Monnam(mtmp
));
1865 (void) newcham(mtmp
, muse_newcham_mon(mtmp
), FALSE
, FALSE
);
1867 makeknown(POT_POLYMORPH
);
1868 m_useup(mtmp
, otmp
);
1870 case MUSE_POLY_TRAP
:
1872 const char *Mnam
= Monnam(mtmp
);
1874 pline("%s deliberately %s onto a polymorph trap!", Mnam
,
1875 vtense(Mnam
, locomotion(mtmp
->data
, "jump")));
1878 seetrap(t_at(trapx
, trapy
));
1880 /* don't use rloc() due to worms */
1881 remove_monster(mtmp
->mx
, mtmp
->my
);
1882 newsym(mtmp
->mx
, mtmp
->my
);
1883 place_monster(mtmp
, trapx
, trapy
);
1886 newsym(trapx
, trapy
);
1888 (void) newcham(mtmp
, (struct permonst
*) 0, FALSE
, FALSE
);
1891 /* attempt to disarm hero */
1893 const char *The_whip
= vismon
? "The bullwhip" : "A whip";
1894 int where_to
= rn2(4);
1895 struct obj
*obj
= uwep
;
1897 char the_weapon
[BUFSZ
];
1899 if (!obj
|| !canletgo(obj
, "")
1900 || (u
.twoweap
&& canletgo(uswapwep
, "") && rn2(2)))
1903 break; /* shouldn't happen after find_misc() */
1905 Strcpy(the_weapon
, the(xname(obj
)));
1906 hand
= body_part(HAND
);
1908 hand
= makeplural(hand
);
1911 pline("%s flicks a bullwhip towards your %s!", Monnam(mtmp
),
1913 if (obj
->otyp
== HEAVY_IRON_BALL
) {
1914 pline("%s fails to wrap around %s.", The_whip
, the_weapon
);
1917 pline("%s wraps around %s you're wielding!", The_whip
,
1920 pline("%s welded to your %s%c",
1921 !is_plural(obj
) ? "It is" : "They are", hand
,
1922 !obj
->bknown
? '!' : '.');
1923 /* obj->bknown = 1; */ /* welded() takes care of this */
1927 pline_The("whip slips free."); /* not `The_whip' */
1929 } else if (where_to
== 3 && mon_hates_silver(mtmp
)
1930 && objects
[obj
->otyp
].oc_material
== SILVER
) {
1931 /* this monster won't want to catch a silver
1932 weapon; drop it at hero's feet instead */
1935 remove_worn_item(obj
, FALSE
);
1938 case 1: /* onto floor beneath mon */
1939 pline("%s yanks %s from your %s!", Monnam(mtmp
), the_weapon
,
1941 place_object(obj
, mtmp
->mx
, mtmp
->my
);
1943 case 2: /* onto floor beneath you */
1944 pline("%s yanks %s to the %s!", Monnam(mtmp
), the_weapon
,
1945 surface(u
.ux
, u
.uy
));
1948 case 3: /* into mon's inventory */
1949 pline("%s snatches %s!", Monnam(mtmp
), the_weapon
);
1950 (void) mpickobj(mtmp
, obj
);
1957 return 0; /* i.e. an exploded wand */
1959 impossible("%s wanted to perform action %d?", Monnam(mtmp
),
1970 pline("For some reason, %s presence is known to you.",
1971 s_suffix(noit_mon_nam(mtmp
)));
1974 cliparound(mtmp
->mx
, mtmp
->my
);
1976 show_glyph(mtmp
->mx
, mtmp
->my
, mon_to_glyph(mtmp
));
1978 You_feel("aggravated at %s.", noit_mon_nam(mtmp
));
1979 display_nhwindow(WIN_MAP
, TRUE
);
1981 if (unconscious()) {
1983 nomovemsg
= "Aggravated, you are jolted into full consciousness.";
1985 newsym(mtmp
->mx
, mtmp
->my
);
1986 if (!canspotmon(mtmp
))
1987 map_invisible(mtmp
->mx
, mtmp
->my
);
1994 struct permonst
*pm
= mtmp
->data
;
1995 int difficulty
= monstr
[(monsndx(pm
))];
1997 if (is_animal(pm
) || attacktype(pm
, AT_EXPL
) || mindless(mtmp
->data
)
1998 || pm
->mlet
== S_GHOST
|| pm
->mlet
== S_KOP
)
2000 /* Unlike other rnd_item functions, we only allow _weak_ monsters
2001 * to have this item; after all, the item will be used to strengthen
2002 * the monster and strong monsters won't use it at all...
2004 if (difficulty
< 6 && !rn2(30))
2005 return rn2(6) ? POT_POLYMORPH
: WAN_POLYMORPH
;
2007 if (!rn2(40) && !nonliving(pm
) && !is_vampshifter(mtmp
))
2008 return AMULET_OF_LIFE_SAVING
;
2014 return rn2(6) ? POT_SPEED
: WAN_SPEED_MONSTER
;
2016 if (mtmp
->mpeaceful
&& !See_invisible
)
2018 return rn2(6) ? POT_INVISIBILITY
: WAN_MAKE_INVISIBLE
;
2020 return POT_GAIN_LEVEL
;
2027 searches_for_item(mon
, obj
)
2031 int typ
= obj
->otyp
;
2033 if (is_animal(mon
->data
) || mindless(mon
->data
)
2034 || mon
->data
== &mons
[PM_GHOST
]) /* don't loot bones piles */
2037 if (typ
== WAN_MAKE_INVISIBLE
|| typ
== POT_INVISIBILITY
)
2038 return (boolean
) (!mon
->minvis
&& !mon
->invis_blkd
2039 && !attacktype(mon
->data
, AT_GAZE
));
2040 if (typ
== WAN_SPEED_MONSTER
|| typ
== POT_SPEED
)
2041 return (boolean
) (mon
->mspeed
!= MFAST
);
2043 switch (obj
->oclass
) {
2047 if (typ
== WAN_DIGGING
)
2048 return (boolean
) !is_floater(mon
->data
);
2049 if (typ
== WAN_POLYMORPH
)
2050 return (boolean
) (monstr
[monsndx(mon
->data
)] < 6);
2051 if (objects
[typ
].oc_dir
== RAY
|| typ
== WAN_STRIKING
2052 || typ
== WAN_TELEPORTATION
|| typ
== WAN_CREATE_MONSTER
)
2056 if (typ
== POT_HEALING
|| typ
== POT_EXTRA_HEALING
2057 || typ
== POT_FULL_HEALING
|| typ
== POT_POLYMORPH
2058 || typ
== POT_GAIN_LEVEL
|| typ
== POT_PARALYSIS
2059 || typ
== POT_SLEEPING
|| typ
== POT_ACID
|| typ
== POT_CONFUSION
)
2061 if (typ
== POT_BLINDNESS
&& !attacktype(mon
->data
, AT_GAZE
))
2065 if (typ
== SCR_TELEPORTATION
|| typ
== SCR_CREATE_MONSTER
2066 || typ
== SCR_EARTH
|| typ
== SCR_FIRE
)
2070 if (typ
== AMULET_OF_LIFE_SAVING
)
2071 return (boolean
) !(nonliving(mon
->data
) || is_vampshifter(mon
));
2072 if (typ
== AMULET_OF_REFLECTION
)
2076 if (typ
== PICK_AXE
)
2077 return (boolean
) needspick(mon
->data
);
2078 if (typ
== UNICORN_HORN
)
2079 return (boolean
) (!obj
->cursed
&& !is_unicorn(mon
->data
));
2080 if (typ
== FROST_HORN
|| typ
== FIRE_HORN
)
2081 return (obj
->spe
> 0 && can_blow(mon
));
2085 return (boolean
) (((mon
->misc_worn_check
& W_ARMG
) != 0L
2086 && touch_petrifies(&mons
[obj
->corpsenm
]))
2087 || (!resists_ston(mon
)
2088 && cures_stoning(mon
, obj
, FALSE
)));
2090 return (boolean
) (mcould_eat_tin(mon
)
2091 && (!resists_ston(mon
)
2092 && cures_stoning(mon
, obj
, TRUE
)));
2094 return (boolean
) touch_petrifies(&mons
[obj
->corpsenm
]);
2104 mon_reflects(mon
, str
)
2108 struct obj
*orefl
= which_armor(mon
, W_ARMS
);
2110 if (orefl
&& orefl
->otyp
== SHIELD_OF_REFLECTION
) {
2112 pline(str
, s_suffix(mon_nam(mon
)), "shield");
2113 makeknown(SHIELD_OF_REFLECTION
);
2116 } else if (arti_reflects(MON_WEP(mon
))) {
2117 /* due to wielded artifact weapon */
2119 pline(str
, s_suffix(mon_nam(mon
)), "weapon");
2121 } else if ((orefl
= which_armor(mon
, W_AMUL
))
2122 && orefl
->otyp
== AMULET_OF_REFLECTION
) {
2124 pline(str
, s_suffix(mon_nam(mon
)), "amulet");
2125 makeknown(AMULET_OF_REFLECTION
);
2128 } else if ((orefl
= which_armor(mon
, W_ARM
))
2129 && (orefl
->otyp
== SILVER_DRAGON_SCALES
2130 || orefl
->otyp
== SILVER_DRAGON_SCALE_MAIL
)) {
2132 pline(str
, s_suffix(mon_nam(mon
)), "armor");
2134 } else if (mon
->data
== &mons
[PM_SILVER_DRAGON
]
2135 || mon
->data
== &mons
[PM_CHROMATIC_DRAGON
]) {
2136 /* Silver dragons only reflect when mature; babies do not */
2138 pline(str
, s_suffix(mon_nam(mon
)), "scales");
2146 const char *fmt
, *str
;
2148 /* Check from outermost to innermost objects */
2149 if (EReflecting
& W_ARMS
) {
2151 pline(fmt
, str
, "shield");
2152 makeknown(SHIELD_OF_REFLECTION
);
2155 } else if (EReflecting
& W_WEP
) {
2156 /* Due to wielded artifact weapon */
2158 pline(fmt
, str
, "weapon");
2160 } else if (EReflecting
& W_AMUL
) {
2162 pline(fmt
, str
, "medallion");
2163 makeknown(AMULET_OF_REFLECTION
);
2166 } else if (EReflecting
& W_ARM
) {
2168 pline(fmt
, str
, uskin
? "luster" : "armor");
2170 } else if (youmonst
.data
== &mons
[PM_SILVER_DRAGON
]) {
2172 pline(fmt
, str
, "scales");
2178 /* TRUE if the monster ate something */
2180 munstone(mon
, by_you
)
2187 if (resists_ston(mon
))
2189 if (mon
->meating
|| !mon
->mcanmove
|| mon
->msleeping
)
2191 mon
->mstrategy
&= ~STRAT_WAITFORU
;
2193 tinok
= mcould_eat_tin(mon
);
2194 for (obj
= mon
->minvent
; obj
; obj
= obj
->nobj
) {
2195 if (cures_stoning(mon
, obj
, tinok
)) {
2196 mon_consume_unstone(mon
, obj
, by_you
, TRUE
);
2204 mon_consume_unstone(mon
, obj
, by_you
, stoning
)
2208 boolean stoning
; /* True: stop petrification, False: cure stun && confusion */
2210 boolean vis
= canseemon(mon
), tinned
= obj
->otyp
== TIN
,
2211 food
= obj
->otyp
== CORPSE
|| tinned
,
2212 acid
= obj
->otyp
== POT_ACID
2213 || (food
&& acidic(&mons
[obj
->corpsenm
])),
2214 lizard
= food
&& obj
->corpsenm
== PM_LIZARD
;
2215 int nutrit
= food
? dog_nutrition(mon
, obj
) : 0; /* also sets meating */
2217 /* give a "<mon> is slowing down" message and also remove
2218 intrinsic speed (comparable to similar effect on the hero) */
2220 mon_adjust_speed(mon
, -3, (struct obj
*) 0);
2223 long save_quan
= obj
->quan
;
2226 pline("%s %s %s.", Monnam(mon
),
2227 (obj
->oclass
== POTION_CLASS
)
2229 : (obj
->otyp
== TIN
) ? "opens and eats the contents of"
2231 distant_name(obj
, doname
));
2232 obj
->quan
= save_quan
;
2235 (obj
->oclass
== POTION_CLASS
) ? "drinking" : "chewing");
2238 /* obj is now gone */
2240 if (acid
&& !tinned
&& !resists_acid(mon
)) {
2241 mon
->mhp
-= rnd(15);
2243 pline("%s has a very bad case of stomach acid.", Monnam(mon
));
2244 if (mon
->mhp
<= 0) {
2245 pline("%s dies!", Monnam(mon
));
2247 /* hero gets credit (experience) and blame (possible loss
2248 of alignment and/or luck and/or telepathy depending on
2249 mon) for the kill but does not break pacifism conduct */
2250 xkilled(mon
, XKILL_NOMSG
| XKILL_NOCONDUCT
);
2256 if (stoning
&& vis
) {
2258 pline("What a pity - %s just ruined a future piece of art!",
2261 pline("%s seems limber!", Monnam(mon
));
2263 if (lizard
&& (mon
->mconf
|| mon
->mstun
)) {
2266 if (vis
&& !is_bat(mon
->data
) && mon
->data
!= &mons
[PM_STALKER
])
2267 pline("%s seems steadier now.", Monnam(mon
));
2269 if (mon
->mtame
&& !mon
->isminion
&& nutrit
> 0) {
2270 struct edog
*edog
= EDOG(mon
);
2272 if (edog
->hungrytime
< monstermoves
)
2273 edog
->hungrytime
= monstermoves
;
2274 edog
->hungrytime
+= nutrit
;
2277 /* use up monster's next move */
2278 mon
->movement
-= NORMAL_SPEED
;
2279 mon
->mlstmv
= monstermoves
;
2282 /* decide whether obj can cure petrification; also used when picking up */
2284 cures_stoning(mon
, obj
, tinok
)
2289 if (obj
->otyp
== POT_ACID
)
2291 if (obj
->otyp
!= CORPSE
&& (obj
->otyp
!= TIN
|| !tinok
))
2293 /* corpse, or tin that mon can open */
2294 return (boolean
) (obj
->corpsenm
== PM_LIZARD
2295 || (acidic(&mons
[obj
->corpsenm
])
2296 && (obj
->corpsenm
!= PM_GREEN_SLIME
2297 || slimeproof(mon
->data
))));
2304 struct obj
*obj
, *mwep
;
2307 /* monkeys who manage to steal tins can't open and eat them
2308 even if they happen to also have the appropriate tool */
2309 if (is_animal(mon
->data
))
2312 mwep
= MON_WEP(mon
);
2313 welded_wep
= mwep
&& mwelded(mwep
);
2314 /* this is different from the player; tin opener or dagger doesn't
2315 have to be wielded, and knife can be used instead of dagger */
2316 for (obj
= mon
->minvent
; obj
; obj
= obj
->nobj
) {
2317 /* if stuck with a cursed weapon, don't check rest of inventory */
2318 if (welded_wep
&& obj
!= mwep
)
2321 if (obj
->otyp
== TIN_OPENER
2322 || (obj
->oclass
== WEAPON_CLASS
2323 && (objects
[obj
->otyp
].oc_skill
== P_DAGGER
2324 || objects
[obj
->otyp
].oc_skill
== P_KNIFE
)))
2330 /* TRUE if monster does something to avoid turning into green slime */
2332 munslime(mon
, by_you
)
2336 struct obj
*obj
, odummy
;
2337 struct permonst
*mptr
= mon
->data
;
2340 * muse_unslime() gives "mon starts turning green", "mon zaps
2341 * itself with a wand of fire", and "mon's slime burns away"
2342 * messages. Monsters who don't get any chance at that just have
2343 * (via our caller) newcham()'s "mon turns into slime" feedback.
2346 if (slimeproof(mptr
))
2348 if (mon
->meating
|| !mon
->mcanmove
|| mon
->msleeping
)
2350 mon
->mstrategy
&= ~STRAT_WAITFORU
;
2352 /* if monster can breathe fire, do so upon self; a monster who deals
2353 fire damage by biting, clawing, gazing, and especially exploding
2354 isn't able to cure itself of green slime with its own attack
2355 [possible extension: monst capable of casting high level clerical
2356 spells could toss pillar of fire at self--probably too suicidal] */
2357 if (!mon
->mcan
&& !mon
->mspec_used
2358 && attacktype_fordmg(mptr
, AT_BREA
, AD_FIRE
)) {
2359 odummy
= zeroobj
; /* otyp == STRANGE_OBJECT */
2360 return muse_unslime(mon
, &odummy
, (struct trap
*) 0, by_you
);
2363 /* same MUSE criteria as use_defensive() */
2364 if (!is_animal(mptr
) && !mindless(mptr
)) {
2367 for (obj
= mon
->minvent
; obj
; obj
= obj
->nobj
)
2368 if (cures_sliming(mon
, obj
))
2369 return muse_unslime(mon
, obj
, (struct trap
*) 0, by_you
);
2371 if (((t
= t_at(mon
->mx
, mon
->my
)) == 0 || t
->ttyp
!= FIRE_TRAP
)
2372 && mptr
->mmove
&& !mon
->mtrapped
) {
2373 int xy
[2][8], x
, y
, idx
, ridx
, nxy
= 0;
2375 for (x
= mon
->mx
- 1; x
<= mon
->mx
+ 1; ++x
)
2376 for (y
= mon
->my
- 1; y
<= mon
->my
+ 1; ++y
)
2377 if (isok(x
, y
) && accessible(x
, y
)
2378 && !m_at(x
, y
) && (x
!= u
.ux
|| y
!= u
.uy
)) {
2379 xy
[0][nxy
] = x
, xy
[1][nxy
] = y
;
2382 for (idx
= 0; idx
< nxy
; ++idx
) {
2383 ridx
= rn1(nxy
- idx
, idx
);
2386 xy
[0][idx
] = xy
[0][ridx
];
2389 xy
[1][idx
] = xy
[1][ridx
];
2392 if ((t
= t_at(xy
[0][idx
], xy
[1][idx
])) != 0
2393 && t
->ttyp
== FIRE_TRAP
)
2397 if (t
&& t
->ttyp
== FIRE_TRAP
)
2398 return muse_unslime(mon
, &zeroobj
, t
, by_you
);
2405 /* mon uses an item--selected by caller--to burn away incipient slime */
2407 muse_unslime(mon
, obj
, trap
, by_you
)
2411 boolean by_you
; /* true: if mon kills itself, hero gets credit/blame */
2412 { /* [by_you not honored if 'mon' triggers fire trap]. */
2413 struct obj
*odummyp
;
2414 int otyp
= obj
->otyp
, dmg
= 0;
2415 boolean vis
= canseemon(mon
), res
= TRUE
;
2418 pline("%s starts turning %s.", Monnam(mon
),
2419 green_mon(mon
) ? "into ooze" : hcolor(NH_GREEN
));
2420 /* -4 => sliming, causes quiet loss of enhanced speed */
2421 mon_adjust_speed(mon
, -4, (struct obj
*) 0);
2424 const char *Mnam
= vis
? Monnam(mon
) : 0;
2426 if (mon
->mx
== trap
->tx
&& mon
->my
== trap
->ty
) {
2428 pline("%s triggers %s fire trap!", Mnam
,
2429 trap
->tseen
? "the" : "a");
2431 remove_monster(mon
->mx
, mon
->my
);
2432 newsym(mon
->mx
, mon
->my
);
2433 place_monster(mon
, trap
->tx
, trap
->ty
);
2434 if (mon
->wormno
) /* won't happen; worms don't MUSE to unslime */
2436 newsym(mon
->mx
, mon
->my
);
2438 pline("%s %s %s %s fire trap!", Mnam
,
2439 vtense(Mnam
, locomotion(mon
->data
, "move")),
2440 is_floater(mon
->data
) ? "over" : "onto",
2441 trap
->tseen
? "the" : "a");
2443 /* hack to avoid mintrap()'s chance of avoiding known trap */
2444 mon
->mtrapseen
&= ~(1 << (FIRE_TRAP
- 1));
2446 } else if (otyp
== STRANGE_OBJECT
) {
2447 /* monster is using fire breath on self */
2449 pline("%s breathes fire on %sself.", Monnam(mon
), mhim(mon
));
2451 mon
->mspec_used
= rn1(10, 5);
2452 /* -21 => monster's fire breath; 1 => # of damage dice */
2453 dmg
= zhitm(mon
, by_you
? 21 : -21, 1, &odummyp
);
2454 } else if (otyp
== SCR_FIRE
) {
2457 if (cansee(mon
->mx
, mon
->my
))
2458 pline("Oh, what a pretty fire!");
2459 if (vis
&& !objects
[otyp
].oc_name_known
2460 && !objects
[otyp
].oc_uname
)
2462 m_useup(mon
, obj
); /* after docall() */
2463 vis
= FALSE
; /* skip makeknown() below */
2464 res
= FALSE
; /* failed to cure sliming */
2466 m_useup(mon
, obj
); /* before explode() */
2467 dmg
= (2 * (rn1(3, 3) + 2 * bcsign(obj
)) + 1) / 3;
2468 /* -11 => monster's fireball */
2469 explode(mon
->mx
, mon
->my
, -11, dmg
, SCROLL_CLASS
,
2470 /* by_you: override -11 for mon but not others */
2471 by_you
? -EXPL_FIERY
: EXPL_FIERY
);
2472 dmg
= 0; /* damage has been applied by explode() */
2474 } else { /* wand/horn of fire w/ positive charge count */
2475 mzapmsg(mon
, obj
, TRUE
);
2477 /* -1 => monster's wand of fire; 2 => # of damage dice */
2478 dmg
= zhitm(mon
, by_you
? 1 : -1, 2, &odummyp
);
2482 /* zhitm() applies damage but doesn't kill creature off;
2483 for fire breath, dmg is going to be 0 (fire breathers are
2484 immune to fire damage) but for wand of fire or fire horn,
2485 'mon' could have taken damage so might die */
2486 if (mon
->mhp
<= 0) {
2488 /* mon killed self but hero gets credit and blame (except
2489 for pacifist conduct); xkilled()'s message would say
2490 "You killed/destroyed <mon>" so give our own message */
2492 pline("%s is %s by the fire!", Monnam(mon
),
2493 nonliving(mon
->data
) ? "destroyed" : "killed");
2494 xkilled(mon
, XKILL_NOMSG
| XKILL_NOCONDUCT
);
2496 monkilled(mon
, "fire", AD_FIRE
);
2498 /* non-fatal damage occurred */
2500 pline("%s is burned%s", Monnam(mon
), exclam(dmg
));
2504 if (res
&& mon
->mhp
> 0)
2505 pline("%s slime is burned away!", s_suffix(Monnam(mon
)));
2506 if (otyp
!= STRANGE_OBJECT
)
2509 /* use up monster's next move */
2510 mon
->movement
-= NORMAL_SPEED
;
2511 mon
->mlstmv
= monstermoves
;
2515 /* decide whether obj can be used to cure green slime */
2517 cures_sliming(mon
, obj
)
2521 /* scroll of fire, non-empty wand or horn of fire */
2522 if (obj
->otyp
== SCR_FIRE
)
2523 return (haseyes(mon
->data
) && mon
->mcansee
);
2524 /* hero doesn't need hands or even limbs to zap, so mon doesn't either */
2525 return ((obj
->otyp
== WAN_FIRE
2526 || (obj
->otyp
== FIRE_HORN
&& can_blow(mon
)))
2530 /* TRUE if monster appears to be green; for active TEXTCOLOR, we go by
2531 the display color, otherwise we just pick things that seem plausibly
2532 green (which doesn't necessarily match the TEXTCOLOR categorization) */
2537 struct permonst
*ptr
= mon
->data
;
2542 if (iflags
.use_color
)
2543 return (ptr
->mcolor
== CLR_GREEN
|| ptr
->mcolor
== CLR_BRIGHT_GREEN
);
2546 if (strstri(ptr
->mname
, "green"))
2548 switch (monsndx(ptr
)) {
2549 case PM_FOREST_CENTAUR
:
2550 case PM_GARTER_SNAKE
:
2561 if (is_elf(ptr
) && !is_prince(ptr
) && !is_lord(ptr
)
2562 && ptr
!= &mons
[PM_GREY_ELF
])