1 /* NetHack 3.6 mon.c $NHDT-Date: 1454528962 2016/02/03 19:49:22 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.210 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* If you're using precompiled headers, you don't want this either */
14 STATIC_VAR boolean vamp_rise_msg
;
16 STATIC_DCL
void FDECL(sanity_check_single_mon
, (struct monst
*, BOOLEAN_P
,
18 STATIC_DCL boolean
FDECL(restrap
, (struct monst
*));
19 STATIC_DCL
long FDECL(mm_aggression
, (struct monst
*, struct monst
*));
20 STATIC_DCL
long FDECL(mm_displacement
, (struct monst
*, struct monst
*));
21 STATIC_DCL
int NDECL(pick_animal
);
22 STATIC_DCL
void FDECL(kill_eggs
, (struct obj
*));
23 STATIC_DCL
int FDECL(pickvampshape
, (struct monst
*));
24 STATIC_DCL boolean
FDECL(isspecmon
, (struct monst
*));
25 STATIC_DCL boolean
FDECL(validspecmon
, (struct monst
*, int));
26 STATIC_DCL boolean
FDECL(validvamp
, (struct monst
*, int *, int));
27 STATIC_DCL
struct permonst
*FDECL(accept_newcham_form
, (int));
28 STATIC_DCL
struct obj
*FDECL(make_corpse
, (struct monst
*, unsigned));
29 STATIC_DCL
void FDECL(m_detach
, (struct monst
*, struct permonst
*));
30 STATIC_DCL
void FDECL(lifesaved_monster
, (struct monst
*));
32 #define LEVEL_SPECIFIC_NOCORPSE(mdat) \
33 (Is_rogue_level(&u.uz) \
34 || (level.flags.graveyard && is_undead(mdat) && rn2(3)))
37 /* part of the original warning code which was replaced in 3.3.1 */
38 const char *warnings
[] = {
39 "white", "pink", "red", "ruby", "purple", "black"
45 sanity_check_single_mon(mtmp
, chk_geno
, msg
)
50 if (DEADMONSTER(mtmp
))
52 if (mtmp
->data
< &mons
[LOW_PM
] || mtmp
->data
>= &mons
[NUMMONS
]) {
53 impossible("illegal mon data %s; mnum=%d (%s)",
54 fmt_ptr((genericptr_t
) mtmp
->data
), mtmp
->mnum
, msg
);
56 int mndx
= monsndx(mtmp
->data
);
58 if (mtmp
->mnum
!= mndx
) {
59 impossible("monster mnum=%d, monsndx=%d (%s)",
60 mtmp
->mnum
, mndx
, msg
);
63 if (chk_geno
&& (mvitals
[mndx
].mvflags
& G_GENOD
) != 0)
64 impossible("genocided %s in play (%s)", mons
[mndx
].mname
, msg
);
66 if (mtmp
->isshk
&& !has_eshk(mtmp
))
67 impossible("shk without eshk (%s)", msg
);
68 if (mtmp
->ispriest
&& !has_epri(mtmp
))
69 impossible("priest without epri (%s)", msg
);
70 if (mtmp
->isgd
&& !has_egd(mtmp
))
71 impossible("guard without egd (%s)", msg
);
72 if (mtmp
->isminion
&& !has_emin(mtmp
))
73 impossible("minion without emin (%s)", msg
);
74 /* guardian angel on astral level is tame but has emin rather than edog */
75 if (mtmp
->mtame
&& !has_edog(mtmp
) && !mtmp
->isminion
)
76 impossible("pet without edog (%s)", msg
);
83 struct monst
*mtmp
, *m
;
85 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
86 sanity_check_single_mon(mtmp
, TRUE
, "fmon");
87 x
= mtmp
->mx
, y
= mtmp
->my
;
88 if (!isok(x
, y
) || (x
== 0 && !mtmp
->isgd
))
89 impossible("mon (%s) claims to be at <%d,%d>?",
90 fmt_ptr((genericptr_t
) mtmp
), x
, y
);
91 else if (level
.monsters
[x
][y
] != mtmp
)
92 impossible("mon (%s) at <%d,%d> is not there!",
93 fmt_ptr((genericptr_t
) mtmp
), x
, y
);
96 for (x
= 0; x
< COLNO
; x
++)
97 for (y
= 0; y
< ROWNO
; y
++)
98 if ((mtmp
= level
.monsters
[x
][y
]) != 0) {
99 for (m
= fmon
; m
; m
= m
->nmon
)
103 impossible("map mon (%s) at <%d,%d> not in fmon list!",
104 fmt_ptr((genericptr_t
) mtmp
), x
, y
);
105 else if ((mtmp
->mx
!= x
|| mtmp
->my
!= y
)
106 && mtmp
->data
!= &mons
[PM_LONG_WORM
])
107 impossible("map mon (%s) at <%d,%d> is found at <%d,%d>?",
108 fmt_ptr((genericptr_t
) mtmp
),
109 mtmp
->mx
, mtmp
->my
, x
, y
);
112 for (mtmp
= migrating_mons
; mtmp
; mtmp
= mtmp
->nmon
) {
113 sanity_check_single_mon(mtmp
, FALSE
, "migr");
118 /* convert the monster index of an undead to its living counterpart */
120 undead_to_corpse(mndx
)
124 case PM_KOBOLD_ZOMBIE
:
125 case PM_KOBOLD_MUMMY
:
128 case PM_DWARF_ZOMBIE
:
132 case PM_GNOME_ZOMBIE
:
145 case PM_VAMPIRE_LORD
:
147 case PM_VAMPIRE_MAGE
:
149 case PM_HUMAN_ZOMBIE
:
153 case PM_GIANT_ZOMBIE
:
157 case PM_ETTIN_ZOMBIE
:
167 /* Convert the monster index of some monsters (such as quest guardians)
168 * to their generic species type.
170 * Return associated character class monster, rather than species
178 /* Quest guardians */
180 mndx
= mode
? PM_ARCHEOLOGIST
: PM_HUMAN
;
183 mndx
= mode
? PM_BARBARIAN
: PM_HUMAN
;
186 mndx
= mode
? PM_CAVEMAN
: PM_HUMAN
;
189 mndx
= mode
? PM_HEALER
: PM_HUMAN
;
192 mndx
= mode
? PM_KNIGHT
: PM_HUMAN
;
195 mndx
= mode
? PM_MONK
: PM_HUMAN
;
198 mndx
= mode
? PM_PRIEST
: PM_HUMAN
;
201 mndx
= mode
? PM_RANGER
: PM_HUMAN
;
204 mndx
= mode
? PM_ROGUE
: PM_HUMAN
;
207 mndx
= mode
? PM_SAMURAI
: PM_HUMAN
;
210 mndx
= mode
? PM_TOURIST
: PM_HUMAN
;
213 mndx
= mode
? PM_WIZARD
: PM_HUMAN
;
216 mndx
= mode
? PM_VALKYRIE
: PM_HUMAN
;
219 if (mndx
>= LOW_PM
&& mndx
< NUMMONS
) {
220 struct permonst
*ptr
= &mons
[mndx
];
224 else if (is_elf(ptr
))
226 else if (is_dwarf(ptr
))
228 else if (is_gnome(ptr
))
230 else if (is_orc(ptr
))
238 /* return monster index if chameleon, or NON_PM if not */
246 * As of 3.6.0 we just check M2_SHAPESHIFTER instead of having a
247 * big switch statement with hardcoded shapeshifter types here.
249 if (mndx
>= LOW_PM
&& is_shapeshifter(&mons
[mndx
]))
254 /* for deciding whether corpse will carry along full monster data */
255 #define KEEPTRAITS(mon) \
256 ((mon)->isshk || (mon)->mtame || unique_corpstat((mon)->data) \
257 || is_reviver((mon)->data) \
258 /* normally quest leader will be unique, */ \
259 /* but he or she might have been polymorphed */ \
260 || (mon)->m_id == quest_status.leader_m_id \
261 /* special cancellation handling for these */ \
262 || (dmgtype((mon)->data, AD_SEDU) || dmgtype((mon)->data, AD_SSEX)))
264 /* Creates a monster corpse, a "special" corpse, or nothing if it doesn't
265 * leave corpses. Monsters which leave "special" corpses should have
266 * G_NOCORPSE set in order to prevent wishing for one, finding tins of one,
269 STATIC_OVL
struct obj
*
270 make_corpse(mtmp
, corpseflags
)
271 register struct monst
*mtmp
;
272 unsigned corpseflags
;
274 register struct permonst
*mdat
= mtmp
->data
;
276 struct obj
*obj
= (struct obj
*) 0;
277 struct obj
*otmp
= (struct obj
*) 0;
278 int x
= mtmp
->mx
, y
= mtmp
->my
;
279 int mndx
= monsndx(mdat
);
280 unsigned corpstatflags
= corpseflags
;
281 boolean burythem
= ((corpstatflags
& CORPSTAT_BURIED
) != 0);
285 case PM_SILVER_DRAGON
:
287 case PM_SHIMMERING_DRAGON
:
290 case PM_ORANGE_DRAGON
:
291 case PM_WHITE_DRAGON
:
292 case PM_BLACK_DRAGON
:
294 case PM_GREEN_DRAGON
:
295 case PM_YELLOW_DRAGON
:
296 /* Make dragon scales. This assumes that the order of the
297 dragons is the same as the order of the scales. */
298 if (!rn2(mtmp
->mrevived
? 20 : 3)) {
299 num
= GRAY_DRAGON_SCALES
+ monsndx(mdat
) - PM_GRAY_DRAGON
;
300 obj
= mksobj_at(num
, x
, y
, FALSE
, FALSE
);
302 obj
->cursed
= obj
->blessed
= FALSE
;
305 case PM_WHITE_UNICORN
:
306 case PM_GRAY_UNICORN
:
307 case PM_BLACK_UNICORN
:
308 if (mtmp
->mrevived
&& rn2(2)) {
310 pline("%s recently regrown horn crumbles to dust.",
311 s_suffix(Monnam(mtmp
)));
313 obj
= mksobj_at(UNICORN_HORN
, x
, y
, TRUE
, FALSE
);
314 if (obj
&& mtmp
->mrevived
)
315 obj
->degraded_horn
= 1;
319 (void) mksobj_at(WORM_TOOTH
, x
, y
, TRUE
, FALSE
);
322 case PM_VAMPIRE_LORD
:
323 /* include mtmp in the mkcorpstat() call */
324 num
= undead_to_corpse(mndx
);
325 corpstatflags
|= CORPSTAT_INIT
;
326 obj
= mkcorpstat(CORPSE
, mtmp
, &mons
[num
], x
, y
, corpstatflags
);
327 obj
->age
-= 100; /* this is an *OLD* corpse */
329 case PM_KOBOLD_MUMMY
:
337 case PM_KOBOLD_ZOMBIE
:
338 case PM_DWARF_ZOMBIE
:
339 case PM_GNOME_ZOMBIE
:
342 case PM_HUMAN_ZOMBIE
:
343 case PM_GIANT_ZOMBIE
:
344 case PM_ETTIN_ZOMBIE
:
345 num
= undead_to_corpse(mndx
);
346 corpstatflags
|= CORPSTAT_INIT
;
347 obj
= mkcorpstat(CORPSE
, mtmp
, &mons
[num
], x
, y
, corpstatflags
);
348 obj
->age
-= 100; /* this is an *OLD* corpse */
353 obj
= mksobj_at(IRON_CHAIN
, x
, y
, TRUE
, FALSE
);
354 free_mname(mtmp
); /* don't christen obj */
357 num
= d(2, 4); /* very low chance of creating all glass gems */
359 obj
= mksobj_at((LAST_GEM
+ rnd(9)), x
, y
, TRUE
, FALSE
);
363 obj
= mksobj_at(ROCK
, x
, y
, FALSE
, FALSE
);
364 obj
->quan
= (long) (rn2(20) + 50);
365 obj
->owt
= weight(obj
);
369 corpstatflags
&= ~CORPSTAT_INIT
;
371 mkcorpstat(STATUE
, (struct monst
*) 0, mdat
, x
, y
, corpstatflags
);
376 obj
= mksobj_at(QUARTERSTAFF
, x
, y
, TRUE
, FALSE
);
380 case PM_LEATHER_GOLEM
:
383 obj
= mksobj_at(LEATHER_ARMOR
, x
, y
, TRUE
, FALSE
);
387 /* Good luck gives more coins */
388 obj
= mkgold((long) (200 - rnl(101)), x
, y
);
394 obj
= mksobj_at(SCR_BLANK_PAPER
, x
, y
, TRUE
, FALSE
);
397 /* expired puddings will congeal into a large blob;
398 like dragons, relies on the order remaining consistent */
400 case PM_BROWN_PUDDING
:
402 case PM_BLACK_PUDDING
:
403 /* we have to do this here because most other places
404 expect there to be an object coming back; not this one */
405 obj
= mksobj_at(GLOB_OF_BLACK_PUDDING
- (PM_BLACK_PUDDING
- mndx
),
408 while (obj
&& (otmp
= obj_nexto(obj
)) != (struct obj
*) 0) {
409 pudding_merge_message(obj
, otmp
);
410 obj
= obj_meld(&obj
, &otmp
);
417 if (mvitals
[mndx
].mvflags
& G_NOCORPSE
) {
418 return (struct obj
*) 0;
420 corpstatflags
|= CORPSTAT_INIT
;
421 /* preserve the unique traits of some creatures */
422 obj
= mkcorpstat(CORPSE
, KEEPTRAITS(mtmp
) ? mtmp
: 0,
423 mdat
, x
, y
, corpstatflags
);
427 (void) bury_an_obj(obj
, &dealloc
);
429 return dealloc
? (struct obj
*) 0 : obj
;
434 /* All special cases should precede the G_NOCORPSE check */
436 if (!obj
) return NULL
;
438 /* if polymorph or undead turning has killed this monster,
439 prevent the same attack beam from hitting its corpse */
440 if (context
.bypasses
)
444 obj
= oname(obj
, MNAME(mtmp
));
446 /* Avoid "It was hidden under a green mold corpse!"
447 * during Blind combat. An unseen monster referred to as "it"
448 * could be killed and leave a corpse. If a hider then hid
449 * underneath it, you could be told the corpse type of a
450 * monster that you never knew was there without this.
451 * The code in hitmu() substitutes the word "something"
452 * if the corpses obj->dknown is 0.
454 if (Blind
&& !sensemon(mtmp
))
462 /* check mtmp and water/lava for compatibility, 0 (survived), 1 (died) */
465 register struct monst
*mtmp
;
467 boolean inpool
, inlava
, infountain
;
469 /* [what about ceiling clingers?] */
470 inpool
= (is_pool(mtmp
->mx
, mtmp
->my
)
471 && !(is_flyer(mtmp
->data
) || is_floater(mtmp
->data
)));
472 inlava
= (is_lava(mtmp
->mx
, mtmp
->my
)
473 && !(is_flyer(mtmp
->data
) || is_floater(mtmp
->data
)));
474 infountain
= IS_FOUNTAIN(levl
[mtmp
->mx
][mtmp
->my
].typ
);
476 /* Flying and levitation keeps our steed out of the liquid */
477 /* (but not water-walking or swimming) */
478 if (mtmp
== u
.usteed
&& (Flying
|| Levitation
))
481 /* Gremlin multiplying won't go on forever since the hit points
482 * keep going down, and when it gets to 1 hit point the clone
483 * function will fail.
485 if (mtmp
->data
== &mons
[PM_GREMLIN
] && (inpool
|| infountain
) && rn2(3)) {
486 if (split_mon(mtmp
, (struct monst
*) 0))
487 dryup(mtmp
->mx
, mtmp
->my
, FALSE
);
489 water_damage_chain(mtmp
->minvent
, FALSE
);
491 } else if (mtmp
->data
== &mons
[PM_IRON_GOLEM
] && inpool
&& !rn2(5)) {
494 if (cansee(mtmp
->mx
, mtmp
->my
))
495 pline("%s rusts.", Monnam(mtmp
));
497 if (mtmp
->mhpmax
> dam
)
504 water_damage_chain(mtmp
->minvent
, FALSE
);
510 * Lava effects much as water effects. Lava likers are able to
511 * protect their stuff. Fire resistant monsters can only protect
514 if (!is_clinger(mtmp
->data
) && !likes_lava(mtmp
->data
)) {
515 if (!resists_fire(mtmp
)) {
516 if (cansee(mtmp
->mx
, mtmp
->my
))
517 pline("%s %s.", Monnam(mtmp
),
518 mtmp
->data
== &mons
[PM_WATER_ELEMENTAL
]
520 : "burns to a crisp");
523 if (--mtmp
->mhp
< 1) {
524 if (cansee(mtmp
->mx
, mtmp
->my
))
525 pline("%s surrenders to the fire.", Monnam(mtmp
));
527 } else if (cansee(mtmp
->mx
, mtmp
->my
))
528 pline("%s burns slightly.", Monnam(mtmp
));
531 (void) fire_damage_chain(mtmp
->minvent
, FALSE
, FALSE
,
533 (void) rloc(mtmp
, FALSE
);
539 /* Most monsters drown in pools. flooreffects() will take care of
540 * water damage to dead monsters' inventory, but survivors need to
541 * be handled here. Swimmers are able to protect their stuff...
543 if (!is_clinger(mtmp
->data
) && !is_swimmer(mtmp
->data
)
544 && !amphibious(mtmp
->data
)) {
545 if (cansee(mtmp
->mx
, mtmp
->my
)) {
546 pline("%s drowns.", Monnam(mtmp
));
548 if (u
.ustuck
&& u
.uswallow
&& u
.ustuck
== mtmp
) {
549 /* This can happen after a purple worm plucks you off a
550 flying steed while you are over water. */
551 pline("%s sinks as water rushes in and flushes you out.",
556 water_damage_chain(mtmp
->minvent
, FALSE
);
557 (void) rloc(mtmp
, FALSE
);
563 /* but eels have a difficult time outside */
564 if (mtmp
->data
->mlet
== S_EEL
&& !Is_waterlevel(&u
.uz
)) {
565 /* as mhp gets lower, the rate of further loss slows down */
566 if (mtmp
->mhp
> 1 && rn2(mtmp
->mhp
) > rn2(8))
568 monflee(mtmp
, 2, FALSE
, FALSE
);
578 int mmove
= mon
->data
->mmove
;
580 /* Note: MSLOW's `+ 1' prevents slowed speed 1 getting reduced to 0;
581 * MFAST's `+ 2' prevents hasted speed 1 from becoming a no-op;
582 * both adjustments have negligible effect on higher speeds.
584 if (mon
->mspeed
== MSLOW
)
585 mmove
= (2 * mmove
+ 1) / 3;
586 else if (mon
->mspeed
== MFAST
)
587 mmove
= (4 * mmove
+ 2) / 3;
589 if (mon
== u
.usteed
) {
590 if (u
.ugallop
&& context
.mv
) {
591 /* average movement is 1.50 times normal */
592 mmove
= ((rn2(2) ? 4 : 5) * mmove
) / 3;
595 /* vary movement points allocated to slightly reduce predictability;
596 random increment (avg +2) exceeds random decrement (avg +1) by
597 a small amount; normal speed monsters will occasionally get an
598 extra move and slow ones won't be quite as slow */
599 mmove
+= rn2(5) - rn2(3); /* + 0..4 - 0..2, average net +1 */
607 /* actions that happen once per ``turn'', regardless of each
608 individual monster's metabolism; some of these might need to
609 be reclassified to occur more in proportion with movement rate */
615 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
616 if (DEADMONSTER(mtmp
))
619 /* must check non-moving monsters once/turn in case
620 * they managed to end up in liquid */
621 if (mtmp
->data
->mmove
== 0) {
622 if (vision_full_recalc
)
628 /* regenerate hit points */
629 mon_regen(mtmp
, FALSE
);
631 /* possibly polymorph shapechangers and lycanthropes */
632 if (mtmp
->cham
>= LOW_PM
)
633 decide_to_shapeshift(mtmp
, (canspotmon(mtmp
)
634 || (u
.uswallow
&& mtmp
== u
.ustuck
))
638 /* gradually time out temporary problems */
639 if (mtmp
->mblinded
&& !--mtmp
->mblinded
)
641 if (mtmp
->mfrozen
&& !--mtmp
->mfrozen
)
643 if (mtmp
->mfleetim
&& !--mtmp
->mfleetim
)
646 /* FIXME: mtmp->mlstmv ought to be updated here */
653 register struct monst
*mtmp
, *nmtmp
;
654 register boolean somebody_can_move
= FALSE
;
657 * Some of you may remember the former assertion here that
658 * because of deaths and other actions, a simple one-pass
659 * algorithm wasn't possible for movemon. Deaths are no longer
660 * removed to the separate list fdmon; they are simply left in
661 * the chain with hit points <= 0, to be cleaned up at the end
664 * The only other actions which cause monsters to be removed from
665 * the chain are level migrations and losedogs(). I believe losedogs()
666 * is a cleanup routine not associated with monster movements, and
667 * monsters can only affect level migrations on themselves, not others
668 * (hence the fetching of nmon before moving the monster). Currently,
669 * monsters can jump into traps, read cursed scrolls of teleportation,
670 * and drink cursed potions of raise level to change levels. These are
671 * all reflexive at this point. Should one monster be able to level
672 * teleport another, this scheme would have problems.
675 for (mtmp
= fmon
; mtmp
; mtmp
= nmtmp
) {
676 /* end monster movement early if hero is flagged to leave the level */
679 /* or if the program has lost contact with the user */
680 || program_state
.done_hup
683 somebody_can_move
= FALSE
;
687 /* one dead monster needs to perform a move after death:
688 vault guard whose temporary corridor is still on the map */
689 if (mtmp
->isgd
&& !mtmp
->mx
&& mtmp
->mhp
<= 0)
690 (void) gd_move(mtmp
);
691 if (DEADMONSTER(mtmp
))
694 /* Find a monster that we have not treated yet. */
695 if (mtmp
->movement
< NORMAL_SPEED
)
698 mtmp
->movement
-= NORMAL_SPEED
;
699 if (mtmp
->movement
>= NORMAL_SPEED
)
700 somebody_can_move
= TRUE
;
702 if (vision_full_recalc
)
703 vision_recalc(0); /* vision! */
705 /* reset obj bypasses before next monster moves */
706 if (context
.bypasses
)
712 if (is_hider(mtmp
->data
)) {
713 /* unwatched mimics and piercers may hide again [MRS] */
716 if (mtmp
->m_ap_type
== M_AP_FURNITURE
717 || mtmp
->m_ap_type
== M_AP_OBJECT
)
719 if (mtmp
->mundetected
)
721 } else if (mtmp
->data
->mlet
== S_EEL
&& !mtmp
->mundetected
722 && (mtmp
->mflee
|| distu(mtmp
->mx
, mtmp
->my
) > 2)
723 && !canseemon(mtmp
) && !rn2(4)) {
724 /* some eels end up stuck in isolated pools, where they
725 can't--or at least won't--move, so they never reach
726 their post-move chance to re-hide */
731 /* continue if the monster died fighting */
732 if (Conflict
&& !mtmp
->iswiz
&& mtmp
->mcansee
) {
734 * Conflict does not take effect in the first round.
735 * Therefore, A monster when stepping into the area will
736 * get to swing at you.
738 * The call to fightm() must be _last_. The monster might
739 * have died if it returns 1.
741 if (couldsee(mtmp
->mx
, mtmp
->my
)
742 && (distu(mtmp
->mx
, mtmp
->my
) <= BOLT_LIM
* BOLT_LIM
)
744 continue; /* mon might have died */
746 if (dochugw(mtmp
)) /* otherwise just move the monster */
750 if (any_light_source())
751 vision_full_recalc
= 1; /* in case a mon moved with a light source */
752 /* reset obj bypasses after last monster has moved */
753 if (context
.bypasses
)
756 /* remove dead monsters; dead vault guard will be left at <0,0>
757 if temporary corridor out of vault hasn't been removed yet */
760 /* a monster may have levteleported player -dlc */
763 /* changed levels, so these monsters are dormant */
764 somebody_can_move
= FALSE
;
767 return somebody_can_move
;
770 #define mstoning(obj) \
771 (ofood(obj) && (touch_petrifies(&mons[(obj)->corpsenm]) \
772 || (obj)->corpsenm == PM_MEDUSA))
775 * Maybe eat a metallic object (not just gold).
776 * Return value: 0 => nothing happened, 1 => monster ate something,
777 * 2 => monster died (it must have grown into a genocided form, but
778 * that can't happen at present because nothing which eats objects
779 * has young and old forms).
783 register struct monst
*mtmp
;
785 register struct obj
*otmp
;
786 struct permonst
*ptr
;
787 int poly
, grow
, heal
, mstone
;
789 /* If a pet, eating is handled separately, in dog.c */
793 /* Eats topmost metal object if it is there */
794 for (otmp
= level
.objects
[mtmp
->mx
][mtmp
->my
]; otmp
;
795 otmp
= otmp
->nexthere
) {
796 /* Don't eat indigestible/choking/inappropriate objects */
797 if ((mtmp
->data
== &mons
[PM_RUST_MONSTER
] && !is_rustprone(otmp
))
798 || (otmp
->otyp
== AMULET_OF_STRANGULATION
)
799 || (otmp
->otyp
== RIN_SLOW_DIGESTION
))
801 if (is_metallic(otmp
) && !obj_resists(otmp
, 5, 95)
802 && touch_artifact(otmp
, mtmp
)) {
803 if (mtmp
->data
== &mons
[PM_RUST_MONSTER
] && otmp
->oerodeproof
) {
804 if (canseemon(mtmp
) && flags
.verbose
) {
805 pline("%s eats %s!", Monnam(mtmp
),
806 distant_name(otmp
, doname
));
808 /* The object's rustproofing is gone now */
809 otmp
->oerodeproof
= 0;
811 if (canseemon(mtmp
) && flags
.verbose
) {
812 pline("%s spits %s out in disgust!", Monnam(mtmp
),
813 distant_name(otmp
, doname
));
816 if (cansee(mtmp
->mx
, mtmp
->my
) && flags
.verbose
)
817 pline("%s eats %s!", Monnam(mtmp
),
818 distant_name(otmp
, doname
));
819 else if (flags
.verbose
)
820 You_hear("a crunching sound.");
821 mtmp
->meating
= otmp
->owt
/ 2 + 1;
822 /* Heal up to the object's weight in hp */
823 if (mtmp
->mhp
< mtmp
->mhpmax
) {
824 mtmp
->mhp
+= objects
[otmp
->otyp
].oc_weight
;
825 if (mtmp
->mhp
> mtmp
->mhpmax
)
826 mtmp
->mhp
= mtmp
->mhpmax
;
831 } else if (otmp
== uchain
) {
832 unpunish(); /* frees uchain */
834 poly
= polyfodder(otmp
);
835 grow
= mlevelgain(otmp
);
836 heal
= mhealup(otmp
);
837 mstone
= mstoning(otmp
);
841 if (newcham(mtmp
, (struct permonst
*) 0, FALSE
, FALSE
))
844 ptr
= grow_up(mtmp
, (struct monst
*) 0);
846 if (poly_when_stoned(ptr
)) {
849 } else if (!resists_ston(mtmp
)) {
851 pline("%s turns to stone!", Monnam(mtmp
));
853 ptr
= (struct permonst
*) 0;
856 mtmp
->mhp
= mtmp
->mhpmax
;
859 return 2; /* it died */
861 /* Left behind a pile? */
863 (void) mksobj_at(ROCK
, mtmp
->mx
, mtmp
->my
, TRUE
, FALSE
);
864 newsym(mtmp
->mx
, mtmp
->my
);
872 /* monster eats a pile of objects */
874 meatobj(mtmp
) /* for gelatinous cubes */
877 register struct obj
*otmp
, *otmp2
;
878 struct permonst
*ptr
, *original_ptr
= mtmp
->data
;
879 int poly
, grow
, heal
, count
= 0, ecount
= 0;
883 /* If a pet, eating is handled separately, in dog.c */
887 /* eat organic objects, including cloth and wood, if present;
888 engulf others, except huge rocks and metal attached to player
889 [despite comment at top, doesn't assume that eater is a g.cube] */
890 for (otmp
= level
.objects
[mtmp
->mx
][mtmp
->my
]; otmp
; otmp
= otmp2
) {
891 otmp2
= otmp
->nexthere
;
893 /* touch sensitive items */
894 if (otmp
->otyp
== CORPSE
&& is_rider(&mons
[otmp
->corpsenm
])) {
895 /* Rider corpse isn't just inedible; can't engulf it either */
896 (void) revive_corpse(otmp
);
898 /* untouchable (or inaccessible) items */
899 } else if ((otmp
->otyp
== CORPSE
900 && touch_petrifies(&mons
[otmp
->corpsenm
])
901 && !resists_ston(mtmp
))
902 /* don't engulf boulders and statues or ball&chain */
903 || otmp
->oclass
== ROCK_CLASS
904 || otmp
== uball
|| otmp
== uchain
) {
905 /* do nothing--neither eaten nor engulfed */
908 /* inedible items -- engulf these */
909 } else if (!is_organic(otmp
) || obj_resists(otmp
, 5, 95)
910 || !touch_artifact(otmp
, mtmp
)
911 /* redundant due to non-organic composition but
912 included for emphasis */
913 || (otmp
->otyp
== AMULET_OF_STRANGULATION
914 || otmp
->otyp
== RIN_SLOW_DIGESTION
)
915 /* cockatrice corpses handled above; this
916 touch_petrifies() check catches eggs */
917 || ((otmp
->otyp
== CORPSE
|| otmp
->otyp
== EGG
)
918 && ((touch_petrifies(&mons
[otmp
->corpsenm
])
919 && !resists_ston(mtmp
))
920 || (otmp
->corpsenm
== PM_GREEN_SLIME
921 && !slimeproof(mtmp
->data
))))) {
925 Sprintf(buf
, "%s engulfs %s.", Monnam(mtmp
),
926 distant_name(otmp
, doname
));
927 else if (ecount
== 2)
928 Sprintf(buf
, "%s engulfs several objects.", Monnam(mtmp
));
929 obj_extract_self(otmp
);
930 (void) mpickobj(mtmp
, otmp
); /* slurp */
932 /* lastly, edible items; yum! */
936 if (cansee(mtmp
->mx
, mtmp
->my
) && flags
.verbose
)
937 pline("%s eats %s!", Monnam(mtmp
),
938 distant_name(otmp
, doname
));
939 else if (flags
.verbose
)
940 You_hear("a slurping sound.");
941 /* Heal up to the object's weight in hp */
942 if (mtmp
->mhp
< mtmp
->mhpmax
) {
943 mtmp
->mhp
+= objects
[otmp
->otyp
].oc_weight
;
944 if (mtmp
->mhp
> mtmp
->mhpmax
)
945 mtmp
->mhp
= mtmp
->mhpmax
;
947 if (Has_contents(otmp
)) {
948 register struct obj
*otmp3
;
950 /* contents of eaten containers become engulfed; this
951 is arbitrary, but otherwise g.cubes are too powerful */
952 while ((otmp3
= otmp
->cobj
) != 0) {
953 obj_extract_self(otmp3
);
954 if (otmp
->otyp
== ICE_BOX
&& otmp3
->otyp
== CORPSE
) {
955 otmp3
->age
= monstermoves
- otmp3
->age
;
956 start_corpse_timeout(otmp3
);
958 (void) mpickobj(mtmp
, otmp3
);
961 poly
= polyfodder(otmp
);
962 grow
= mlevelgain(otmp
);
963 heal
= mhealup(otmp
);
964 delobj(otmp
); /* munch */
967 if (newcham(mtmp
, (struct permonst
*) 0, FALSE
, FALSE
))
970 ptr
= grow_up(mtmp
, (struct monst
*) 0);
972 mtmp
->mhp
= mtmp
->mhpmax
;
974 /* in case it polymorphed or died */
975 if (ptr
!= original_ptr
)
979 /* Engulf & devour is instant, so don't set meating */
981 newsym(mtmp
->mx
, mtmp
->my
);
985 if (cansee(mtmp
->mx
, mtmp
->my
) && flags
.verbose
&& buf
[0])
987 else if (flags
.verbose
)
988 You_hear("%s slurping sound%s.",
989 (ecount
== 1) ? "a" : "several", plur(ecount
));
991 return (count
> 0 || ecount
> 0) ? 1 : 0;
996 register struct monst
*mtmp
;
998 register struct obj
*gold
;
1001 if ((gold
= g_at(mtmp
->mx
, mtmp
->my
)) != 0) {
1002 mat_idx
= objects
[gold
->otyp
].oc_material
;
1003 obj_extract_self(gold
);
1004 add_to_minv(mtmp
, gold
);
1005 if (cansee(mtmp
->mx
, mtmp
->my
)) {
1006 if (flags
.verbose
&& !mtmp
->isgd
)
1007 pline("%s picks up some %s.", Monnam(mtmp
),
1008 mat_idx
== GOLD
? "gold" : "money");
1009 newsym(mtmp
->mx
, mtmp
->my
);
1015 mpickstuff(mtmp
, str
)
1016 register struct monst
*mtmp
;
1017 register const char *str
;
1019 register struct obj
*otmp
, *otmp2
, *otmp3
;
1022 /* prevent shopkeepers from leaving the door of their shop */
1023 if (mtmp
->isshk
&& inhishop(mtmp
))
1026 for (otmp
= level
.objects
[mtmp
->mx
][mtmp
->my
]; otmp
; otmp
= otmp2
) {
1027 otmp2
= otmp
->nexthere
;
1028 /* Nymphs take everything. Most monsters don't pick up corpses. */
1029 if (!str
? searches_for_item(mtmp
, otmp
)
1030 : !!(index(str
, otmp
->oclass
))) {
1031 if (otmp
->otyp
== CORPSE
&& mtmp
->data
->mlet
!= S_NYMPH
1032 /* let a handful of corpse types thru to can_carry() */
1033 && !touch_petrifies(&mons
[otmp
->corpsenm
])
1034 && otmp
->corpsenm
!= PM_LIZARD
1035 && !acidic(&mons
[otmp
->corpsenm
]))
1037 if (!touch_artifact(otmp
, mtmp
))
1039 carryamt
= can_carry(mtmp
, otmp
);
1042 if (is_pool(mtmp
->mx
, mtmp
->my
))
1044 /* handle cases where the critter can only get some */
1046 if (carryamt
!= otmp
->quan
) {
1047 otmp3
= splitobj(otmp
, carryamt
);
1049 if (cansee(mtmp
->mx
, mtmp
->my
) && flags
.verbose
)
1050 pline("%s picks up %s.", Monnam(mtmp
),
1051 (distu(mtmp
->mx
, mtmp
->my
) <= 5)
1053 : distant_name(otmp3
, doname
));
1054 obj_extract_self(otmp3
); /* remove from floor */
1055 (void) mpickobj(mtmp
, otmp3
); /* may merge and free otmp3 */
1056 m_dowear(mtmp
, FALSE
);
1057 newsym(mtmp
->mx
, mtmp
->my
);
1058 return TRUE
; /* pick only one object */
1071 for (obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
) {
1072 if (obj
->otyp
!= BOULDER
|| !throws_rocks(mtmp
->data
))
1073 curload
+= obj
->owt
;
1085 /* Base monster carrying capacity is equal to human maximum
1086 * carrying capacity, or half human maximum if not strong.
1087 * (for a polymorphed player, the value used would be the
1088 * non-polymorphed carrying capacity instead of max/half max).
1089 * This is then modified by the ratio between the monster weights
1090 * and human weights. Corpseless monsters are given a capacity
1091 * proportional to their size instead of weight.
1093 if (!mtmp
->data
->cwt
)
1094 maxload
= (MAX_CARR_CAP
* (long) mtmp
->data
->msize
) / MZ_HUMAN
;
1095 else if (!strongmonst(mtmp
->data
)
1096 || (strongmonst(mtmp
->data
) && (mtmp
->data
->cwt
> WT_HUMAN
)))
1097 maxload
= (MAX_CARR_CAP
* (long) mtmp
->data
->cwt
) / WT_HUMAN
;
1099 maxload
= MAX_CARR_CAP
; /*strong monsters w/cwt <= WT_HUMAN*/
1101 if (!strongmonst(mtmp
->data
))
1107 return (int) maxload
;
1110 /* for restricting monsters' object-pickup.
1112 * to support the new pet behavior, this now returns the max # of objects
1113 * that a given monster could pick up from a pile. frequently this will be
1114 * otmp->quan, but special cases for 'only one' now exist so.
1116 * this will probably cause very amusing behavior with pets and gold coins.
1118 * TODO: allow picking up 2-N objects from a pile of N based on weight.
1119 * Change from 'int' to 'long' to accomate big stacks of gold.
1120 * Right now we fake it by reporting a partial quantity, but the
1121 * likesgold handling m_move results in picking up the whole stack.
1124 can_carry(mtmp
, otmp
)
1128 int iquan
, otyp
= otmp
->otyp
, newload
= otmp
->owt
;
1129 struct permonst
*mdat
= mtmp
->data
;
1133 return 0; /* can't carry anything */
1135 if (otyp
== CORPSE
&& touch_petrifies(&mons
[otmp
->corpsenm
])
1136 && !(mtmp
->misc_worn_check
& W_ARMG
) && !resists_ston(mtmp
))
1138 if (otyp
== CORPSE
&& is_rider(&mons
[otmp
->corpsenm
]))
1140 if (objects
[otyp
].oc_material
== SILVER
&& mon_hates_silver(mtmp
)
1141 && (otyp
!= BELL_OF_OPENING
|| !is_covetous(mdat
)))
1144 /* hostile monsters who like gold will pick up the whole stack;
1145 tame mosnters with hands will pick up the partial stack */
1146 iquan
= (otmp
->quan
> (long) LARGEST_INT
)
1147 ? 20000 + rn2(LARGEST_INT
- 20000 + 1)
1150 /* monsters without hands can't pick up multiple objects at once
1151 * unless they have an engulfing attack
1153 * ...dragons, of course, can always carry gold pieces and gems somehow
1156 boolean glomper
= FALSE
;
1158 if (mtmp
->data
->mlet
== S_DRAGON
1159 && (otmp
->oclass
== COIN_CLASS
1160 || otmp
->oclass
== GEM_CLASS
))
1163 for (nattk
= 0; nattk
< NATTK
; nattk
++)
1164 if (mtmp
->data
->mattk
[nattk
].aatyp
== AT_ENGL
) {
1168 if ((mtmp
->data
->mflags1
& M1_NOHANDS
) && !glomper
)
1172 /* steeds don't pick up stuff (to avoid shop abuse) */
1173 if (mtmp
== u
.usteed
)
1176 return iquan
; /* no limit */
1177 if (mtmp
->mpeaceful
&& !mtmp
->mtame
)
1179 /* otherwise players might find themselves obligated to violate
1180 * their alignment if the monster takes something they need
1183 /* special--boulder throwers carry unlimited amounts of boulders */
1184 if (throws_rocks(mdat
) && otyp
== BOULDER
)
1187 /* nymphs deal in stolen merchandise, but not boulders or statues */
1188 if (mdat
->mlet
== S_NYMPH
)
1189 return (otmp
->oclass
== ROCK_CLASS
) ? 0 : iquan
;
1191 if (curr_mon_load(mtmp
) + newload
> max_mon_load(mtmp
))
1197 /* return number of acceptable neighbour positions */
1199 mfndpos(mon
, poss
, info
, flag
)
1201 coord
*poss
; /* coord poss[9] */
1202 long *info
; /* long info[9] */
1205 struct permonst
*mdat
= mon
->data
;
1206 register struct trap
*ttmp
;
1211 boolean wantpool
, poolok
, lavaok
, nodiag
;
1212 boolean rockok
= FALSE
, treeok
= FALSE
, thrudoor
;
1214 boolean poisongas_ok
, in_poisongas
;
1216 int gas_glyph
= cmap_to_glyph(S_poisoncloud
);
1220 nowtyp
= levl
[x
][y
].typ
;
1222 nodiag
= NODIAG(mdat
- mons
);
1223 wantpool
= mdat
->mlet
== S_EEL
;
1224 poolok
= (is_flyer(mdat
) || is_clinger(mdat
)
1225 || (is_swimmer(mdat
) && !wantpool
));
1226 lavaok
= (is_flyer(mdat
) || is_clinger(mdat
) || likes_lava(mdat
));
1227 thrudoor
= ((flag
& (ALLOW_WALL
| BUSTDOOR
)) != 0L);
1228 poisongas_ok
= ((nonliving(mdat
) || is_vampshifter(mon
)
1229 || breathless(mdat
)) || resists_poison(mon
));
1230 in_poisongas
= ((gas_reg
= visible_region_at(x
,y
)) != 0
1231 && gas_reg
->glyph
== gas_glyph
);
1233 if (flag
& ALLOW_DIG
) {
1236 /* need to be specific about what can currently be dug */
1237 if (!needspick(mdat
)) {
1238 rockok
= treeok
= TRUE
;
1239 } else if ((mw_tmp
= MON_WEP(mon
)) && mw_tmp
->cursed
1240 && mon
->weapon_check
== NO_WEAPON_WANTED
) {
1241 rockok
= is_pick(mw_tmp
);
1242 treeok
= is_axe(mw_tmp
);
1244 rockok
= (m_carrying(mon
, PICK_AXE
)
1245 || (m_carrying(mon
, DWARVISH_MATTOCK
)
1246 && !which_armor(mon
, W_ARMS
)));
1247 treeok
= (m_carrying(mon
, AXE
) || (m_carrying(mon
, BATTLE_AXE
)
1248 && !which_armor(mon
, W_ARMS
)));
1250 if (rockok
|| treeok
)
1254 nexttry
: /* eels prefer the water, but if there is no water nearby,
1255 they will crawl over land */
1262 maxx
= min(x
+ 1, COLNO
- 1);
1263 maxy
= min(y
+ 1, ROWNO
- 1);
1264 for (nx
= max(1, x
- 1); nx
<= maxx
; nx
++)
1265 for (ny
= max(0, y
- 1); ny
<= maxy
; ny
++) {
1266 if (nx
== x
&& ny
== y
)
1268 ntyp
= levl
[nx
][ny
].typ
;
1270 && !((flag
& ALLOW_WALL
) && may_passwall(nx
, ny
))
1271 && !((IS_TREE(ntyp
) ? treeok
: rockok
) && may_dig(nx
, ny
)))
1273 /* KMH -- Added iron bars */
1274 if (ntyp
== IRONBARS
&& !(flag
& ALLOW_BARS
))
1276 if (IS_DOOR(ntyp
) && !(amorphous(mdat
) || can_fog(mon
))
1277 && (((levl
[nx
][ny
].doormask
& D_CLOSED
) && !(flag
& OPENDOOR
))
1278 || ((levl
[nx
][ny
].doormask
& D_LOCKED
)
1279 && !(flag
& UNLOCKDOOR
))) && !thrudoor
)
1281 /* avoid poison gas? */
1282 if (!poisongas_ok
&& !in_poisongas
1283 && (gas_reg
= visible_region_at(nx
,ny
)) != 0
1284 && gas_reg
->glyph
== gas_glyph
)
1286 /* first diagonal checks (tight squeezes handled below) */
1287 if (nx
!= x
&& ny
!= y
1289 || (IS_DOOR(nowtyp
) && (levl
[x
][y
].doormask
& ~D_BROKEN
))
1290 || (IS_DOOR(ntyp
) && (levl
[nx
][ny
].doormask
& ~D_BROKEN
))
1291 || ((IS_DOOR(nowtyp
) || IS_DOOR(ntyp
))
1292 && Is_rogue_level(&u
.uz
))
1293 /* mustn't pass between adjacent long worm segments,
1294 but can attack that way */
1295 || (m_at(x
, ny
) && m_at(nx
, y
) && worm_cross(x
, y
, nx
, ny
)
1296 && !m_at(nx
, ny
) && (nx
!= u
.ux
|| ny
!= u
.uy
))))
1298 if ((is_pool(nx
, ny
) == wantpool
|| poolok
)
1299 && (lavaok
|| !is_lava(nx
, ny
))) {
1301 boolean monseeu
= (mon
->mcansee
1302 && (!Invis
|| perceives(mdat
)));
1303 boolean checkobj
= OBJ_AT(nx
, ny
);
1305 /* Displacement also displaces the Elbereth/scare monster,
1306 * as long as you are visible.
1308 if (Displaced
&& monseeu
&& mon
->mux
== nx
&& mon
->muy
== ny
) {
1317 if (onscary(dispx
, dispy
, mon
)) {
1318 if (!(flag
& ALLOW_SSM
))
1320 info
[cnt
] |= ALLOW_SSM
;
1322 if ((nx
== u
.ux
&& ny
== u
.uy
)
1323 || (nx
== mon
->mux
&& ny
== mon
->muy
)) {
1324 if (nx
== u
.ux
&& ny
== u
.uy
) {
1325 /* If it's right next to you, it found you,
1326 * displaced or no. We must set mux and muy
1327 * right now, so when we return we can tell
1328 * that the ALLOW_U means to attack _you_ and
1334 if (!(flag
& ALLOW_U
))
1336 info
[cnt
] |= ALLOW_U
;
1338 if (MON_AT(nx
, ny
)) {
1339 struct monst
*mtmp2
= m_at(nx
, ny
);
1340 long mmflag
= flag
| mm_aggression(mon
, mtmp2
);
1342 if (mmflag
& ALLOW_M
) {
1343 info
[cnt
] |= ALLOW_M
;
1345 if (!(mmflag
& ALLOW_TM
))
1347 info
[cnt
] |= ALLOW_TM
;
1350 mmflag
= flag
| mm_displacement(mon
, mtmp2
);
1351 if (!(mmflag
& ALLOW_MDISP
))
1353 info
[cnt
] |= ALLOW_MDISP
;
1356 /* Note: ALLOW_SANCT only prevents movement, not
1357 attack, into a temple. */
1358 if (level
.flags
.has_temple
&& *in_rooms(nx
, ny
, TEMPLE
)
1359 && !*in_rooms(x
, y
, TEMPLE
)
1360 && in_your_sanctuary((struct monst
*) 0, nx
, ny
)) {
1361 if (!(flag
& ALLOW_SANCT
))
1363 info
[cnt
] |= ALLOW_SANCT
;
1366 if (checkobj
&& sobj_at(CLOVE_OF_GARLIC
, nx
, ny
)) {
1367 if (flag
& NOGARLIC
)
1369 info
[cnt
] |= NOGARLIC
;
1371 if (checkobj
&& sobj_at(BOULDER
, nx
, ny
)) {
1372 if (!(flag
& ALLOW_ROCK
))
1374 info
[cnt
] |= ALLOW_ROCK
;
1376 if (monseeu
&& onlineu(nx
, ny
)) {
1379 info
[cnt
] |= NOTONL
;
1381 /* check for diagonal tight squeeze */
1382 if (nx
!= x
&& ny
!= y
&& bad_rock(mdat
, x
, ny
)
1383 && bad_rock(mdat
, nx
, y
) && cant_squeeze_thru(mon
))
1385 /* The monster avoids a particular type of trap if it's
1386 * familiar with the trap type. Pets get ALLOW_TRAPS
1387 * and checking is done in dogmove.c. In either case,
1388 * "harmless" traps are neither avoided nor marked in info[].
1390 if ((ttmp
= t_at(nx
, ny
)) != 0) {
1391 if (ttmp
->ttyp
>= TRAPNUM
|| ttmp
->ttyp
== 0) {
1393 "A monster looked at a very strange trap of type %d.",
1397 if ((ttmp
->ttyp
!= RUST_TRAP
1398 || mdat
== &mons
[PM_IRON_GOLEM
])
1399 && ttmp
->ttyp
!= STATUE_TRAP
1400 && ((ttmp
->ttyp
!= PIT
&& ttmp
->ttyp
!= SPIKED_PIT
1401 && ttmp
->ttyp
!= TRAPDOOR
&& ttmp
->ttyp
!= HOLE
)
1402 || (!is_flyer(mdat
) && !is_floater(mdat
)
1403 && !is_clinger(mdat
)) || Sokoban
)
1404 && (ttmp
->ttyp
!= SLP_GAS_TRAP
|| !resists_sleep(mon
))
1405 && (ttmp
->ttyp
!= BEAR_TRAP
1406 || (mdat
->msize
> MZ_SMALL
&& !amorphous(mdat
)
1407 && !is_flyer(mdat
) && !is_floater(mdat
)
1408 && !is_whirly(mdat
) && !unsolid(mdat
)))
1409 && (ttmp
->ttyp
!= FIRE_TRAP
|| !resists_fire(mon
))
1410 && (ttmp
->ttyp
!= SQKY_BOARD
|| !is_flyer(mdat
))
1411 && (ttmp
->ttyp
!= WEB
1412 || (!amorphous(mdat
) && !webmaker(mdat
)
1413 && !is_whirly(mdat
) && !unsolid(mdat
)))
1414 && (ttmp
->ttyp
!= ANTI_MAGIC
|| !resists_magm(mon
))) {
1415 if (!(flag
& ALLOW_TRAPS
)) {
1416 if (mon
->mtrapseen
& (1L << (ttmp
->ttyp
- 1)))
1419 info
[cnt
] |= ALLOW_TRAPS
;
1427 if (!cnt
&& wantpool
&& !is_pool(x
, y
)) {
1434 /* Monster against monster special attacks; for the specified monster
1435 combinations, this allows one monster to attack another adjacent one
1436 in the absence of Conflict. There is no provision for targetting
1437 other monsters; just hand to hand fighting when they happen to be
1438 next to each other. */
1440 mm_aggression(magr
, mdef
)
1441 struct monst
*magr
, /* monster that is currently deciding where to move */
1442 *mdef
; /* another monster which is next to it */
1444 /* supposedly purple worms are attracted to shrieking because they
1445 like to eat shriekers, so attack the latter when feasible */
1446 if (magr
->data
== &mons
[PM_PURPLE_WORM
]
1447 && mdef
->data
== &mons
[PM_SHRIEKER
])
1448 return ALLOW_M
| ALLOW_TM
;
1449 /* Various other combinations such as dog vs cat, cat vs rat, and
1450 elf vs orc have been suggested. For the time being we don't
1455 /* Monster displacing another monster out of the way */
1457 mm_displacement(magr
, mdef
)
1458 struct monst
*magr
, /* monster that is currently deciding where to move */
1459 *mdef
; /* another monster which is next to it */
1461 struct permonst
*pa
= magr
->data
, *pd
= mdef
->data
;
1463 /* if attacker can't barge through, there's nothing to do;
1464 or if defender can barge through too, don't let attacker
1465 do so, otherwise they might just end up swapping places
1466 again when defender gets its chance to move */
1467 if ((pa
->mflags3
& M3_DISPLACES
) != 0 && (pd
->mflags3
& M3_DISPLACES
) == 0
1468 /* no displacing grid bugs diagonally */
1469 && !(magr
->mx
!= mdef
->mx
&& magr
->my
!= mdef
->my
1470 && NODIAG(monsndx(pd
)))
1471 /* no displacing trapped monsters or multi-location longworms */
1472 && !mdef
->mtrapped
&& (!mdef
->wormno
|| !count_wsegs(mdef
))
1473 /* riders can move anything; others, same size or smaller only */
1474 && (is_rider(pa
) || pa
->msize
>= pd
->msize
))
1479 /* Is the square close enough for the monster to move or attack into? */
1485 int distance
= dist2(mon
->mx
, mon
->my
, x
, y
);
1487 if (distance
== 2 && NODIAG(mon
->data
- mons
))
1489 return (boolean
) (distance
< 3);
1492 /* really free dead monsters */
1496 struct monst
**mtmp
, *freetmp
;
1499 for (mtmp
= &fmon
; *mtmp
;) {
1501 if (freetmp
->mhp
<= 0 && !freetmp
->isgd
) {
1502 *mtmp
= freetmp
->nmon
;
1503 freetmp
->nmon
= NULL
;
1504 dealloc_monst(freetmp
);
1507 mtmp
= &(freetmp
->nmon
);
1510 if (count
!= iflags
.purge_monsters
)
1511 impossible("dmonsfree: %d removed doesn't match %d pending",
1512 count
, iflags
.purge_monsters
);
1513 iflags
.purge_monsters
= 0;
1516 /* called when monster is moved to larger structure */
1518 replmon(mtmp
, mtmp2
)
1519 struct monst
*mtmp
, *mtmp2
;
1523 /* transfer the monster's inventory */
1524 for (otmp
= mtmp2
->minvent
; otmp
; otmp
= otmp
->nobj
) {
1525 if (otmp
->where
!= OBJ_MINVENT
|| otmp
->ocarry
!= mtmp
)
1526 impossible("replmon: minvent inconsistency");
1527 otmp
->ocarry
= mtmp2
;
1531 /* remove the old monster from the map and from `fmon' list */
1532 relmon(mtmp
, (struct monst
**) 0);
1534 /* finish adding its replacement */
1535 if (mtmp
!= u
.usteed
) /* don't place steed onto the map */
1536 place_monster(mtmp2
, mtmp2
->mx
, mtmp2
->my
);
1537 if (mtmp2
->wormno
) /* update level.monsters[wseg->wx][wseg->wy] */
1538 place_wsegs(mtmp2
); /* locations to mtmp2 not mtmp. */
1539 if (emits_light(mtmp2
->data
)) {
1540 /* since this is so rare, we don't have any `mon_move_light_source' */
1541 new_light_source(mtmp2
->mx
, mtmp2
->my
, emits_light(mtmp2
->data
),
1542 LS_MONSTER
, monst_to_any(mtmp2
));
1543 /* here we rely on fact that `mtmp' hasn't actually been deleted */
1544 del_light_source(LS_MONSTER
, monst_to_any(mtmp
));
1548 if (u
.ustuck
== mtmp
)
1550 if (u
.usteed
== mtmp
)
1553 replshk(mtmp
, mtmp2
);
1555 /* discard the old monster */
1556 dealloc_monst(mtmp
);
1559 /* release mon from the display and the map's monster list,
1560 maybe transfer it to one of the other monster lists */
1562 relmon(mon
, monst_list
)
1564 struct monst
**monst_list
; /* &migrating_mons or &mydogs or null */
1567 boolean unhide
= (monst_list
!= 0);
1568 int mx
= mon
->mx
, my
= mon
->my
;
1571 panic("relmon: no fmon available.");
1574 /* can't remain hidden across level changes (exception: wizard
1575 clone can continue imitating some other monster form); also,
1576 might be imitating a boulder so need line-of-sight unblocking */
1577 mon
->mundetected
= 0;
1578 if (mon
->m_ap_type
&& mon
->m_ap_type
!= M_AP_MONSTER
)
1582 remove_monster(mx
, my
);
1587 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
1588 if (mtmp
->nmon
== mon
)
1592 mtmp
->nmon
= mon
->nmon
;
1594 panic("relmon: mon not in list.");
1599 /* insert into mydogs or migrating_mons */
1600 mon
->nmon
= *monst_list
;
1603 /* orphan has no next monster */
1609 copy_mextra(mtmp2
, mtmp1
)
1610 struct monst
*mtmp2
, *mtmp1
;
1612 if (!mtmp2
|| !mtmp1
|| !mtmp1
->mextra
)
1616 mtmp2
->mextra
= newmextra();
1618 new_mname(mtmp2
, (int) strlen(MNAME(mtmp1
)) + 1);
1619 Strcpy(MNAME(mtmp2
), MNAME(mtmp1
));
1624 (void) memcpy((genericptr_t
) EGD(mtmp2
), (genericptr_t
) EGD(mtmp1
),
1625 sizeof (struct egd
));
1630 (void) memcpy((genericptr_t
) EPRI(mtmp2
), (genericptr_t
) EPRI(mtmp1
),
1631 sizeof (struct epri
));
1636 (void) memcpy((genericptr_t
) ESHK(mtmp2
), (genericptr_t
) ESHK(mtmp1
),
1637 sizeof (struct eshk
));
1642 (void) memcpy((genericptr_t
) EMIN(mtmp2
), (genericptr_t
) EMIN(mtmp1
),
1643 sizeof (struct emin
));
1648 (void) memcpy((genericptr_t
) EDOG(mtmp2
), (genericptr_t
) EDOG(mtmp1
),
1649 sizeof (struct edog
));
1651 if (has_mcorpsenm(mtmp1
))
1652 MCORPSENM(mtmp2
) = MCORPSENM(mtmp1
);
1659 struct mextra
*x
= m
->mextra
;
1663 free((genericptr_t
) x
->mname
);
1665 free((genericptr_t
) x
->egd
);
1667 free((genericptr_t
) x
->epri
);
1669 free((genericptr_t
) x
->eshk
);
1671 free((genericptr_t
) x
->emin
);
1673 free((genericptr_t
) x
->edog
);
1674 /* [no action needed for x->mcorpsenm] */
1676 free((genericptr_t
) x
);
1677 m
->mextra
= (struct mextra
*) 0;
1686 panic("dealloc_monst with nmon");
1688 dealloc_mextra(mon
);
1689 free((genericptr_t
) mon
);
1692 /* remove effects of mtmp from other data structures */
1694 m_detach(mtmp
, mptr
)
1696 struct permonst
*mptr
; /* reflects mtmp->data _prior_ to mtmp's death */
1698 if (mtmp
== context
.polearm
.hitmon
)
1699 context
.polearm
.hitmon
= 0;
1701 m_unleash(mtmp
, FALSE
);
1702 /* to prevent an infinite relobj-flooreffects-hmon-killed loop */
1704 mtmp
->mhp
= 0; /* simplify some tests: force mhp to 0 */
1705 relobj(mtmp
, 0, FALSE
);
1706 remove_monster(mtmp
->mx
, mtmp
->my
);
1707 if (emits_light(mptr
))
1708 del_light_source(LS_MONSTER
, monst_to_any(mtmp
));
1709 if (mtmp
->m_ap_type
)
1711 newsym(mtmp
->mx
, mtmp
->my
);
1713 fill_pit(mtmp
->mx
, mtmp
->my
);
1719 iflags
.purge_monsters
++;
1722 /* find the worn amulet of life saving which will save a monster */
1727 if (!nonliving(mon
->data
) || is_vampshifter(mon
)) {
1728 struct obj
*otmp
= which_armor(mon
, W_AMUL
);
1730 if (otmp
&& otmp
->otyp
== AMULET_OF_LIFE_SAVING
)
1733 return (struct obj
*) 0;
1737 lifesaved_monster(mtmp
)
1741 struct obj
*lifesave
= mlifesaver(mtmp
);
1744 /* not canseemon; amulets are on the head, so you don't want
1745 * to show this for a long worm with only a tail visible.
1746 * Nor do you check invisibility, because glowing and
1747 * disintegrating amulets are always visible. */
1748 if (cansee(mtmp
->mx
, mtmp
->my
)) {
1749 pline("But wait...");
1750 pline("%s medallion begins to glow!", s_suffix(Monnam(mtmp
)));
1751 makeknown(AMULET_OF_LIFE_SAVING
);
1752 /* amulet is visible, but monster might not be */
1753 if (canseemon(mtmp
)) {
1754 if (attacktype(mtmp
->data
, AT_EXPL
)
1755 || attacktype(mtmp
->data
, AT_BOOM
))
1756 pline("%s reconstitutes!", Monnam(mtmp
));
1758 pline("%s looks much better!", Monnam(mtmp
));
1760 pline_The("medallion crumbles to dust!");
1762 m_useup(mtmp
, lifesave
);
1764 surviver
= !(mvitals
[monsndx(mtmp
->data
)].mvflags
& G_GENOD
);
1767 if (mtmp
->mtame
&& !mtmp
->isminion
) {
1768 wary_dog(mtmp
, !surviver
);
1770 if (mtmp
->mhpmax
<= 0)
1772 mtmp
->mhp
= mtmp
->mhpmax
;
1776 /* genocided monster can't be life-saved */
1777 if (cansee(mtmp
->mx
, mtmp
->my
))
1778 pline("Unfortunately, %s is still genocided...", mon_nam(mtmp
));
1785 register struct monst
*mtmp
;
1787 struct permonst
*mptr
;
1790 lifesaved_monster(mtmp
);
1794 if (is_vampshifter(mtmp
)) {
1795 int mndx
= mtmp
->cham
;
1796 int x
= mtmp
->mx
, y
= mtmp
->my
;
1798 /* this only happens if shapeshifted */
1799 if (mndx
>= LOW_PM
&& mndx
!= monsndx(mtmp
->data
)
1800 && !(mvitals
[mndx
].mvflags
& G_GENOD
)) {
1802 boolean in_door
= (amorphous(mtmp
->data
)
1803 && closed_door(mtmp
->mx
, mtmp
->my
)),
1804 /* alternate message phrasing for some monster types */
1805 spec_mon
= (nonliving(mtmp
->data
)
1806 || noncorporeal(mtmp
->data
)
1807 || amorphous(mtmp
->data
));
1809 /* construct a format string before transformation */
1810 Sprintf(buf
, "The %s%s suddenly %s and rises as %%s!",
1811 spec_mon
? "" : "seemingly dead ",
1812 x_monnam(mtmp
, ARTICLE_NONE
, (char *) 0,
1813 SUPPRESS_SADDLE
| SUPPRESS_HALLUCINATION
1814 | SUPPRESS_INVISIBLE
| SUPPRESS_IT
,
1816 spec_mon
? "reconstitutes" : "transforms");
1819 if (mtmp
->mhpmax
<= 0)
1821 mtmp
->mhp
= mtmp
->mhpmax
;
1822 /* this can happen if previously a fog cloud */
1823 if (u
.uswallow
&& (mtmp
== u
.ustuck
))
1824 expels(mtmp
, mtmp
->data
, FALSE
);
1828 if (enexto(&new_xy
, mtmp
->mx
, mtmp
->my
, &mons
[mndx
])) {
1829 rloc_to(mtmp
, new_xy
.x
, new_xy
.y
);
1832 newcham(mtmp
, &mons
[mndx
], FALSE
, FALSE
);
1833 if (mtmp
->data
== &mons
[mndx
])
1834 mtmp
->cham
= NON_PM
;
1837 if (canspotmon(mtmp
)) {
1838 pline(buf
, a_monnam(mtmp
));
1839 vamp_rise_msg
= TRUE
;
1846 /* dead vault guard is actually kept at coordinate <0,0> until
1847 his temporary corridor to/from the vault has been removed;
1848 need to do this after life-saving and before m_detach() */
1849 if (mtmp
->isgd
&& !grddead(mtmp
))
1852 /* Player is thrown from his steed when it dies */
1853 if (mtmp
== u
.usteed
)
1854 dismount_steed(DISMOUNT_GENERIC
);
1856 mptr
= mtmp
->data
; /* save this for m_detach() */
1857 /* restore chameleon, lycanthropes to true form at death */
1858 if (mtmp
->cham
>= LOW_PM
) {
1859 set_mon_data(mtmp
, &mons
[mtmp
->cham
], -1);
1860 mtmp
->cham
= NON_PM
;
1861 } else if (mtmp
->data
== &mons
[PM_WEREJACKAL
])
1862 set_mon_data(mtmp
, &mons
[PM_HUMAN_WEREJACKAL
], -1);
1863 else if (mtmp
->data
== &mons
[PM_WEREWOLF
])
1864 set_mon_data(mtmp
, &mons
[PM_HUMAN_WEREWOLF
], -1);
1865 else if (mtmp
->data
== &mons
[PM_WERERAT
])
1866 set_mon_data(mtmp
, &mons
[PM_HUMAN_WERERAT
], -1);
1868 /* if MAXMONNO monsters of a given type have died, and it
1869 * can be done, extinguish that monster.
1871 * mvitals[].died does double duty as total number of dead monsters
1872 * and as experience factor for the player killing more monsters.
1873 * this means that a dragon dying by other means reduces the
1874 * experience the player gets for killing a dragon directly; this
1875 * is probably not too bad, since the player likely finagled the
1876 * first dead dragon via ring of conflict or pets, and extinguishing
1877 * based on only player kills probably opens more avenues of abuse
1878 * for rings of conflict and such.
1880 tmp
= monsndx(mtmp
->data
);
1881 if (mvitals
[tmp
].died
< 255)
1882 mvitals
[tmp
].died
++;
1884 /* if it's a (possibly polymorphed) quest leader, mark him as dead */
1885 if (mtmp
->m_id
== quest_status
.leader_m_id
)
1886 quest_status
.leader_is_dead
= TRUE
;
1888 /* if the mail daemon dies, no more mail delivery. -3. */
1889 if (tmp
== PM_MAIL_DAEMON
)
1890 mvitals
[tmp
].mvflags
|= G_GENOD
;
1893 if (mtmp
->data
->mlet
== S_KOP
) {
1894 /* Dead Kops may come back. */
1896 case 1: /* returns near the stairs */
1897 (void) makemon(mtmp
->data
, xdnstair
, ydnstair
, NO_MM_FLAGS
);
1899 case 2: /* randomly */
1900 (void) makemon(mtmp
->data
, 0, 0, NO_MM_FLAGS
);
1908 if (mtmp
->data
->msound
== MS_NEMESIS
)
1910 if (mtmp
->data
== &mons
[PM_MEDUSA
])
1911 u
.uachieve
.killed_medusa
= 1;
1912 if (glyph_is_invisible(levl
[mtmp
->mx
][mtmp
->my
].glyph
))
1913 unmap_object(mtmp
->mx
, mtmp
->my
);
1914 m_detach(mtmp
, mptr
);
1917 /* TRUE if corpse might be dropped, magr may die if mon was swallowed */
1919 corpse_chance(mon
, magr
, was_swallowed
)
1921 struct monst
*magr
; /* killer, if swallowed */
1922 boolean was_swallowed
; /* digestion */
1924 struct permonst
*mdat
= mon
->data
;
1927 if (mdat
== &mons
[PM_VLAD_THE_IMPALER
] || mdat
->mlet
== S_LICH
) {
1928 if (cansee(mon
->mx
, mon
->my
) && !was_swallowed
)
1929 pline("%s body crumbles into dust.", s_suffix(Monnam(mon
)));
1933 /* Gas spores always explode upon death */
1934 for (i
= 0; i
< NATTK
; i
++) {
1935 if (mdat
->mattk
[i
].aatyp
== AT_BOOM
) {
1936 if (mdat
->mattk
[i
].damn
)
1937 tmp
= d((int) mdat
->mattk
[i
].damn
, (int) mdat
->mattk
[i
].damd
);
1938 else if (mdat
->mattk
[i
].damd
)
1939 tmp
= d((int) mdat
->mlevel
+ 1, (int) mdat
->mattk
[i
].damd
);
1942 if (was_swallowed
&& magr
) {
1943 if (magr
== &youmonst
) {
1944 There("is an explosion in your %s!", body_part(STOMACH
));
1945 Sprintf(killer
.name
, "%s explosion",
1946 s_suffix(mdat
->mname
));
1947 losehp(Maybe_Half_Phys(tmp
), killer
.name
, KILLED_BY_AN
);
1949 You_hear("an explosion.");
1953 if (magr
->mhp
< 1) { /* maybe lifesaved */
1954 if (canspotmon(magr
))
1955 pline("%s rips open!", Monnam(magr
));
1956 } else if (canseemon(magr
))
1957 pline("%s seems to have indigestion.", Monnam(magr
));
1963 Sprintf(killer
.name
, "%s explosion", s_suffix(mdat
->mname
));
1964 killer
.format
= KILLED_BY_AN
;
1965 explode(mon
->mx
, mon
->my
, -1, tmp
, MON_EXPLODE
, EXPL_NOXIOUS
);
1970 /* must duplicate this below check in xkilled() since it results in
1971 * creating no objects as well as no corpse
1973 if (LEVEL_SPECIFIC_NOCORPSE(mdat
))
1976 if (((bigmonst(mdat
) || mdat
== &mons
[PM_LIZARD
]) && !mon
->mcloned
)
1977 || is_golem(mdat
) || is_mplayer(mdat
) || is_rider(mdat
))
1979 tmp
= 2 + ((mdat
->geno
& G_FREQ
) < 2) + verysmall(mdat
);
1980 return (boolean
) !rn2(tmp
);
1983 /* drop (perhaps) a cadaver and remove monster */
1986 register struct monst
*mdef
;
1990 return; /* lifesaved */
1992 if (corpse_chance(mdef
, (struct monst
*) 0, FALSE
)
1993 && (accessible(mdef
->mx
, mdef
->my
) || is_pool(mdef
->mx
, mdef
->my
)))
1994 (void) make_corpse(mdef
, CORPSTAT_NONE
);
1997 /* monster disappears, not dies */
2002 mdef
->mhp
= 0; /* can skip some inventory bookkeeping */
2004 /* dead vault guard is actually kept at coordinate <0,0> until
2005 his temporary corridor to/from the vault has been removed */
2006 if (mdef
->isgd
&& !grddead(mdef
))
2008 /* hero is thrown from his steed when it disappears */
2009 if (mdef
== u
.usteed
)
2010 dismount_steed(DISMOUNT_GENERIC
);
2011 /* drop special items like the Amulet so that a dismissed Kop or nurse
2012 can't remove them from the game */
2013 mdrop_special_objs(mdef
);
2014 /* release rest of monster's inventory--it is removed from game */
2015 discard_minvent(mdef
);
2016 m_detach(mdef
, mdef
->data
);
2019 /* drop a statue or rock and remove monster */
2024 struct obj
*otmp
, *obj
, *oldminvent
;
2025 xchar x
= mdef
->mx
, y
= mdef
->my
;
2026 boolean wasinside
= FALSE
;
2028 /* we have to make the statue before calling mondead, to be able to
2029 * put inventory in it, and we have to check for lifesaving before
2030 * making the statue....
2032 lifesaved_monster(mdef
);
2036 mdef
->mtrapped
= 0; /* (see m_detach) */
2038 if ((int) mdef
->data
->msize
> MZ_TINY
2039 || !rn2(2 + ((int) (mdef
->data
->geno
& G_FREQ
) > 2))) {
2041 /* some objects may end up outside the statue */
2042 while ((obj
= mdef
->minvent
) != 0) {
2043 obj_extract_self(obj
);
2045 update_mon_intrinsics(mdef
, obj
, FALSE
, TRUE
);
2046 obj_no_longer_held(obj
);
2047 if (obj
->owornmask
& W_WEP
)
2048 setmnotwielded(mdef
, obj
);
2049 obj
->owornmask
= 0L;
2050 if (obj
->otyp
== BOULDER
2051 #if 0 /* monsters don't carry statues */
2052 || (obj
->otyp
== STATUE
2053 && mons
[obj
->corpsenm
].msize
>= mdef
->data
->msize
)
2055 /* invocation tools resist even with 0% resistance */
2056 || obj_resists(obj
, 0, 0)) {
2057 if (flooreffects(obj
, x
, y
, "fall"))
2059 place_object(obj
, x
, y
);
2062 end_burn(obj
, TRUE
);
2063 obj
->nobj
= oldminvent
;
2067 /* defer statue creation until after inventory removal
2068 so that saved monster traits won't retain any stale
2069 item-conferred attributes */
2070 otmp
= mkcorpstat(STATUE
, mdef
, mdef
->data
, x
, y
, CORPSTAT_NONE
);
2071 if (has_mname(mdef
))
2072 otmp
= oname(otmp
, MNAME(mdef
));
2073 while ((obj
= oldminvent
) != 0) {
2074 oldminvent
= obj
->nobj
;
2075 (void) add_to_container(otmp
, obj
);
2077 /* Archeologists should not break unique statues */
2078 if (mdef
->data
->geno
& G_UNIQ
)
2080 otmp
->owt
= weight(otmp
);
2082 otmp
= mksobj_at(ROCK
, x
, y
, TRUE
, FALSE
);
2085 /* mondead() already does this, but we must do it before the newsym */
2086 if (glyph_is_invisible(levl
[x
][y
].glyph
))
2090 /* We don't currently trap the hero in the statue in this case but we
2092 if (u
.uswallow
&& u
.ustuck
== mdef
)
2096 if (is_animal(mdef
->data
))
2097 You("%s through an opening in the new %s.",
2098 locomotion(youmonst
.data
, "jump"), xname(otmp
));
2102 /* another monster has killed the monster mdef */
2104 monkilled(mdef
, fltxt
, how
)
2109 boolean be_sad
= FALSE
; /* true if unseen pet is killed */
2111 if ((mdef
->wormno
? worm_known(mdef
) : cansee(mdef
->mx
, mdef
->my
))
2113 pline("%s is %s%s%s!", Monnam(mdef
),
2114 nonliving(mdef
->data
) ? "destroyed" : "killed",
2115 *fltxt
? " by the " : "", fltxt
);
2117 be_sad
= (mdef
->mtame
!= 0);
2119 /* no corpses if digested or disintegrated */
2120 if (how
== AD_DGST
|| how
== -AD_RBRE
)
2125 if (be_sad
&& mdef
->mhp
<= 0)
2126 You("have a sad feeling for a moment, then it passes.");
2133 if (u
.ustuck
== mtmp
) {
2139 if (Punished
&& uchain
->where
!= OBJ_FLOOR
)
2141 vision_full_recalc
= 1;
2155 /* the player has killed the monster mtmp */
2159 int dest
; /* dest==1, normal; dest==0, don't print message; dest==2, don't
2160 drop corpse either; dest==3, message but no corpse */
2162 int tmp
, mndx
, x
= mtmp
->mx
, y
= mtmp
->my
;
2163 struct permonst
*mdat
;
2166 boolean wasinside
= u
.uswallow
&& (u
.ustuck
== mtmp
);
2167 boolean burycorpse
= FALSE
;
2170 u
.uconduct
.killer
++;
2173 const char *verb
= nonliving(mtmp
->data
) ? "destroy" : "kill";
2175 if (!wasinside
&& !canspotmon(mtmp
))
2176 You("%s it!", verb
);
2182 (has_mname(mtmp
)) ? ARTICLE_NONE
: ARTICLE_THE
,
2184 (has_mname(mtmp
)) ? SUPPRESS_SADDLE
: 0,
2189 if (mtmp
->mtrapped
&& (t
= t_at(x
, y
)) != 0
2190 && (t
->ttyp
== PIT
|| t
->ttyp
== SPIKED_PIT
)) {
2191 if (sobj_at(BOULDER
, x
, y
))
2193 * Prevent corpses/treasure being created "on top"
2194 * of the boulder that is about to fall in. This is
2195 * out of order, but cannot be helped unless this
2196 * whole routine is rearranged.
2198 if (m_carrying(mtmp
, BOULDER
))
2202 /* your pet knows who just killed it...watch out */
2203 if (mtmp
->mtame
&& !mtmp
->isminion
)
2204 EDOG(mtmp
)->killed_by_u
= 1;
2206 if (wasinside
&& thrownobj
&& thrownobj
!= uball
) {
2207 /* thrown object has killed hero's engulfer; add it to mon's
2208 inventory now so that it will be placed with mon's other
2209 stuff prior to lookhere/autopickup when hero is expelled
2210 below (as a side-effect, this missile has immunity from
2211 being consumed [for this shot/throw only]) */
2212 mpickobj(mtmp
, thrownobj
);
2213 /* let throwing code know that missile has been disposed of */
2217 vamp_rise_msg
= FALSE
; /* might get set in mondead() */
2218 /* dispose of monster and make cadaver */
2224 if (mtmp
->mhp
> 0) { /* monster lifesaved */
2225 /* Cannot put the non-visible lifesaving message in
2226 * lifesaved_monster() since the message appears only when you
2227 * kill it (as opposed to visible lifesaving which always
2231 if (!cansee(x
, y
) && !vamp_rise_msg
)
2232 pline("Maybe not...");
2236 mdat
= mtmp
->data
; /* note: mondead can change mtmp->data */
2237 mndx
= monsndx(mdat
);
2244 if ((dest
& 2) || LEVEL_SPECIFIC_NOCORPSE(mdat
))
2248 if (mdat
== &mons
[PM_MAIL_DAEMON
]) {
2249 stackobj(mksobj_at(SCR_MAIL
, x
, y
, FALSE
, FALSE
));
2252 if (accessible(x
, y
) || is_pool(x
, y
)) {
2253 struct obj
*cadaver
;
2256 /* illogical but traditional "treasure drop" */
2257 if (!rn2(6) && !(mvitals
[mndx
].mvflags
& G_NOCORPSE
)
2258 /* no extra item from swallower or steed */
2259 && (x
!= u
.ux
|| y
!= u
.uy
)
2260 /* no extra item from kops--too easy to abuse */
2261 && mdat
->mlet
!= S_KOP
2262 /* no items from cloned monsters */
2263 && !mtmp
->mcloned
) {
2264 otmp
= mkobj(RANDOM_CLASS
, TRUE
);
2265 /* don't create large objects from small monsters */
2267 if (mdat
->msize
< MZ_HUMAN
&& otyp
!= FIGURINE
2268 /* oc_big is also oc_bimanual and oc_bulky */
2269 && (otmp
->owt
> 30 || objects
[otyp
].oc_big
)) {
2271 } else if (!flooreffects(otmp
, x
, y
, (dest
& 1) ? "fall" : "")) {
2272 place_object(otmp
, x
, y
);
2276 /* corpse--none if hero was inside the monster */
2277 if (!wasinside
&& corpse_chance(mtmp
, (struct monst
*) 0, FALSE
)) {
2278 cadaver
= make_corpse(mtmp
, burycorpse
? CORPSTAT_BURIED
2280 if (burycorpse
&& cadaver
&& cansee(x
, y
) && !mtmp
->minvis
2281 && cadaver
->where
== OBJ_BURIED
&& (dest
& 1)) {
2282 pline("%s corpse ends up buried.", s_suffix(Monnam(mtmp
)));
2287 spoteffects(TRUE
); /* poor man's expels() */
2288 /* monster is gone, corpse or other object might now be visible */
2292 /* punish bad behaviour */
2293 if (is_human(mdat
) && (!always_hostile(mdat
) && mtmp
->malign
<= 0)
2294 && (mndx
< PM_ARCHEOLOGIST
|| mndx
> PM_WIZARD
)
2295 && u
.ualign
.type
!= A_CHAOTIC
) {
2296 HTelepat
&= ~INTRINSIC
;
2299 if (Blind
&& !Blind_telepat
)
2300 see_monsters(); /* Can't sense monsters any more. */
2302 if ((mtmp
->mpeaceful
&& !rn2(2)) || mtmp
->mtame
)
2304 if (is_unicorn(mdat
) && sgn(u
.ualign
.type
) == sgn(mdat
->maligntyp
)) {
2306 You_feel("guilty...");
2309 /* give experience points */
2310 tmp
= experience(mtmp
, (int) mvitals
[mndx
].died
);
2311 more_experienced(tmp
, 0);
2312 newexplevel(); /* will decide if you go up */
2314 /* adjust alignment points */
2315 if (mtmp
->m_id
== quest_status
.leader_m_id
) { /* REAL BAD! */
2316 adjalign(-(u
.ualign
.record
+ (int) ALIGNLIM
/ 2));
2317 pline("That was %sa bad idea...",
2318 u
.uevent
.qcompleted
? "probably " : "");
2319 } else if (mdat
->msound
== MS_NEMESIS
) { /* Real good! */
2320 adjalign((int) (ALIGNLIM
/ 4));
2321 } else if (mdat
->msound
== MS_GUARDIAN
) { /* Bad */
2322 adjalign(-(int) (ALIGNLIM
/ 8));
2324 pline("That was probably a bad idea...");
2326 pline("Whoopsie-daisy!");
2327 } else if (mtmp
->ispriest
) {
2328 adjalign((p_coaligned(mtmp
)) ? -2 : 2);
2329 /* cancel divine protection for killing your priest */
2330 if (p_coaligned(mtmp
))
2332 if (mdat
->maligntyp
== A_NONE
)
2333 adjalign((int) (ALIGNLIM
/ 4)); /* BIG bonus */
2334 } else if (mtmp
->mtame
) {
2335 adjalign(-15); /* bad!! */
2336 /* your god is mighty displeased... */
2338 You_hear("the rumble of distant thunder...");
2340 You_hear("the studio audience applaud!");
2341 } else if (mtmp
->mpeaceful
)
2344 /* malign was already adjusted for u.ualign.type and randomization */
2345 adjalign(mtmp
->malign
);
2348 /* changes the monster into a stone monster of the same type
2349 this should only be called when poly_when_stoned() is true */
2354 if (mtmp
->data
->mlet
== S_GOLEM
) {
2355 /* it's a golem, and not a stone golem */
2356 if (canseemon(mtmp
))
2357 pline("%s solidifies...", Monnam(mtmp
));
2358 if (newcham(mtmp
, &mons
[PM_STONE_GOLEM
], FALSE
, FALSE
)) {
2359 if (canseemon(mtmp
))
2360 pline("Now it's %s.", an(mtmp
->data
->mname
));
2362 if (canseemon(mtmp
))
2363 pline("... and returns to normal.");
2366 impossible("Can't polystone %s!", a_monnam(mtmp
));
2373 if (is_vampshifter(mtmp
)) {
2374 int mndx
= mtmp
->cham
;
2375 int x
= mtmp
->mx
, y
= mtmp
->my
;
2377 /* this only happens if shapeshifted */
2378 if (mndx
>= LOW_PM
&& mndx
!= monsndx(mtmp
->data
)
2379 && !(mvitals
[mndx
].mvflags
& G_GENOD
)) {
2381 boolean in_door
= (amorphous(mtmp
->data
)
2382 && closed_door(mtmp
->mx
, mtmp
->my
));
2384 /* construct a format string before transformation */
2385 Sprintf(buf
, "The lapidifying %s %s %s",
2386 x_monnam(mtmp
, ARTICLE_NONE
, (char *) 0,
2387 SUPPRESS_SADDLE
| SUPPRESS_HALLUCINATION
2388 | SUPPRESS_INVISIBLE
| SUPPRESS_IT
,
2390 amorphous(mtmp
->data
) ? "coalesces on the" :
2391 is_flyer(mtmp
->data
) ? "drops to the" : "writhes on the",
2395 if (mtmp
->mhpmax
<= 0)
2397 mtmp
->mhp
= mtmp
->mhpmax
;
2398 /* this can happen if previously a fog cloud */
2399 if (u
.uswallow
&& (mtmp
== u
.ustuck
))
2400 expels(mtmp
, mtmp
->data
, FALSE
);
2404 if (enexto(&new_xy
, mtmp
->mx
, mtmp
->my
, &mons
[mndx
])) {
2405 rloc_to(mtmp
, new_xy
.x
, new_xy
.y
);
2408 if (canspotmon(mtmp
)) {
2410 display_nhwindow(WIN_MESSAGE
, FALSE
);
2412 newcham(mtmp
, &mons
[mndx
], FALSE
, FALSE
);
2413 if (mtmp
->data
== &mons
[mndx
])
2414 mtmp
->cham
= NON_PM
;
2417 if (canspotmon(mtmp
)) {
2418 pline("%s rises from the %s with renewed agility!",
2419 Amonnam(mtmp
), surface(mtmp
->mx
, mtmp
->my
));
2421 newsym(mtmp
->mx
, mtmp
->my
);
2422 return FALSE
; /* didn't petrify */
2428 /* make monster mtmp next to you (if possible);
2429 might place monst on far side of a wall or boulder */
2435 boolean couldspot
= canspotmon(mtmp
);
2437 if (mtmp
== u
.usteed
) {
2438 /* Keep your steed in sync with you instead */
2444 if (!enexto(&mm
, u
.ux
, u
.uy
, mtmp
->data
))
2446 rloc_to(mtmp
, mm
.x
, mm
.y
);
2447 if (!in_mklev
&& (mtmp
->mstrategy
& STRAT_APPEARMSG
)) {
2448 mtmp
->mstrategy
&= ~STRAT_APPEARMSG
; /* one chance only */
2449 if (!couldspot
&& canspotmon(mtmp
))
2450 pline("%s suddenly %s!", Amonnam(mtmp
),
2451 !Blind
? "appears" : "arrives");
2456 /* like mnexto() but requires destination to be directly accessible */
2462 struct permonst
*ptr
= mtmp
->data
;
2463 boolean diagok
= !NODIAG(ptr
- mons
);
2467 if (!enexto(&mm
, u
.ux
, u
.uy
, ptr
))
2469 if (couldsee(mm
.x
, mm
.y
)
2470 /* don't move grid bugs diagonally */
2471 && (diagok
|| mm
.x
== mtmp
->mx
|| mm
.y
== mtmp
->my
)) {
2472 rloc_to(mtmp
, mm
.x
, mm
.y
);
2475 } while (--tryct
> 0);
2479 * Put monster near (or at) location if possible.
2481 * 1 - if a monster was moved from x, y to put mtmp at x, y.
2482 * 0 - in most cases.
2485 mnearto(mtmp
, x
, y
, move_other
)
2486 register struct monst
*mtmp
;
2488 boolean move_other
; /* make sure mtmp gets to x, y! so move m_at(x, y) */
2490 struct monst
*othermon
= (struct monst
*) 0;
2494 if (mtmp
->mx
== x
&& mtmp
->my
== y
)
2497 if (move_other
&& (othermon
= m_at(x
, y
)) != 0) {
2498 if (othermon
->wormno
)
2499 remove_worm(othermon
);
2501 remove_monster(x
, y
);
2506 if (!goodpos(newx
, newy
, mtmp
, 0)) {
2507 /* Actually we have real problems if enexto ever fails.
2508 * Migrating_mons that need to be placed will cause
2509 * no end of trouble.
2511 if (!enexto(&mm
, newx
, newy
, mtmp
->data
))
2516 rloc_to(mtmp
, newx
, newy
);
2518 if (move_other
&& othermon
) {
2519 xchar oldx
= othermon
->mx
, oldy
= othermon
->my
;
2521 othermon
->mx
= othermon
->my
= 0;
2522 (void) mnearto(othermon
, x
, y
, FALSE
);
2523 if (othermon
->mx
== 0 && othermon
->my
== 0) {
2524 /* reloc failed, dump monster into "limbo"
2525 (aka migrate to current level) */
2526 othermon
->mx
= oldx
;
2527 othermon
->my
= oldy
;
2528 mdrop_special_objs(othermon
);
2529 migrate_to_level(othermon
, ledger_no(&u
.uz
), MIGR_APPROX_XY
, NULL
);
2536 /* monster responds to player action; not the same as a passive attack;
2537 assumes reason for response has been tested, and response _must_ be made */
2542 if (mtmp
->data
->msound
== MS_SHRIEK
) {
2544 pline("%s shrieks.", Monnam(mtmp
));
2549 (void) makemon(&mons
[PM_PURPLE_WORM
], 0, 0, NO_MM_FLAGS
);
2551 (void) makemon((struct permonst
*) 0, 0, 0, NO_MM_FLAGS
);
2555 if (mtmp
->data
== &mons
[PM_MEDUSA
]) {
2558 for (i
= 0; i
< NATTK
; i
++)
2559 if (mtmp
->data
->mattk
[i
].aatyp
== AT_GAZE
) {
2560 (void) gazemu(mtmp
, &mtmp
->data
->mattk
[i
]);
2570 mtmp
->mstrategy
&= ~STRAT_WAITMASK
;
2571 if (!mtmp
->mpeaceful
)
2575 mtmp
->mpeaceful
= 0;
2576 if (mtmp
->ispriest
) {
2577 if (p_coaligned(mtmp
))
2578 adjalign(-5); /* very bad */
2582 adjalign(-1); /* attacking peaceful monsters is bad */
2583 if (couldsee(mtmp
->mx
, mtmp
->my
)) {
2584 if (humanoid(mtmp
->data
) || mtmp
->isshk
|| mtmp
->isgd
)
2585 pline("%s gets angry!", Monnam(mtmp
));
2586 else if (flags
.verbose
&& !Deaf
)
2590 /* attacking your own quest leader will anger his or her guardians */
2591 if (!context
.mon_moving
/* should always be the case here */
2592 && mtmp
->data
== &mons
[quest_info(MS_LEADER
)]) {
2594 struct permonst
*q_guardian
= &mons
[quest_info(MS_GUARDIAN
)];
2597 /* guardians will sense this attack even if they can't see it */
2598 for (mon
= fmon
; mon
; mon
= mon
->nmon
) {
2599 if (DEADMONSTER(mon
))
2601 if (mon
->data
== q_guardian
&& mon
->mpeaceful
) {
2607 if (got_mad
&& !Hallucination
)
2608 pline_The("%s appear%s to be angry too...",
2609 got_mad
== 1 ? q_guardian
->mname
2610 : makeplural(q_guardian
->mname
),
2611 got_mad
== 1 ? "s" : "");
2615 /* wake up a monster, usually making it angry in the process */
2618 register struct monst
*mtmp
;
2620 mtmp
->msleeping
= 0;
2621 finish_meating(mtmp
);
2623 if (mtmp
->m_ap_type
) {
2625 } else if (context
.forcefight
&& !context
.mon_moving
2626 && mtmp
->mundetected
) {
2627 mtmp
->mundetected
= 0;
2628 newsym(mtmp
->mx
, mtmp
->my
);
2632 /* Wake up nearby monsters without angering them. */
2636 register struct monst
*mtmp
;
2638 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
2639 if (DEADMONSTER(mtmp
))
2641 if (distu(mtmp
->mx
, mtmp
->my
) < u
.ulevel
* 20) {
2642 mtmp
->msleeping
= 0;
2643 if (!unique_corpstat(mtmp
->data
))
2644 mtmp
->mstrategy
&= ~STRAT_WAITMASK
;
2645 if (mtmp
->mtame
&& !mtmp
->isminion
)
2646 EDOG(mtmp
)->whistletime
= moves
;
2651 /* Wake up monsters near some particular location. */
2653 wake_nearto(x
, y
, distance
)
2654 register int x
, y
, distance
;
2656 register struct monst
*mtmp
;
2658 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
2659 if (DEADMONSTER(mtmp
))
2661 if (distance
== 0 || dist2(mtmp
->mx
, mtmp
->my
, x
, y
) < distance
) {
2662 mtmp
->msleeping
= 0;
2663 if (!unique_corpstat(mtmp
->data
))
2664 mtmp
->mstrategy
&= ~STRAT_WAITMASK
;
2669 /* NOTE: we must check for mimicry before calling this routine */
2672 register struct monst
*mtmp
;
2674 boolean is_blocker_appear
= (is_lightblocker_mappear(mtmp
));
2676 if (has_mcorpsenm(mtmp
))
2677 freemcorpsenm(mtmp
);
2679 mtmp
->m_ap_type
= M_AP_NOTHING
;
2680 mtmp
->mappearance
= 0;
2683 * Discovered mimics don't block light.
2685 if (is_blocker_appear
2686 && !does_block(mtmp
->mx
, mtmp
->my
, &levl
[mtmp
->mx
][mtmp
->my
]))
2687 unblock_point(mtmp
->mx
, mtmp
->my
);
2689 newsym(mtmp
->mx
, mtmp
->my
);
2692 /* force all chameleons to become normal */
2696 register struct monst
*mtmp
;
2699 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
2700 if (DEADMONSTER(mtmp
))
2702 mcham
= (int) mtmp
->cham
;
2703 if (mcham
>= LOW_PM
) {
2704 (void) newcham(mtmp
, &mons
[mcham
], FALSE
, FALSE
);
2705 mtmp
->cham
= NON_PM
;
2707 if (is_were(mtmp
->data
) && mtmp
->data
->mlet
!= S_HUMAN
)
2709 if (mtmp
->m_ap_type
&& cansee(mtmp
->mx
, mtmp
->my
)) {
2711 /* we pretend that the mimic doesn't
2712 know that it has been unmasked */
2713 mtmp
->msleeping
= 1;
2718 /* Let the chameleons change again -dgk */
2722 register struct monst
*mtmp
;
2724 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
2725 if (DEADMONSTER(mtmp
))
2727 mtmp
->cham
= pm_to_cham(monsndx(mtmp
->data
));
2728 if (mtmp
->data
->mlet
== S_MIMIC
&& mtmp
->msleeping
2729 && cansee(mtmp
->mx
, mtmp
->my
)) {
2730 set_mimic_sym(mtmp
);
2731 newsym(mtmp
->mx
, mtmp
->my
);
2736 /* called when restoring a monster from a saved level; protection
2737 against shape-changing might be different now than it was at the
2738 time the level was saved. */
2745 if (Protection_from_shape_changers
) {
2746 mcham
= (int) mon
->cham
;
2747 if (mcham
>= LOW_PM
) {
2749 (void) newcham(mon
, &mons
[mcham
], FALSE
, FALSE
);
2750 } else if (is_were(mon
->data
) && !is_human(mon
->data
)) {
2753 } else if (mon
->cham
== NON_PM
) {
2754 mon
->cham
= pm_to_cham(monsndx(mon
->data
));
2758 /* unwatched hiders may hide again; if so, returns True */
2761 register struct monst
*mtmp
;
2765 if (mtmp
->mcan
|| mtmp
->m_ap_type
|| cansee(mtmp
->mx
, mtmp
->my
)
2766 || rn2(3) || mtmp
== u
.ustuck
2767 /* can't hide while trapped except in pits */
2768 || (mtmp
->mtrapped
&& (t
= t_at(mtmp
->mx
, mtmp
->my
)) != 0
2769 && !(t
->ttyp
== PIT
|| t
->ttyp
== SPIKED_PIT
))
2770 || (sensemon(mtmp
) && distu(mtmp
->mx
, mtmp
->my
) <= 2))
2773 if (mtmp
->data
->mlet
== S_MIMIC
) {
2774 set_mimic_sym(mtmp
);
2776 } else if (levl
[mtmp
->mx
][mtmp
->my
].typ
== ROOM
) {
2777 mtmp
->mundetected
= 1;
2784 /* monster/hero tries to hide under something at the current location */
2790 boolean undetected
= FALSE
, is_u
= (mtmp
== &youmonst
);
2791 xchar x
= is_u
? u
.ux
: mtmp
->mx
, y
= is_u
? u
.uy
: mtmp
->my
;
2793 if (mtmp
== u
.ustuck
) {
2794 ; /* can't hide if holding you or held by you */
2795 } else if (is_u
? (u
.utrap
&& u
.utraptype
!= TT_PIT
)
2796 : (mtmp
->mtrapped
&& (t
= t_at(x
, y
)) != 0
2797 && !(t
->ttyp
== PIT
|| t
->ttyp
== SPIKED_PIT
))) {
2798 ; /* can't hide while stuck in a non-pit trap */
2799 } else if (mtmp
->data
->mlet
== S_EEL
) {
2800 undetected
= (is_pool(x
, y
) && !Is_waterlevel(&u
.uz
));
2801 } else if (hides_under(mtmp
->data
) && OBJ_AT(x
, y
)) {
2802 struct obj
*otmp
= level
.objects
[x
][y
];
2804 /* most monsters won't hide under cockatrice corpse */
2805 if (otmp
->nexthere
|| otmp
->otyp
!= CORPSE
2806 || (mtmp
== &youmonst
? Stone_resistance
: resists_ston(mtmp
))
2807 || !touch_petrifies(&mons
[otmp
->corpsenm
]))
2812 u
.uundetected
= undetected
;
2814 mtmp
->mundetected
= undetected
;
2818 /* called when returning to a previously visited level */
2823 boolean hider_under
= hides_under(mon
->data
) || mon
->data
->mlet
== S_EEL
;
2825 if ((is_hider(mon
->data
) || hider_under
)
2826 && !(mon
->mundetected
|| mon
->m_ap_type
)) {
2827 xchar x
= mon
->mx
, y
= mon
->my
;
2828 char save_viz
= viz_array
[y
][x
];
2830 /* override vision, forcing hero to be unable to see monster's spot */
2831 viz_array
[y
][x
] &= ~(IN_SIGHT
| COULD_SEE
);
2832 if (is_hider(mon
->data
))
2833 (void) restrap(mon
);
2834 /* try again if mimic missed its 1/3 chance to hide */
2835 if (mon
->data
->mlet
== S_MIMIC
&& !mon
->m_ap_type
)
2836 (void) restrap(mon
);
2838 (void) hideunder(mon
);
2839 viz_array
[y
][x
] = save_viz
;
2843 static short *animal_list
= 0; /* list of PM values for animal monsters */
2844 static int animal_list_count
;
2847 mon_animal_list(construct
)
2851 short animal_temp
[SPECIAL_PM
];
2854 /* if (animal_list) impossible("animal_list already exists"); */
2856 for (n
= 0, i
= LOW_PM
; i
< SPECIAL_PM
; i
++)
2857 if (is_animal(&mons
[i
]))
2858 animal_temp
[n
++] = i
;
2859 /* if (n == 0) animal_temp[n++] = NON_PM; */
2861 animal_list
= (short *) alloc(n
* sizeof *animal_list
);
2862 (void) memcpy((genericptr_t
) animal_list
, (genericptr_t
) animal_temp
,
2863 n
* sizeof *animal_list
);
2864 animal_list_count
= n
;
2865 } else { /* release */
2867 free((genericptr_t
) animal_list
), animal_list
= 0;
2868 animal_list_count
= 0;
2878 mon_animal_list(TRUE
);
2880 res
= animal_list
[rn2(animal_list_count
)];
2881 /* rogue level should use monsters represented by uppercase letters
2882 only, but since chameleons aren't generated there (not uppercase!)
2883 we don't perform a lot of retries */
2884 if (Is_rogue_level(&u
.uz
) && !isupper((uchar
) mons
[res
].mlet
))
2885 res
= animal_list
[rn2(animal_list_count
)];
2890 decide_to_shapeshift(mon
, shiftflags
)
2894 struct permonst
*ptr
;
2895 unsigned was_female
= mon
->female
;
2896 boolean msg
= FALSE
;
2898 if ((shiftflags
& SHIFT_MSG
)
2899 || ((shiftflags
& SHIFT_SEENMSG
) && sensemon(mon
)))
2902 if (!is_vampshifter(mon
)) {
2903 /* regular shapeshifter */
2905 (void) newcham(mon
, (struct permonst
*) 0, FALSE
, msg
);
2907 /* The vampire has to be in good health (mhp) to maintain
2910 * If we're shifted and getting low on hp, maybe shift back.
2911 * If we're not already shifted and in good health, maybe shift.
2913 if (mon
->data
->mlet
!= S_VAMPIRE
) {
2914 if ((mon
->mhp
<= (mon
->mhpmax
+ 5) / 6) && rn2(4)
2915 && mon
->cham
>= LOW_PM
)
2916 (void) newcham(mon
, &mons
[mon
->cham
], FALSE
, msg
);
2918 if (mon
->mhp
>= 9 * mon
->mhpmax
/ 10 && !rn2(6)
2920 || distu(mon
->mx
, mon
->my
) > BOLT_LIM
* BOLT_LIM
))
2921 (void) newcham(mon
, (struct permonst
*) 0, FALSE
, msg
);
2923 /* override the 10% chance for sex change */
2925 if (!is_male(ptr
) && !is_female(ptr
) && !is_neuter(ptr
))
2926 mon
->female
= was_female
;
2934 int mndx
= mon
->cham
, wolfchance
= 10;
2935 /* avoid picking monsters with lowercase display symbols ('d' for wolf
2936 and 'v' for fog cloud) on rogue level*/
2937 boolean uppercase_only
= Is_rogue_level(&u
.uz
);
2940 case PM_VLAD_THE_IMPALER
:
2941 /* ensure Vlad can keep carrying the Candelabrum */
2942 if (mon_has_special(mon
))
2943 break; /* leave mndx as is */
2946 case PM_VAMPIRE_LORD
: /* vampire lord or Vlad can become wolf */
2947 if (!rn2(wolfchance
) && !uppercase_only
) {
2952 case PM_VAMPIRE
: /* any vampire can become fog or bat */
2953 mndx
= (!rn2(4) && !uppercase_only
) ? PM_FOG_CLOUD
: PM_VAMPIRE_BAT
;
2959 /* nonshapechangers who warrant special polymorph handling */
2964 return (mon
->isshk
|| mon
->ispriest
|| mon
->isgd
2965 || mon
->m_id
== quest_status
.leader_m_id
);
2968 /* restrict certain special monsters (shopkeepers, aligned priests,
2969 vault guards) to forms that allow them to behave sensibly (catching
2970 gold, speaking?) so that they don't need too much extra code */
2972 validspecmon(mon
, mndx
)
2977 return TRUE
; /* caller wants random */
2979 if (!accept_newcham_form(mndx
))
2980 return FALSE
; /* geno'd or !polyok */
2982 if (isspecmon(mon
)) {
2983 struct permonst
*ptr
= &mons
[mndx
];
2985 /* reject notake because object manipulation is expected
2986 and nohead because speech capability is expected */
2987 if (notake(ptr
) || !has_head(ptr
))
2989 /* [should we check ptr->msound here too?] */
2991 return TRUE
; /* potential new form is ok */
2994 /* prevent wizard mode user from specifying invalid vampshifter shape */
2996 validvamp(mon
, mndx_p
, monclass
)
2998 int *mndx_p
, monclass
;
3000 /* simplify caller's usage */
3001 if (!is_vampshifter(mon
))
3002 return validspecmon(mon
, *mndx_p
);
3004 if (*mndx_p
== PM_VAMPIRE
|| *mndx_p
== PM_VAMPIRE_LORD
3005 || *mndx_p
== PM_VLAD_THE_IMPALER
) {
3006 /* player picked some type of vampire; use mon's self */
3007 *mndx_p
= mon
->cham
;
3010 if (mon
->cham
== PM_VLAD_THE_IMPALER
&& mon_has_special(mon
)) {
3011 /* Vlad with Candelabrum; override choice, then accept it */
3012 *mndx_p
= PM_VLAD_THE_IMPALER
;
3015 /* basic vampires can't become wolves; any can become fog or bat
3016 (we don't enforce upper-case only for rogue level here) */
3017 if (*mndx_p
== PM_WOLF
)
3018 return (boolean
) (mon
->cham
!= PM_VAMPIRE
);
3019 if (*mndx_p
== PM_FOG_CLOUD
|| *mndx_p
== PM_VAMPIRE_BAT
)
3022 /* if we get here, specific type was no good; try by class */
3025 *mndx_p
= mon
->cham
;
3028 *mndx_p
= PM_VAMPIRE_BAT
;
3031 *mndx_p
= PM_FOG_CLOUD
;
3034 if (mon
->cham
!= PM_VAMPIRE
) {
3043 return (boolean
) (*mndx_p
!= NON_PM
);
3047 select_newcham_form(mon
)
3050 int mndx
= NON_PM
, tryct
;
3052 switch (mon
->cham
) {
3055 mndx
= pick_nasty();
3057 case PM_DOPPELGANGER
:
3059 mndx
= pick_nasty();
3060 } else if (rn2(3)) { /* role monsters */
3061 mndx
= rn1(PM_WIZARD
- PM_ARCHEOLOGIST
+ 1, PM_ARCHEOLOGIST
);
3062 } else if (!rn2(3)) { /* quest guardians */
3063 mndx
= rn1(PM_APPRENTICE
- PM_STUDENT
+ 1, PM_STUDENT
);
3064 /* avoid own role's guardian */
3065 if (mndx
== urole
.guardnum
)
3067 } else { /* general humanoids */
3070 mndx
= rn1(SPECIAL_PM
- LOW_PM
, LOW_PM
);
3071 if (humanoid(&mons
[mndx
]) && polyok(&mons
[mndx
]))
3073 } while (--tryct
> 0);
3080 mndx
= pick_animal();
3082 case PM_VLAD_THE_IMPALER
:
3083 case PM_VAMPIRE_LORD
:
3085 mndx
= pickvampshape(mon
);
3087 case NON_PM
: /* ordinary */
3089 struct obj
*m_armr
= which_armor(mon
, W_ARM
);
3091 if (m_armr
&& Is_dragon_scales(m_armr
))
3092 mndx
= (int) (Dragon_scales_to_pm(m_armr
) - mons
);
3093 else if (m_armr
&& Is_dragon_mail(m_armr
))
3094 mndx
= (int) (Dragon_mail_to_pm(m_armr
) - mons
);
3099 /* for debugging: allow control of polymorphed monster */
3100 if (wizard
&& iflags
.mon_polycontrol
) {
3101 char pprompt
[BUFSZ
], buf
[BUFSZ
];
3104 Sprintf(pprompt
, "Change %s @ %s into what kind of monster?",
3106 coord_desc((int) mon
->mx
, (int) mon
->my
, buf
,
3107 (iflags
.getpos_coords
!= GPCOORDS_NONE
)
3108 ? iflags
.getpos_coords
: GPCOORDS_MAP
));
3112 getlin(pprompt
, buf
);
3114 /* for ESC, take form selected above (might be NON_PM) */
3117 /* for "*", use NON_PM to pick an arbitrary shape below */
3118 if (!strcmp(buf
, "*") || !strcmp(buf
, "random")) {
3122 mndx
= name_to_mon(buf
);
3123 if (mndx
== NON_PM
) {
3124 /* didn't get a type, so check whether it's a class
3125 (single letter or text match with def_monsyms[]) */
3126 monclass
= name_to_monclass(buf
, &mndx
);
3127 if (monclass
&& mndx
== NON_PM
)
3128 mndx
= mkclass_poly(monclass
);
3130 if (mndx
>= LOW_PM
) {
3131 /* got a specific type of monster; use it if we can */
3132 if (validvamp(mon
, &mndx
, monclass
))
3134 /* can't; revert to random in case we exhaust tryct */
3138 pline("It can't become that.");
3139 } while (--tryct
> 0);
3141 pline1(thats_enough_tries
);
3142 if (is_vampshifter(mon
) && !validvamp(mon
, &mndx
, monclass
))
3143 mndx
= pickvampshape(mon
); /* don't resort to arbitrary */
3146 /* if no form was specified above, pick one at random now */
3147 if (mndx
== NON_PM
) {
3150 mndx
= rn1(SPECIAL_PM
- LOW_PM
, LOW_PM
);
3151 } while (--tryct
> 0 && !validspecmon(mon
, mndx
)
3152 /* try harder to select uppercase monster on rogue level */
3153 && (tryct
> 40 && Is_rogue_level(&u
.uz
)
3154 && !isupper((uchar
) mons
[mndx
].mlet
)));
3159 /* this used to be inline within newcham() but monpolycontrol needs it too */
3160 STATIC_OVL
struct permonst
*
3161 accept_newcham_form(mndx
)
3164 struct permonst
*mdat
;
3169 if ((mvitals
[mndx
].mvflags
& G_GENOD
) != 0)
3171 if (is_placeholder(mdat
))
3173 /* select_newcham_form() might deliberately pick a player
3174 character type (random selection never does) which
3175 polyok() rejects, so we need a special case here */
3176 if (is_mplayer(mdat
))
3178 /* polyok() rules out M2_PNAME, M2_WERE, and all humans except Kops */
3179 return polyok(mdat
) ? mdat
: 0;
3183 mgender_from_permonst(mtmp
, mdat
)
3185 struct permonst
*mdat
;
3187 if (is_male(mdat
)) {
3189 mtmp
->female
= FALSE
;
3190 } else if (is_female(mdat
)) {
3192 mtmp
->female
= TRUE
;
3193 } else if (!is_neuter(mdat
)) {
3195 mtmp
->female
= !mtmp
->female
;
3199 /* make a chameleon take on another shape, or a polymorph target
3200 (possibly self-inflicted) become a different monster;
3201 returns 1 if it actually changes form */
3203 newcham(mtmp
, mdat
, polyspot
, msg
)
3205 struct permonst
*mdat
;
3206 boolean polyspot
; /* change is the result of wand or spell of polymorph */
3207 boolean msg
; /* "The oldmon turns into a newmon!" */
3211 struct permonst
*olddata
= mtmp
->data
;
3212 char oldname
[BUFSZ
], l_oldname
[BUFSZ
], newname
[BUFSZ
];
3214 /* Riders are immune to polymorph and green slime
3215 (but apparent Rider might actually be a doppelganger) */
3216 if (is_rider(mtmp
->data
) && mtmp
->cham
== NON_PM
)
3220 /* like Monnam() but never mention saddle */
3221 Strcpy(oldname
, x_monnam(mtmp
, ARTICLE_THE
, (char *) 0,
3222 SUPPRESS_SADDLE
, FALSE
));
3223 oldname
[0] = highc(oldname
[0]);
3225 /* we need this one whether msg is true or not */
3226 Strcpy(l_oldname
, x_monnam(mtmp
, ARTICLE_THE
, (char *) 0,
3227 (has_mname(mtmp
)) ? SUPPRESS_SADDLE
: 0, FALSE
));
3229 /* mdat = 0 -> caller wants a random monster shape */
3231 /* select_newcham_form() loops when resorting to random but
3232 it doesn't always pick that so we still retry here too */
3235 mndx
= select_newcham_form(mtmp
);
3236 mdat
= accept_newcham_form(mndx
);
3237 /* for the first several tries we require upper-case on
3238 the rogue level (after that, we take whatever we get) */
3239 if (tryct
> 15 && Is_rogue_level(&u
.uz
)
3240 && mdat
&& !isupper((uchar
) mdat
->mlet
))
3244 } while (--tryct
> 0);
3247 } else if (mvitals
[monsndx(mdat
)].mvflags
& G_GENOD
)
3248 return 0; /* passed in mdat is genocided */
3250 if (mdat
== mtmp
->data
)
3251 return 0; /* still the same monster */
3253 mgender_from_permonst(mtmp
, mdat
);
3255 if (In_endgame(&u
.uz
) && is_mplayer(olddata
) && has_mname(mtmp
)) {
3256 /* mplayers start out as "Foo the Bar", but some of the
3257 * titles are inappropriate when polymorphed, particularly
3258 * into the opposite sex. players don't use ranks when
3259 * polymorphed, so dropping the rank for mplayers seems
3262 char *p
= index(MNAME(mtmp
), ' ');
3268 if (mtmp
->wormno
) { /* throw tail away */
3270 place_monster(mtmp
, mtmp
->mx
, mtmp
->my
);
3272 if (mtmp
->m_ap_type
&& mdat
->mlet
!= S_MIMIC
)
3273 seemimic(mtmp
); /* revert to normal monster */
3275 /* (this code used to try to adjust the monster's health based on
3276 a normal one of its type but there are too many special cases
3277 which need to handled in order to do that correctly, so just
3278 give the new form the same proportion of HP as its old one had) */
3281 /* set level and hit points */
3282 newmonhp(mtmp
, monsndx(mdat
));
3283 /* new hp: same fraction of max as before */
3285 mtmp
->mhp
= (int) (((long) hpn
* (long) mtmp
->mhp
) / (long) hpd
);
3287 /* sanity check (potential overflow) */
3288 if (mtmp
->mhp
< 0 || mtmp
->mhp
> mtmp
->mhpmax
)
3289 mtmp
->mhp
= mtmp
->mhpmax
;
3290 /* unlikely but not impossible; a 1HD creature with 1HP that changes
3291 into a 0HD creature will require this statement */
3295 /* take on the new form... */
3296 set_mon_data(mtmp
, mdat
, 0);
3298 if (emits_light(olddata
) != emits_light(mtmp
->data
)) {
3299 /* used to give light, now doesn't, or vice versa,
3300 or light's range has changed */
3301 if (emits_light(olddata
))
3302 del_light_source(LS_MONSTER
, monst_to_any(mtmp
));
3303 if (emits_light(mtmp
->data
))
3304 new_light_source(mtmp
->mx
, mtmp
->my
, emits_light(mtmp
->data
),
3305 LS_MONSTER
, monst_to_any(mtmp
));
3307 if (!mtmp
->perminvis
|| pm_invisible(olddata
))
3308 mtmp
->perminvis
= pm_invisible(mdat
);
3309 mtmp
->minvis
= mtmp
->invis_blkd
? 0 : mtmp
->perminvis
;
3310 if (mtmp
->mundetected
)
3311 (void) hideunder(mtmp
);
3312 if (u
.ustuck
== mtmp
) {
3314 if (!attacktype(mdat
, AT_ENGL
)) {
3315 /* Does mdat care? */
3316 if (!noncorporeal(mdat
) && !amorphous(mdat
)
3317 && !is_whirly(mdat
) && (mdat
!= &mons
[PM_YELLOW_LIGHT
])) {
3318 char msgtrail
[BUFSZ
];
3320 if (is_vampshifter(mtmp
)) {
3321 Sprintf(msgtrail
, " which was a shapeshifted %s",
3323 } else if (is_animal(mdat
)) {
3324 Strcpy(msgtrail
, "'s stomach");
3329 /* Do this even if msg is FALSE */
3331 (amorphous(olddata
) || is_whirly(olddata
))
3332 ? "emerge from" : "break out of",
3333 l_oldname
, msgtrail
);
3334 msg
= FALSE
; /* message has been given */
3335 mtmp
->mhp
= 1; /* almost dead */
3337 expels(mtmp
, olddata
, FALSE
);
3339 /* update swallow glyphs for new monster */
3342 } else if (!sticks(mdat
) && !sticks(youmonst
.data
))
3347 if (mdat
== &mons
[PM_LONG_WORM
] && (mtmp
->wormno
= get_wormno()) != 0) {
3349 /* DICE 3.0 doesn't like assigning and comparing mtmp->wormno in the
3352 if (mdat
== &mons
[PM_LONG_WORM
]
3353 && (mtmp
->wormno
= get_wormno(), mtmp
->wormno
!= 0)) {
3355 /* we can now create worms with tails - 11/91 */
3356 initworm(mtmp
, rn2(5));
3357 if (count_wsegs(mtmp
))
3358 place_worm_tail_randomly(mtmp
, mtmp
->mx
, mtmp
->my
);
3361 newsym(mtmp
->mx
, mtmp
->my
);
3364 char *save_mname
= 0;
3366 if (has_mname(mtmp
)) {
3367 save_mname
= MNAME(mtmp
);
3368 MNAME(mtmp
) = (char *) 0;
3370 Strcpy(newname
, (mdat
== &mons
[PM_GREEN_SLIME
])
3372 : x_monnam(mtmp
, ARTICLE_A
, (char *) 0,
3373 SUPPRESS_SADDLE
, FALSE
));
3374 if (!strcmpi(oldname
, "it") && !strcmpi(newname
, "it"))
3375 (void) usmellmon(mdat
);
3377 pline("%s turns into %s!", oldname
, newname
);
3379 MNAME(mtmp
) = save_mname
;
3382 /* when polymorph trap/wand/potion produces a vampire, turn in into
3383 a full-fledged vampshifter unless shape-changing is blocked */
3384 if (mtmp
->cham
== NON_PM
&& mdat
->mlet
== S_VAMPIRE
3385 && !Protection_from_shape_changers
)
3386 mtmp
->cham
= pm_to_cham(monsndx(mdat
));
3388 possibly_unwield(mtmp
, polyspot
); /* might lose use of weapon */
3389 mon_break_armor(mtmp
, polyspot
);
3390 if (!(mtmp
->misc_worn_check
& W_ARMG
))
3391 mselftouch(mtmp
, "No longer petrify-resistant, ",
3392 !context
.mon_moving
);
3393 m_dowear(mtmp
, FALSE
);
3395 /* This ought to re-test can_carry() on each item in the inventory
3396 * rather than just checking ex-giants & boulders, but that'd be
3397 * pretty expensive to perform. If implemented, then perhaps
3398 * minvent should be sorted in order to drop heaviest items first.
3400 /* former giants can't continue carrying boulders */
3401 if (mtmp
->minvent
&& !throws_rocks(mdat
)) {
3402 register struct obj
*otmp
, *otmp2
;
3404 for (otmp
= mtmp
->minvent
; otmp
; otmp
= otmp2
) {
3406 if (otmp
->otyp
== BOULDER
) {
3407 /* this keeps otmp from being polymorphed in the
3408 same zap that the monster that held it is polymorphed */
3411 obj_extract_self(otmp
);
3412 /* probably ought to give some "drop" message here */
3413 if (flooreffects(otmp
, mtmp
->mx
, mtmp
->my
, ""))
3415 place_object(otmp
, mtmp
->mx
, mtmp
->my
);
3423 /* sometimes an egg will be special */
3424 #define BREEDER_EGG (!rn2(77))
3427 * Determine if the given monster number can be hatched from an egg.
3428 * Return the monster number to use as the egg's corpsenm. Return
3429 * NON_PM if the given monster can't be hatched.
3432 can_be_hatched(mnum
)
3435 /* ranger quest nemesis has the oviparous bit set, making it
3436 be possible to wish for eggs of that unique monster; turn
3437 such into ordinary eggs rather than forbidding them outright */
3438 if (mnum
== PM_SCORPIUS
)
3441 mnum
= little_to_big(mnum
);
3443 * Queen bees lay killer bee eggs (usually), but killer bees don't
3444 * grow into queen bees. Ditto for [winged-]gargoyles.
3446 if (mnum
== PM_KILLER_BEE
|| mnum
== PM_GARGOYLE
3447 || (lays_eggs(&mons
[mnum
])
3449 || (mnum
!= PM_QUEEN_BEE
&& mnum
!= PM_WINGED_GARGOYLE
))))
3454 /* type of egg laid by #sit; usually matches parent */
3456 egg_type_from_parent(mnum
, force_ordinary
)
3457 int mnum
; /* parent monster; caller must handle lays_eggs() check */
3458 boolean force_ordinary
;
3460 if (force_ordinary
|| !BREEDER_EGG
) {
3461 if (mnum
== PM_QUEEN_BEE
)
3462 mnum
= PM_KILLER_BEE
;
3463 else if (mnum
== PM_WINGED_GARGOYLE
)
3469 /* decide whether an egg of the indicated monster type is viable;
3470 also used to determine whether an egg or tin can be created... */
3472 dead_species(m_idx
, egg
)
3478 /* generic eggs are unhatchable and have corpsenm of NON_PM */
3482 * For monsters with both baby and adult forms, genociding either
3483 * form kills all eggs of that monster. Monsters with more than
3484 * two forms (small->large->giant mimics) are more or less ignored;
3485 * fortunately, none of them have eggs. Species extinction due to
3486 * overpopulation does not kill eggs.
3488 alt_idx
= egg
? big_to_little(m_idx
) : m_idx
;
3489 return (boolean
) ((mvitals
[m_idx
].mvflags
& G_GENOD
) != 0
3490 || (mvitals
[alt_idx
].mvflags
& G_GENOD
) != 0);
3493 /* kill off any eggs of genocided monsters */
3496 struct obj
*obj_list
;
3500 for (otmp
= obj_list
; otmp
; otmp
= otmp
->nobj
)
3501 if (otmp
->otyp
== EGG
) {
3502 if (dead_species(otmp
->corpsenm
, TRUE
)) {
3504 * It seems we could also just catch this when
3505 * it attempted to hatch, so we wouldn't have to
3506 * search all of the objlists.. or stop all
3507 * hatch timers based on a corpsenm.
3511 #if 0 /* not used */
3512 } else if (otmp
->otyp
== TIN
) {
3513 if (dead_species(otmp
->corpsenm
, FALSE
))
3514 otmp
->corpsenm
= NON_PM
; /* empty tin */
3515 } else if (otmp
->otyp
== CORPSE
) {
3516 if (dead_species(otmp
->corpsenm
, FALSE
))
3517 ; /* not yet implemented... */
3519 } else if (Has_contents(otmp
)) {
3520 kill_eggs(otmp
->cobj
);
3524 /* kill all members of genocided species */
3526 kill_genocided_monsters()
3528 struct monst
*mtmp
, *mtmp2
;
3533 * Called during genocide, and again upon level change. The latter
3534 * catches up with any migrating monsters as they finally arrive at
3535 * their intended destinations, so possessions get deposited there.
3537 * Chameleon handling:
3538 * 1) if chameleons have been genocided, destroy them
3539 * regardless of current form;
3540 * 2) otherwise, force every chameleon which is imitating
3541 * any genocided species to take on a new form.
3543 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp2
) {
3545 if (DEADMONSTER(mtmp
))
3547 mndx
= monsndx(mtmp
->data
);
3548 kill_cham
= (mtmp
->cham
>= LOW_PM
3549 && (mvitals
[mtmp
->cham
].mvflags
& G_GENOD
));
3550 if ((mvitals
[mndx
].mvflags
& G_GENOD
) || kill_cham
) {
3551 if (mtmp
->cham
>= LOW_PM
&& !kill_cham
)
3552 (void) newcham(mtmp
, (struct permonst
*) 0, FALSE
, FALSE
);
3557 kill_eggs(mtmp
->minvent
);
3562 kill_eggs(migrating_objs
);
3563 kill_eggs(level
.buriedobjlist
);
3567 golemeffects(mon
, damtype
, dam
)
3568 register struct monst
*mon
;
3571 int heal
= 0, slow
= 0;
3573 if (mon
->data
== &mons
[PM_FLESH_GOLEM
]) {
3574 if (damtype
== AD_ELEC
)
3575 heal
= (dam
+ 5) / 6;
3576 else if (damtype
== AD_FIRE
|| damtype
== AD_COLD
)
3578 } else if (mon
->data
== &mons
[PM_IRON_GOLEM
]) {
3579 if (damtype
== AD_ELEC
)
3581 else if (damtype
== AD_FIRE
)
3587 if (mon
->mspeed
!= MSLOW
)
3588 mon_adjust_speed(mon
, -1, (struct obj
*) 0);
3591 if (mon
->mhp
< mon
->mhpmax
) {
3593 if (mon
->mhp
> mon
->mhpmax
)
3594 mon
->mhp
= mon
->mhpmax
;
3595 if (cansee(mon
->mx
, mon
->my
))
3596 pline("%s seems healthier.", Monnam(mon
));
3602 angry_guards(silent
)
3606 int ct
= 0, nct
= 0, sct
= 0, slct
= 0;
3608 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
3609 if (DEADMONSTER(mtmp
))
3611 if (is_watch(mtmp
->data
) && mtmp
->mpeaceful
) {
3613 if (cansee(mtmp
->mx
, mtmp
->my
) && mtmp
->mcanmove
) {
3614 if (distu(mtmp
->mx
, mtmp
->my
) == 2)
3619 if (mtmp
->msleeping
|| mtmp
->mfrozen
) {
3621 mtmp
->msleeping
= mtmp
->mfrozen
= 0;
3623 mtmp
->mpeaceful
= 0;
3627 if (!silent
) { /* do we want pline msgs? */
3629 pline_The("guard%s wake%s up!", slct
> 1 ? "s" : "",
3630 slct
== 1 ? "s" : "");
3633 pline_The("guard%s get%s angry!", nct
== 1 ? "" : "s",
3634 nct
== 1 ? "s" : "");
3636 You_see("%sangry guard%s approaching!",
3637 sct
== 1 ? "an " : "", sct
> 1 ? "s" : "");
3639 You_hear("the shrill sound of a guard's whistle.");
3651 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
3652 if (DEADMONSTER(mtmp
))
3654 if (is_watch(mtmp
->data
))
3655 mtmp
->mpeaceful
= 1;
3660 mimic_hit_msg(mtmp
, otyp
)
3664 short ap
= mtmp
->mappearance
;
3666 switch (mtmp
->m_ap_type
) {
3668 case M_AP_FURNITURE
:
3672 if (otyp
== SPE_HEALING
|| otyp
== SPE_EXTRA_HEALING
) {
3673 pline("%s seems a more vivid %s than before.",
3674 The(simple_typename(ap
)),
3675 c_obj_colors
[objects
[ap
].oc_color
]);
3683 struct permonst
*mdat
;
3686 boolean nonspecific
= FALSE
;
3687 boolean msg_given
= FALSE
;
3690 if (!olfaction(youmonst
.data
))
3692 mndx
= monsndx(mdat
);
3696 You("notice a bovine smell.");
3702 case PM_NEANDERTHAL
:
3703 You("smell body odor.");
3712 case PM_HORNED_DEVIL
:
3719 case PM_HUMAN_WEREJACKAL
:
3720 case PM_HUMAN_WERERAT
:
3721 case PM_HUMAN_WEREWOLF
:
3726 You("detect an odor reminiscent of an animal's den.");
3730 case PM_PURPLE_WORM:
3733 case PM_STEAM_VORTEX
:
3734 You("smell steam.");
3737 case PM_GREEN_SLIME
:
3738 pline("%s stinks.", Something
);
3741 case PM_VIOLET_FUNGUS
:
3743 You("smell mushrooms.");
3746 /* These are here to avoid triggering the
3747 nonspecific treatment through the default case below*/
3748 case PM_WHITE_UNICORN
:
3749 case PM_GRAY_UNICORN
:
3750 case PM_BLACK_UNICORN
:
3759 switch (mdat
->mlet
) {
3761 You("notice a dog smell.");
3765 You("smell a dragon!");
3769 pline("%s smells moldy.", Something
);
3773 You("detect a%s odor reminiscent of a stable.",
3774 (mndx
== PM_PONY
) ? "n" : " strong");
3778 You("smell rotting flesh.");
3786 if (maybe_polyd(is_orc(youmonst
.data
), Race_if(PM_ORC
)))
3787 You("notice an attractive smell.");
3789 pline("A foul stench makes you feel a little nauseated.");
3796 return msg_given
? TRUE
: FALSE
;