1 /* NetHack 3.6 mon.c $NHDT-Date: 1466289475 2016/06/18 22:37:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.227 $ */
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 if (DEADMONSTER(mtmp
))
89 x
= mtmp
->mx
, y
= mtmp
->my
;
90 if (!isok(x
, y
) && !(mtmp
->isgd
&& x
== 0 && y
== 0))
91 impossible("mon (%s) claims to be at <%d,%d>?",
92 fmt_ptr((genericptr_t
) mtmp
), x
, y
);
93 else if (level
.monsters
[x
][y
] != mtmp
)
94 impossible("mon (%s) at <%d,%d> is not there!",
95 fmt_ptr((genericptr_t
) mtmp
), x
, y
);
98 for (x
= 0; x
< COLNO
; x
++)
99 for (y
= 0; y
< ROWNO
; y
++)
100 if ((mtmp
= level
.monsters
[x
][y
]) != 0) {
101 for (m
= fmon
; m
; m
= m
->nmon
)
105 impossible("map mon (%s) at <%d,%d> not in fmon list!",
106 fmt_ptr((genericptr_t
) mtmp
), x
, y
);
107 else if ((mtmp
->mx
!= x
|| mtmp
->my
!= y
)
108 && mtmp
->data
!= &mons
[PM_LONG_WORM
])
109 impossible("map mon (%s) at <%d,%d> is found at <%d,%d>?",
110 fmt_ptr((genericptr_t
) mtmp
),
111 mtmp
->mx
, mtmp
->my
, x
, y
);
114 for (mtmp
= migrating_mons
; mtmp
; mtmp
= mtmp
->nmon
) {
115 sanity_check_single_mon(mtmp
, FALSE
, "migr");
120 /* convert the monster index of an undead to its living counterpart */
122 undead_to_corpse(mndx
)
126 case PM_KOBOLD_ZOMBIE
:
127 case PM_KOBOLD_MUMMY
:
130 case PM_DWARF_ZOMBIE
:
134 case PM_GNOME_ZOMBIE
:
147 case PM_VAMPIRE_LORD
:
149 case PM_VAMPIRE_MAGE
:
151 case PM_HUMAN_ZOMBIE
:
155 case PM_GIANT_ZOMBIE
:
159 case PM_ETTIN_ZOMBIE
:
169 /* Convert the monster index of some monsters (such as quest guardians)
170 * to their generic species type.
172 * Return associated character class monster, rather than species
180 /* Quest guardians */
182 mndx
= mode
? PM_ARCHEOLOGIST
: PM_HUMAN
;
185 mndx
= mode
? PM_BARBARIAN
: PM_HUMAN
;
188 mndx
= mode
? PM_CAVEMAN
: PM_HUMAN
;
191 mndx
= mode
? PM_HEALER
: PM_HUMAN
;
194 mndx
= mode
? PM_KNIGHT
: PM_HUMAN
;
197 mndx
= mode
? PM_MONK
: PM_HUMAN
;
200 mndx
= mode
? PM_PRIEST
: PM_HUMAN
;
203 mndx
= mode
? PM_RANGER
: PM_HUMAN
;
206 mndx
= mode
? PM_ROGUE
: PM_HUMAN
;
209 mndx
= mode
? PM_SAMURAI
: PM_HUMAN
;
212 mndx
= mode
? PM_TOURIST
: PM_HUMAN
;
215 mndx
= mode
? PM_WIZARD
: PM_HUMAN
;
218 mndx
= mode
? PM_VALKYRIE
: PM_HUMAN
;
221 if (mndx
>= LOW_PM
&& mndx
< NUMMONS
) {
222 struct permonst
*ptr
= &mons
[mndx
];
226 else if (is_elf(ptr
))
228 else if (is_dwarf(ptr
))
230 else if (is_gnome(ptr
))
232 else if (is_orc(ptr
))
240 /* return monster index if chameleon, or NON_PM if not */
248 * As of 3.6.0 we just check M2_SHAPESHIFTER instead of having a
249 * big switch statement with hardcoded shapeshifter types here.
251 if (mndx
>= LOW_PM
&& is_shapeshifter(&mons
[mndx
]))
256 /* for deciding whether corpse will carry along full monster data */
257 #define KEEPTRAITS(mon) \
258 ((mon)->isshk || (mon)->mtame || unique_corpstat((mon)->data) \
259 || is_reviver((mon)->data) \
260 /* normally quest leader will be unique, */ \
261 /* but he or she might have been polymorphed */ \
262 || (mon)->m_id == quest_status.leader_m_id \
263 /* special cancellation handling for these */ \
264 || (dmgtype((mon)->data, AD_SEDU) || dmgtype((mon)->data, AD_SSEX)))
266 /* Creates a monster corpse, a "special" corpse, or nothing if it doesn't
267 * leave corpses. Monsters which leave "special" corpses should have
268 * G_NOCORPSE set in order to prevent wishing for one, finding tins of one,
271 STATIC_OVL
struct obj
*
272 make_corpse(mtmp
, corpseflags
)
273 register struct monst
*mtmp
;
274 unsigned corpseflags
;
276 register struct permonst
*mdat
= mtmp
->data
;
278 struct obj
*obj
= (struct obj
*) 0;
279 struct obj
*otmp
= (struct obj
*) 0;
280 int x
= mtmp
->mx
, y
= mtmp
->my
;
281 int mndx
= monsndx(mdat
);
282 unsigned corpstatflags
= corpseflags
;
283 boolean burythem
= ((corpstatflags
& CORPSTAT_BURIED
) != 0);
287 case PM_SILVER_DRAGON
:
289 case PM_SHIMMERING_DRAGON
:
292 case PM_ORANGE_DRAGON
:
293 case PM_WHITE_DRAGON
:
294 case PM_BLACK_DRAGON
:
296 case PM_GREEN_DRAGON
:
297 case PM_YELLOW_DRAGON
:
298 /* Make dragon scales. This assumes that the order of the
299 dragons is the same as the order of the scales. */
300 if (!rn2(mtmp
->mrevived
? 20 : 3)) {
301 num
= GRAY_DRAGON_SCALES
+ monsndx(mdat
) - PM_GRAY_DRAGON
;
302 obj
= mksobj_at(num
, x
, y
, FALSE
, FALSE
);
304 obj
->cursed
= obj
->blessed
= FALSE
;
307 case PM_WHITE_UNICORN
:
308 case PM_GRAY_UNICORN
:
309 case PM_BLACK_UNICORN
:
310 if (mtmp
->mrevived
&& rn2(2)) {
312 pline("%s recently regrown horn crumbles to dust.",
313 s_suffix(Monnam(mtmp
)));
315 obj
= mksobj_at(UNICORN_HORN
, x
, y
, TRUE
, FALSE
);
316 if (obj
&& mtmp
->mrevived
)
317 obj
->degraded_horn
= 1;
321 (void) mksobj_at(WORM_TOOTH
, x
, y
, TRUE
, FALSE
);
324 case PM_VAMPIRE_LORD
:
325 /* include mtmp in the mkcorpstat() call */
326 num
= undead_to_corpse(mndx
);
327 corpstatflags
|= CORPSTAT_INIT
;
328 obj
= mkcorpstat(CORPSE
, mtmp
, &mons
[num
], x
, y
, corpstatflags
);
329 obj
->age
-= 100; /* this is an *OLD* corpse */
331 case PM_KOBOLD_MUMMY
:
339 case PM_KOBOLD_ZOMBIE
:
340 case PM_DWARF_ZOMBIE
:
341 case PM_GNOME_ZOMBIE
:
344 case PM_HUMAN_ZOMBIE
:
345 case PM_GIANT_ZOMBIE
:
346 case PM_ETTIN_ZOMBIE
:
347 num
= undead_to_corpse(mndx
);
348 corpstatflags
|= CORPSTAT_INIT
;
349 obj
= mkcorpstat(CORPSE
, mtmp
, &mons
[num
], x
, y
, corpstatflags
);
350 obj
->age
-= 100; /* this is an *OLD* corpse */
355 obj
= mksobj_at(IRON_CHAIN
, x
, y
, TRUE
, FALSE
);
356 free_mname(mtmp
); /* don't christen obj */
359 num
= d(2, 4); /* very low chance of creating all glass gems */
361 obj
= mksobj_at((LAST_GEM
+ rnd(9)), x
, y
, TRUE
, FALSE
);
365 obj
= mksobj_at(ROCK
, x
, y
, FALSE
, FALSE
);
366 obj
->quan
= (long) (rn2(20) + 50);
367 obj
->owt
= weight(obj
);
371 corpstatflags
&= ~CORPSTAT_INIT
;
373 mkcorpstat(STATUE
, (struct monst
*) 0, mdat
, x
, y
, corpstatflags
);
378 obj
= mksobj_at(QUARTERSTAFF
, x
, y
, TRUE
, FALSE
);
382 case PM_LEATHER_GOLEM
:
385 obj
= mksobj_at(LEATHER_ARMOR
, x
, y
, TRUE
, FALSE
);
389 /* Good luck gives more coins */
390 obj
= mkgold((long) (200 - rnl(101)), x
, y
);
396 obj
= mksobj_at(SCR_BLANK_PAPER
, x
, y
, TRUE
, FALSE
);
399 /* expired puddings will congeal into a large blob;
400 like dragons, relies on the order remaining consistent */
402 case PM_BROWN_PUDDING
:
404 case PM_BLACK_PUDDING
:
405 /* we have to do this here because most other places
406 expect there to be an object coming back; not this one */
407 obj
= mksobj_at(GLOB_OF_BLACK_PUDDING
- (PM_BLACK_PUDDING
- mndx
),
410 while (obj
&& (otmp
= obj_nexto(obj
)) != (struct obj
*) 0) {
411 pudding_merge_message(obj
, otmp
);
412 obj
= obj_meld(&obj
, &otmp
);
418 if (mvitals
[mndx
].mvflags
& G_NOCORPSE
) {
419 return (struct obj
*) 0;
421 corpstatflags
|= CORPSTAT_INIT
;
422 /* preserve the unique traits of some creatures */
423 obj
= mkcorpstat(CORPSE
, KEEPTRAITS(mtmp
) ? mtmp
: 0,
424 mdat
, x
, y
, corpstatflags
);
428 (void) bury_an_obj(obj
, &dealloc
);
430 return dealloc
? (struct obj
*) 0 : obj
;
435 /* All special cases should precede the G_NOCORPSE check */
437 if (!obj
) return NULL
;
439 /* if polymorph or undead turning has killed this monster,
440 prevent the same attack beam from hitting its corpse */
441 if (context
.bypasses
)
445 obj
= oname(obj
, MNAME(mtmp
));
447 /* Avoid "It was hidden under a green mold corpse!"
448 * during Blind combat. An unseen monster referred to as "it"
449 * could be killed and leave a corpse. If a hider then hid
450 * underneath it, you could be told the corpse type of a
451 * monster that you never knew was there without this.
452 * The code in hitmu() substitutes the word "something"
453 * if the corpses obj->dknown is 0.
455 if (Blind
&& !sensemon(mtmp
))
463 /* check mtmp and water/lava for compatibility, 0 (survived), 1 (died) */
466 register struct monst
*mtmp
;
468 boolean inpool
, inlava
, infountain
;
470 /* [what about ceiling clingers?] */
471 inpool
= (is_pool(mtmp
->mx
, mtmp
->my
)
472 && !(is_flyer(mtmp
->data
) || is_floater(mtmp
->data
)));
473 inlava
= (is_lava(mtmp
->mx
, mtmp
->my
)
474 && !(is_flyer(mtmp
->data
) || is_floater(mtmp
->data
)));
475 infountain
= IS_FOUNTAIN(levl
[mtmp
->mx
][mtmp
->my
].typ
);
477 /* Flying and levitation keeps our steed out of the liquid */
478 /* (but not water-walking or swimming) */
479 if (mtmp
== u
.usteed
&& (Flying
|| Levitation
))
482 /* Gremlin multiplying won't go on forever since the hit points
483 * keep going down, and when it gets to 1 hit point the clone
484 * function will fail.
486 if (mtmp
->data
== &mons
[PM_GREMLIN
] && (inpool
|| infountain
) && rn2(3)) {
487 if (split_mon(mtmp
, (struct monst
*) 0))
488 dryup(mtmp
->mx
, mtmp
->my
, FALSE
);
490 water_damage_chain(mtmp
->minvent
, FALSE
);
492 } else if (mtmp
->data
== &mons
[PM_IRON_GOLEM
] && inpool
&& !rn2(5)) {
495 if (cansee(mtmp
->mx
, mtmp
->my
))
496 pline("%s rusts.", Monnam(mtmp
));
498 if (mtmp
->mhpmax
> dam
)
505 water_damage_chain(mtmp
->minvent
, FALSE
);
511 * Lava effects much as water effects. Lava likers are able to
512 * protect their stuff. Fire resistant monsters can only protect
515 if (!is_clinger(mtmp
->data
) && !likes_lava(mtmp
->data
)) {
516 if (!resists_fire(mtmp
)) {
517 if (cansee(mtmp
->mx
, mtmp
->my
)) {
518 struct attack
*dummy
= &mtmp
->data
->mattk
[0];
519 const char *how
= on_fire(mtmp
->data
, dummy
);
521 pline("%s %s.", Monnam(mtmp
),
522 !strcmp(how
, "boiling") ? "boils away"
523 : !strcmp(how
, "melting") ? "melts away"
524 : "burns to a crisp");
530 if (cansee(mtmp
->mx
, mtmp
->my
))
531 pline("%s surrenders to the fire.", Monnam(mtmp
));
533 } else if (cansee(mtmp
->mx
, mtmp
->my
))
534 pline("%s burns slightly.", Monnam(mtmp
));
537 (void) fire_damage_chain(mtmp
->minvent
, FALSE
, FALSE
,
539 (void) rloc(mtmp
, FALSE
);
545 /* Most monsters drown in pools. flooreffects() will take care of
546 * water damage to dead monsters' inventory, but survivors need to
547 * be handled here. Swimmers are able to protect their stuff...
549 if (!is_clinger(mtmp
->data
) && !is_swimmer(mtmp
->data
)
550 && !amphibious(mtmp
->data
)) {
551 if (cansee(mtmp
->mx
, mtmp
->my
)) {
552 pline("%s drowns.", Monnam(mtmp
));
554 if (u
.ustuck
&& u
.uswallow
&& u
.ustuck
== mtmp
) {
555 /* This can happen after a purple worm plucks you off a
556 flying steed while you are over water. */
557 pline("%s sinks as %s rushes in and flushes you out.",
558 Monnam(mtmp
), hliquid("water"));
562 water_damage_chain(mtmp
->minvent
, FALSE
);
563 (void) rloc(mtmp
, FALSE
);
569 /* but eels have a difficult time outside */
570 if (mtmp
->data
->mlet
== S_EEL
&& !Is_waterlevel(&u
.uz
)) {
571 /* as mhp gets lower, the rate of further loss slows down */
572 if (mtmp
->mhp
> 1 && rn2(mtmp
->mhp
) > rn2(8))
574 monflee(mtmp
, 2, FALSE
, FALSE
);
584 int mmove
= mon
->data
->mmove
;
587 /* Note: MSLOW's `+ 1' prevents slowed speed 1 getting reduced to 0;
588 * MFAST's `+ 2' prevents hasted speed 1 from becoming a no-op;
589 * both adjustments have negligible effect on higher speeds.
591 if (mon
->mspeed
== MSLOW
)
592 mmove
= (2 * mmove
+ 1) / 3;
593 else if (mon
->mspeed
== MFAST
)
594 mmove
= (4 * mmove
+ 2) / 3;
596 if (mon
== u
.usteed
&& u
.ugallop
&& context
.mv
) {
597 /* increase movement by a factor of 1.5; also increase variance of
598 movement speed (if it's naturally 24, we don't want it to always
600 mmove
= ((rn2(2) ? 4 : 5) * mmove
) / 3;
603 /* Randomly round the monster's speed to a multiple of NORMAL_SPEED. This
604 makes it impossible for the player to predict when they'll get a free
605 turn (thus preventing exploits like "melee kiting"), while retaining
606 guarantees about shopkeepers not being outsped by a normal-speed player,
607 normal-speed players being unable to open up a gap when fleeing a
608 normal-speed monster, etc.*/
609 mmove_adj
= mmove
% NORMAL_SPEED
;
611 if (rn2(NORMAL_SPEED
) < mmove_adj
)
612 mmove
+= NORMAL_SPEED
;
617 /* actions that happen once per ``turn'', regardless of each
618 individual monster's metabolism; some of these might need to
619 be reclassified to occur more in proportion with movement rate */
625 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
626 if (DEADMONSTER(mtmp
))
629 /* must check non-moving monsters once/turn in case
630 * they managed to end up in liquid */
631 if (mtmp
->data
->mmove
== 0) {
632 if (vision_full_recalc
)
638 /* regenerate hit points */
639 mon_regen(mtmp
, FALSE
);
641 /* possibly polymorph shapechangers and lycanthropes */
642 if (mtmp
->cham
>= LOW_PM
)
643 decide_to_shapeshift(mtmp
, (canspotmon(mtmp
)
644 || (u
.uswallow
&& mtmp
== u
.ustuck
))
648 /* gradually time out temporary problems */
649 if (mtmp
->mblinded
&& !--mtmp
->mblinded
)
651 if (mtmp
->mfrozen
&& !--mtmp
->mfrozen
)
653 if (mtmp
->mfleetim
&& !--mtmp
->mfleetim
)
656 /* FIXME: mtmp->mlstmv ought to be updated here */
663 register struct monst
*mtmp
, *nmtmp
;
664 register boolean somebody_can_move
= FALSE
;
667 * Some of you may remember the former assertion here that
668 * because of deaths and other actions, a simple one-pass
669 * algorithm wasn't possible for movemon. Deaths are no longer
670 * removed to the separate list fdmon; they are simply left in
671 * the chain with hit points <= 0, to be cleaned up at the end
674 * The only other actions which cause monsters to be removed from
675 * the chain are level migrations and losedogs(). I believe losedogs()
676 * is a cleanup routine not associated with monster movements, and
677 * monsters can only affect level migrations on themselves, not others
678 * (hence the fetching of nmon before moving the monster). Currently,
679 * monsters can jump into traps, read cursed scrolls of teleportation,
680 * and drink cursed potions of raise level to change levels. These are
681 * all reflexive at this point. Should one monster be able to level
682 * teleport another, this scheme would have problems.
685 for (mtmp
= fmon
; mtmp
; mtmp
= nmtmp
) {
686 /* end monster movement early if hero is flagged to leave the level */
689 /* or if the program has lost contact with the user */
690 || program_state
.done_hup
693 somebody_can_move
= FALSE
;
697 /* one dead monster needs to perform a move after death:
698 vault guard whose temporary corridor is still on the map */
699 if (mtmp
->isgd
&& !mtmp
->mx
&& mtmp
->mhp
<= 0)
700 (void) gd_move(mtmp
);
701 if (DEADMONSTER(mtmp
))
704 /* Find a monster that we have not treated yet. */
705 if (mtmp
->movement
< NORMAL_SPEED
)
708 mtmp
->movement
-= NORMAL_SPEED
;
709 if (mtmp
->movement
>= NORMAL_SPEED
)
710 somebody_can_move
= TRUE
;
712 if (vision_full_recalc
)
713 vision_recalc(0); /* vision! */
715 /* reset obj bypasses before next monster moves */
716 if (context
.bypasses
)
722 if (is_hider(mtmp
->data
)) {
723 /* unwatched mimics and piercers may hide again [MRS] */
726 if (mtmp
->m_ap_type
== M_AP_FURNITURE
727 || mtmp
->m_ap_type
== M_AP_OBJECT
)
729 if (mtmp
->mundetected
)
731 } else if (mtmp
->data
->mlet
== S_EEL
&& !mtmp
->mundetected
732 && (mtmp
->mflee
|| distu(mtmp
->mx
, mtmp
->my
) > 2)
733 && !canseemon(mtmp
) && !rn2(4)) {
734 /* some eels end up stuck in isolated pools, where they
735 can't--or at least won't--move, so they never reach
736 their post-move chance to re-hide */
741 /* continue if the monster died fighting */
742 if (Conflict
&& !mtmp
->iswiz
&& mtmp
->mcansee
) {
744 * Conflict does not take effect in the first round.
745 * Therefore, A monster when stepping into the area will
746 * get to swing at you.
748 * The call to fightm() must be _last_. The monster might
749 * have died if it returns 1.
751 if (couldsee(mtmp
->mx
, mtmp
->my
)
752 && (distu(mtmp
->mx
, mtmp
->my
) <= BOLT_LIM
* BOLT_LIM
)
754 continue; /* mon might have died */
756 if (dochugw(mtmp
)) /* otherwise just move the monster */
760 if (any_light_source())
761 vision_full_recalc
= 1; /* in case a mon moved with a light source */
762 /* reset obj bypasses after last monster has moved */
763 if (context
.bypasses
)
766 /* remove dead monsters; dead vault guard will be left at <0,0>
767 if temporary corridor out of vault hasn't been removed yet */
770 /* a monster may have levteleported player -dlc */
773 /* changed levels, so these monsters are dormant */
774 somebody_can_move
= FALSE
;
777 return somebody_can_move
;
780 #define mstoning(obj) \
781 (ofood(obj) && (touch_petrifies(&mons[(obj)->corpsenm]) \
782 || (obj)->corpsenm == PM_MEDUSA))
785 * Maybe eat a metallic object (not just gold).
786 * Return value: 0 => nothing happened, 1 => monster ate something,
787 * 2 => monster died (it must have grown into a genocided form, but
788 * that can't happen at present because nothing which eats objects
789 * has young and old forms).
793 register struct monst
*mtmp
;
795 register struct obj
*otmp
;
796 struct permonst
*ptr
;
797 int poly
, grow
, heal
, mstone
;
799 /* If a pet, eating is handled separately, in dog.c */
803 /* Eats topmost metal object if it is there */
804 for (otmp
= level
.objects
[mtmp
->mx
][mtmp
->my
]; otmp
;
805 otmp
= otmp
->nexthere
) {
806 /* Don't eat indigestible/choking/inappropriate objects */
807 if ((mtmp
->data
== &mons
[PM_RUST_MONSTER
] && !is_rustprone(otmp
))
808 || (otmp
->otyp
== AMULET_OF_STRANGULATION
)
809 || (otmp
->otyp
== RIN_SLOW_DIGESTION
))
811 if (is_metallic(otmp
) && !obj_resists(otmp
, 5, 95)
812 && touch_artifact(otmp
, mtmp
)) {
813 if (mtmp
->data
== &mons
[PM_RUST_MONSTER
] && otmp
->oerodeproof
) {
814 if (canseemon(mtmp
) && flags
.verbose
) {
815 pline("%s eats %s!", Monnam(mtmp
),
816 distant_name(otmp
, doname
));
818 /* The object's rustproofing is gone now */
819 otmp
->oerodeproof
= 0;
821 if (canseemon(mtmp
) && flags
.verbose
) {
822 pline("%s spits %s out in disgust!", Monnam(mtmp
),
823 distant_name(otmp
, doname
));
826 if (cansee(mtmp
->mx
, mtmp
->my
) && flags
.verbose
)
827 pline("%s eats %s!", Monnam(mtmp
),
828 distant_name(otmp
, doname
));
829 else if (flags
.verbose
)
830 You_hear("a crunching sound.");
831 mtmp
->meating
= otmp
->owt
/ 2 + 1;
832 /* Heal up to the object's weight in hp */
833 if (mtmp
->mhp
< mtmp
->mhpmax
) {
834 mtmp
->mhp
+= objects
[otmp
->otyp
].oc_weight
;
835 if (mtmp
->mhp
> mtmp
->mhpmax
)
836 mtmp
->mhp
= mtmp
->mhpmax
;
841 } else if (otmp
== uchain
) {
842 unpunish(); /* frees uchain */
844 poly
= polyfodder(otmp
);
845 grow
= mlevelgain(otmp
);
846 heal
= mhealup(otmp
);
847 mstone
= mstoning(otmp
);
851 if (newcham(mtmp
, (struct permonst
*) 0, FALSE
, FALSE
))
854 ptr
= grow_up(mtmp
, (struct monst
*) 0);
856 if (poly_when_stoned(ptr
)) {
859 } else if (!resists_ston(mtmp
)) {
861 pline("%s turns to stone!", Monnam(mtmp
));
863 ptr
= (struct permonst
*) 0;
866 mtmp
->mhp
= mtmp
->mhpmax
;
869 return 2; /* it died */
871 /* Left behind a pile? */
873 (void) mksobj_at(ROCK
, mtmp
->mx
, mtmp
->my
, TRUE
, FALSE
);
874 newsym(mtmp
->mx
, mtmp
->my
);
882 /* monster eats a pile of objects */
884 meatobj(mtmp
) /* for gelatinous cubes */
887 register struct obj
*otmp
, *otmp2
;
888 struct permonst
*ptr
, *original_ptr
= mtmp
->data
;
889 int poly
, grow
, heal
, count
= 0, ecount
= 0;
893 /* If a pet, eating is handled separately, in dog.c */
897 /* eat organic objects, including cloth and wood, if present;
898 engulf others, except huge rocks and metal attached to player
899 [despite comment at top, doesn't assume that eater is a g.cube] */
900 for (otmp
= level
.objects
[mtmp
->mx
][mtmp
->my
]; otmp
; otmp
= otmp2
) {
901 otmp2
= otmp
->nexthere
;
903 /* touch sensitive items */
904 if (otmp
->otyp
== CORPSE
&& is_rider(&mons
[otmp
->corpsenm
])) {
905 /* Rider corpse isn't just inedible; can't engulf it either */
906 (void) revive_corpse(otmp
);
908 /* untouchable (or inaccessible) items */
909 } else if ((otmp
->otyp
== CORPSE
910 && touch_petrifies(&mons
[otmp
->corpsenm
])
911 && !resists_ston(mtmp
))
912 /* don't engulf boulders and statues or ball&chain */
913 || otmp
->oclass
== ROCK_CLASS
914 || otmp
== uball
|| otmp
== uchain
915 /* normally mtmp won't have stepped onto scare monster
916 scroll, but if it does, don't eat or engulf that
917 (note: scrolls inside eaten containers will still
919 || otmp
->otyp
== SCR_SCARE_MONSTER
) {
920 /* do nothing--neither eaten nor engulfed */
923 /* inedible items -- engulf these */
924 } else if (!is_organic(otmp
) || obj_resists(otmp
, 5, 95)
925 || !touch_artifact(otmp
, mtmp
)
926 /* redundant due to non-organic composition but
927 included for emphasis */
928 || (otmp
->otyp
== AMULET_OF_STRANGULATION
929 || otmp
->otyp
== RIN_SLOW_DIGESTION
)
930 /* cockatrice corpses handled above; this
931 touch_petrifies() check catches eggs */
932 || ((otmp
->otyp
== CORPSE
|| otmp
->otyp
== EGG
934 && ((touch_petrifies(&mons
[otmp
->corpsenm
])
935 && !resists_ston(mtmp
))
936 || (otmp
->corpsenm
== PM_GREEN_SLIME
937 && !slimeproof(mtmp
->data
))))) {
941 Sprintf(buf
, "%s engulfs %s.", Monnam(mtmp
),
942 distant_name(otmp
, doname
));
943 else if (ecount
== 2)
944 Sprintf(buf
, "%s engulfs several objects.", Monnam(mtmp
));
945 obj_extract_self(otmp
);
946 (void) mpickobj(mtmp
, otmp
); /* slurp */
948 /* lastly, edible items; yum! */
952 if (cansee(mtmp
->mx
, mtmp
->my
)) {
954 pline("%s eats %s!", Monnam(mtmp
),
955 distant_name(otmp
, doname
));
956 /* give this one even if !verbose */
957 if (otmp
->oclass
== SCROLL_CLASS
958 && !strcmpi(OBJ_DESCR(objects
[otmp
->otyp
]), "YUM YUM"))
959 pline("Yum%c", otmp
->blessed
? '!' : '.');
962 You_hear("a slurping sound.");
964 /* Heal up to the object's weight in hp */
965 if (mtmp
->mhp
< mtmp
->mhpmax
) {
966 mtmp
->mhp
+= objects
[otmp
->otyp
].oc_weight
;
967 if (mtmp
->mhp
> mtmp
->mhpmax
)
968 mtmp
->mhp
= mtmp
->mhpmax
;
970 if (Has_contents(otmp
)) {
971 register struct obj
*otmp3
;
973 /* contents of eaten containers become engulfed; this
974 is arbitrary, but otherwise g.cubes are too powerful */
975 while ((otmp3
= otmp
->cobj
) != 0) {
976 obj_extract_self(otmp3
);
977 if (otmp
->otyp
== ICE_BOX
&& otmp3
->otyp
== CORPSE
) {
978 otmp3
->age
= monstermoves
- otmp3
->age
;
979 start_corpse_timeout(otmp3
);
981 (void) mpickobj(mtmp
, otmp3
);
984 poly
= polyfodder(otmp
);
985 grow
= mlevelgain(otmp
);
986 heal
= mhealup(otmp
);
987 delobj(otmp
); /* munch */
990 if (newcham(mtmp
, (struct permonst
*) 0, FALSE
, FALSE
))
993 ptr
= grow_up(mtmp
, (struct monst
*) 0);
995 mtmp
->mhp
= mtmp
->mhpmax
;
997 /* in case it polymorphed or died */
998 if (ptr
!= original_ptr
)
1002 /* Engulf & devour is instant, so don't set meating */
1004 newsym(mtmp
->mx
, mtmp
->my
);
1008 if (cansee(mtmp
->mx
, mtmp
->my
) && flags
.verbose
&& buf
[0])
1010 else if (flags
.verbose
)
1011 You_hear("%s slurping sound%s.",
1012 (ecount
== 1) ? "a" : "several", plur(ecount
));
1014 return (count
> 0 || ecount
> 0) ? 1 : 0;
1019 register struct monst
*mtmp
;
1021 register struct obj
*gold
;
1024 if ((gold
= g_at(mtmp
->mx
, mtmp
->my
)) != 0) {
1025 mat_idx
= objects
[gold
->otyp
].oc_material
;
1026 obj_extract_self(gold
);
1027 add_to_minv(mtmp
, gold
);
1028 if (cansee(mtmp
->mx
, mtmp
->my
)) {
1029 if (flags
.verbose
&& !mtmp
->isgd
)
1030 pline("%s picks up some %s.", Monnam(mtmp
),
1031 mat_idx
== GOLD
? "gold" : "money");
1032 newsym(mtmp
->mx
, mtmp
->my
);
1038 mpickstuff(mtmp
, str
)
1039 register struct monst
*mtmp
;
1040 register const char *str
;
1042 register struct obj
*otmp
, *otmp2
, *otmp3
;
1045 /* prevent shopkeepers from leaving the door of their shop */
1046 if (mtmp
->isshk
&& inhishop(mtmp
))
1049 for (otmp
= level
.objects
[mtmp
->mx
][mtmp
->my
]; otmp
; otmp
= otmp2
) {
1050 otmp2
= otmp
->nexthere
;
1051 /* Nymphs take everything. Most monsters don't pick up corpses. */
1052 if (!str
? searches_for_item(mtmp
, otmp
)
1053 : !!(index(str
, otmp
->oclass
))) {
1054 if (otmp
->otyp
== CORPSE
&& mtmp
->data
->mlet
!= S_NYMPH
1055 /* let a handful of corpse types thru to can_carry() */
1056 && !touch_petrifies(&mons
[otmp
->corpsenm
])
1057 && otmp
->corpsenm
!= PM_LIZARD
1058 && !acidic(&mons
[otmp
->corpsenm
]))
1060 if (!touch_artifact(otmp
, mtmp
))
1062 carryamt
= can_carry(mtmp
, otmp
);
1065 if (is_pool(mtmp
->mx
, mtmp
->my
))
1067 /* handle cases where the critter can only get some */
1069 if (carryamt
!= otmp
->quan
) {
1070 otmp3
= splitobj(otmp
, carryamt
);
1072 if (cansee(mtmp
->mx
, mtmp
->my
) && flags
.verbose
)
1073 pline("%s picks up %s.", Monnam(mtmp
),
1074 (distu(mtmp
->mx
, mtmp
->my
) <= 5)
1076 : distant_name(otmp3
, doname
));
1077 obj_extract_self(otmp3
); /* remove from floor */
1078 (void) mpickobj(mtmp
, otmp3
); /* may merge and free otmp3 */
1079 m_dowear(mtmp
, FALSE
);
1080 newsym(mtmp
->mx
, mtmp
->my
);
1081 return TRUE
; /* pick only one object */
1094 for (obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
) {
1095 if (obj
->otyp
!= BOULDER
|| !throws_rocks(mtmp
->data
))
1096 curload
+= obj
->owt
;
1108 /* Base monster carrying capacity is equal to human maximum
1109 * carrying capacity, or half human maximum if not strong.
1110 * (for a polymorphed player, the value used would be the
1111 * non-polymorphed carrying capacity instead of max/half max).
1112 * This is then modified by the ratio between the monster weights
1113 * and human weights. Corpseless monsters are given a capacity
1114 * proportional to their size instead of weight.
1116 if (!mtmp
->data
->cwt
)
1117 maxload
= (MAX_CARR_CAP
* (long) mtmp
->data
->msize
) / MZ_HUMAN
;
1118 else if (!strongmonst(mtmp
->data
)
1119 || (strongmonst(mtmp
->data
) && (mtmp
->data
->cwt
> WT_HUMAN
)))
1120 maxload
= (MAX_CARR_CAP
* (long) mtmp
->data
->cwt
) / WT_HUMAN
;
1122 maxload
= MAX_CARR_CAP
; /*strong monsters w/cwt <= WT_HUMAN*/
1124 if (!strongmonst(mtmp
->data
))
1130 return (int) maxload
;
1133 /* for restricting monsters' object-pickup.
1135 * to support the new pet behavior, this now returns the max # of objects
1136 * that a given monster could pick up from a pile. frequently this will be
1137 * otmp->quan, but special cases for 'only one' now exist so.
1139 * this will probably cause very amusing behavior with pets and gold coins.
1141 * TODO: allow picking up 2-N objects from a pile of N based on weight.
1142 * Change from 'int' to 'long' to accomate big stacks of gold.
1143 * Right now we fake it by reporting a partial quantity, but the
1144 * likesgold handling m_move results in picking up the whole stack.
1147 can_carry(mtmp
, otmp
)
1151 int iquan
, otyp
= otmp
->otyp
, newload
= otmp
->owt
;
1152 struct permonst
*mdat
= mtmp
->data
;
1156 return 0; /* can't carry anything */
1158 if (otyp
== CORPSE
&& touch_petrifies(&mons
[otmp
->corpsenm
])
1159 && !(mtmp
->misc_worn_check
& W_ARMG
) && !resists_ston(mtmp
))
1161 if (otyp
== CORPSE
&& is_rider(&mons
[otmp
->corpsenm
]))
1163 if (objects
[otyp
].oc_material
== SILVER
&& mon_hates_silver(mtmp
)
1164 && (otyp
!= BELL_OF_OPENING
|| !is_covetous(mdat
)))
1167 /* hostile monsters who like gold will pick up the whole stack;
1168 tame mosnters with hands will pick up the partial stack */
1169 iquan
= (otmp
->quan
> (long) LARGEST_INT
)
1170 ? 20000 + rn2(LARGEST_INT
- 20000 + 1)
1173 /* monsters without hands can't pick up multiple objects at once
1174 * unless they have an engulfing attack
1176 * ...dragons, of course, can always carry gold pieces and gems somehow
1179 boolean glomper
= FALSE
;
1181 if (mtmp
->data
->mlet
== S_DRAGON
1182 && (otmp
->oclass
== COIN_CLASS
1183 || otmp
->oclass
== GEM_CLASS
))
1186 for (nattk
= 0; nattk
< NATTK
; nattk
++)
1187 if (mtmp
->data
->mattk
[nattk
].aatyp
== AT_ENGL
) {
1191 if ((mtmp
->data
->mflags1
& M1_NOHANDS
) && !glomper
)
1195 /* steeds don't pick up stuff (to avoid shop abuse) */
1196 if (mtmp
== u
.usteed
)
1199 return iquan
; /* no limit */
1200 if (mtmp
->mpeaceful
&& !mtmp
->mtame
)
1202 /* otherwise players might find themselves obligated to violate
1203 * their alignment if the monster takes something they need
1206 /* special--boulder throwers carry unlimited amounts of boulders */
1207 if (throws_rocks(mdat
) && otyp
== BOULDER
)
1210 /* nymphs deal in stolen merchandise, but not boulders or statues */
1211 if (mdat
->mlet
== S_NYMPH
)
1212 return (otmp
->oclass
== ROCK_CLASS
) ? 0 : iquan
;
1214 if (curr_mon_load(mtmp
) + newload
> max_mon_load(mtmp
))
1220 /* return number of acceptable neighbour positions */
1222 mfndpos(mon
, poss
, info
, flag
)
1224 coord
*poss
; /* coord poss[9] */
1225 long *info
; /* long info[9] */
1228 struct permonst
*mdat
= mon
->data
;
1229 register struct trap
*ttmp
;
1234 boolean wantpool
, poolok
, lavaok
, nodiag
;
1235 boolean rockok
= FALSE
, treeok
= FALSE
, thrudoor
;
1237 boolean poisongas_ok
, in_poisongas
;
1239 int gas_glyph
= cmap_to_glyph(S_poisoncloud
);
1243 nowtyp
= levl
[x
][y
].typ
;
1245 nodiag
= NODIAG(mdat
- mons
);
1246 wantpool
= mdat
->mlet
== S_EEL
;
1247 poolok
= (is_flyer(mdat
) || is_clinger(mdat
)
1248 || (is_swimmer(mdat
) && !wantpool
));
1249 lavaok
= (is_flyer(mdat
) || is_clinger(mdat
) || likes_lava(mdat
));
1250 thrudoor
= ((flag
& (ALLOW_WALL
| BUSTDOOR
)) != 0L);
1251 poisongas_ok
= ((nonliving(mdat
) || is_vampshifter(mon
)
1252 || breathless(mdat
)) || resists_poison(mon
));
1253 in_poisongas
= ((gas_reg
= visible_region_at(x
,y
)) != 0
1254 && gas_reg
->glyph
== gas_glyph
);
1256 if (flag
& ALLOW_DIG
) {
1259 /* need to be specific about what can currently be dug */
1260 if (!needspick(mdat
)) {
1261 rockok
= treeok
= TRUE
;
1262 } else if ((mw_tmp
= MON_WEP(mon
)) && mw_tmp
->cursed
1263 && mon
->weapon_check
== NO_WEAPON_WANTED
) {
1264 rockok
= is_pick(mw_tmp
);
1265 treeok
= is_axe(mw_tmp
);
1267 rockok
= (m_carrying(mon
, PICK_AXE
)
1268 || (m_carrying(mon
, DWARVISH_MATTOCK
)
1269 && !which_armor(mon
, W_ARMS
)));
1270 treeok
= (m_carrying(mon
, AXE
) || (m_carrying(mon
, BATTLE_AXE
)
1271 && !which_armor(mon
, W_ARMS
)));
1273 if (rockok
|| treeok
)
1277 nexttry
: /* eels prefer the water, but if there is no water nearby,
1278 they will crawl over land */
1285 maxx
= min(x
+ 1, COLNO
- 1);
1286 maxy
= min(y
+ 1, ROWNO
- 1);
1287 for (nx
= max(1, x
- 1); nx
<= maxx
; nx
++)
1288 for (ny
= max(0, y
- 1); ny
<= maxy
; ny
++) {
1289 if (nx
== x
&& ny
== y
)
1291 ntyp
= levl
[nx
][ny
].typ
;
1293 && !((flag
& ALLOW_WALL
) && may_passwall(nx
, ny
))
1294 && !((IS_TREE(ntyp
) ? treeok
: rockok
) && may_dig(nx
, ny
)))
1296 /* KMH -- Added iron bars */
1297 if (ntyp
== IRONBARS
&& !(flag
& ALLOW_BARS
))
1299 if (IS_DOOR(ntyp
) && !(amorphous(mdat
) || can_fog(mon
))
1300 && (((levl
[nx
][ny
].doormask
& D_CLOSED
) && !(flag
& OPENDOOR
))
1301 || ((levl
[nx
][ny
].doormask
& D_LOCKED
)
1302 && !(flag
& UNLOCKDOOR
))) && !thrudoor
)
1304 /* avoid poison gas? */
1305 if (!poisongas_ok
&& !in_poisongas
1306 && (gas_reg
= visible_region_at(nx
,ny
)) != 0
1307 && gas_reg
->glyph
== gas_glyph
)
1309 /* first diagonal checks (tight squeezes handled below) */
1310 if (nx
!= x
&& ny
!= y
1312 || (IS_DOOR(nowtyp
) && (levl
[x
][y
].doormask
& ~D_BROKEN
))
1313 || (IS_DOOR(ntyp
) && (levl
[nx
][ny
].doormask
& ~D_BROKEN
))
1314 || ((IS_DOOR(nowtyp
) || IS_DOOR(ntyp
))
1315 && Is_rogue_level(&u
.uz
))
1316 /* mustn't pass between adjacent long worm segments,
1317 but can attack that way */
1318 || (m_at(x
, ny
) && m_at(nx
, y
) && worm_cross(x
, y
, nx
, ny
)
1319 && !m_at(nx
, ny
) && (nx
!= u
.ux
|| ny
!= u
.uy
))))
1321 if ((is_pool(nx
, ny
) == wantpool
|| poolok
)
1322 && (lavaok
|| !is_lava(nx
, ny
))) {
1324 boolean monseeu
= (mon
->mcansee
1325 && (!Invis
|| perceives(mdat
)));
1326 boolean checkobj
= OBJ_AT(nx
, ny
);
1328 /* Displacement also displaces the Elbereth/scare monster,
1329 * as long as you are visible.
1331 if (Displaced
&& monseeu
&& mon
->mux
== nx
&& mon
->muy
== ny
) {
1340 if (onscary(dispx
, dispy
, mon
)) {
1341 if (!(flag
& ALLOW_SSM
))
1343 info
[cnt
] |= ALLOW_SSM
;
1345 if ((nx
== u
.ux
&& ny
== u
.uy
)
1346 || (nx
== mon
->mux
&& ny
== mon
->muy
)) {
1347 if (nx
== u
.ux
&& ny
== u
.uy
) {
1348 /* If it's right next to you, it found you,
1349 * displaced or no. We must set mux and muy
1350 * right now, so when we return we can tell
1351 * that the ALLOW_U means to attack _you_ and
1357 if (!(flag
& ALLOW_U
))
1359 info
[cnt
] |= ALLOW_U
;
1361 if (MON_AT(nx
, ny
)) {
1362 struct monst
*mtmp2
= m_at(nx
, ny
);
1363 long mmflag
= flag
| mm_aggression(mon
, mtmp2
);
1365 if (mmflag
& ALLOW_M
) {
1366 info
[cnt
] |= ALLOW_M
;
1368 if (!(mmflag
& ALLOW_TM
))
1370 info
[cnt
] |= ALLOW_TM
;
1373 mmflag
= flag
| mm_displacement(mon
, mtmp2
);
1374 if (!(mmflag
& ALLOW_MDISP
))
1376 info
[cnt
] |= ALLOW_MDISP
;
1379 /* Note: ALLOW_SANCT only prevents movement, not
1380 attack, into a temple. */
1381 if (level
.flags
.has_temple
&& *in_rooms(nx
, ny
, TEMPLE
)
1382 && !*in_rooms(x
, y
, TEMPLE
)
1383 && in_your_sanctuary((struct monst
*) 0, nx
, ny
)) {
1384 if (!(flag
& ALLOW_SANCT
))
1386 info
[cnt
] |= ALLOW_SANCT
;
1389 if (checkobj
&& sobj_at(CLOVE_OF_GARLIC
, nx
, ny
)) {
1390 if (flag
& NOGARLIC
)
1392 info
[cnt
] |= NOGARLIC
;
1394 if (checkobj
&& sobj_at(BOULDER
, nx
, ny
)) {
1395 if (!(flag
& ALLOW_ROCK
))
1397 info
[cnt
] |= ALLOW_ROCK
;
1399 if (monseeu
&& onlineu(nx
, ny
)) {
1402 info
[cnt
] |= NOTONL
;
1404 /* check for diagonal tight squeeze */
1405 if (nx
!= x
&& ny
!= y
&& bad_rock(mdat
, x
, ny
)
1406 && bad_rock(mdat
, nx
, y
) && cant_squeeze_thru(mon
))
1408 /* The monster avoids a particular type of trap if it's
1409 * familiar with the trap type. Pets get ALLOW_TRAPS
1410 * and checking is done in dogmove.c. In either case,
1411 * "harmless" traps are neither avoided nor marked in info[].
1413 if ((ttmp
= t_at(nx
, ny
)) != 0) {
1414 if (ttmp
->ttyp
>= TRAPNUM
|| ttmp
->ttyp
== 0) {
1416 "A monster looked at a very strange trap of type %d.",
1420 if ((ttmp
->ttyp
!= RUST_TRAP
1421 || mdat
== &mons
[PM_IRON_GOLEM
])
1422 && ttmp
->ttyp
!= STATUE_TRAP
1423 && ((ttmp
->ttyp
!= PIT
&& ttmp
->ttyp
!= SPIKED_PIT
1424 && ttmp
->ttyp
!= TRAPDOOR
&& ttmp
->ttyp
!= HOLE
)
1425 || (!is_flyer(mdat
) && !is_floater(mdat
)
1426 && !is_clinger(mdat
)) || Sokoban
)
1427 && (ttmp
->ttyp
!= SLP_GAS_TRAP
|| !resists_sleep(mon
))
1428 && (ttmp
->ttyp
!= BEAR_TRAP
1429 || (mdat
->msize
> MZ_SMALL
&& !amorphous(mdat
)
1430 && !is_flyer(mdat
) && !is_floater(mdat
)
1431 && !is_whirly(mdat
) && !unsolid(mdat
)))
1432 && (ttmp
->ttyp
!= FIRE_TRAP
|| !resists_fire(mon
))
1433 && (ttmp
->ttyp
!= SQKY_BOARD
|| !is_flyer(mdat
))
1434 && (ttmp
->ttyp
!= WEB
1435 || (!amorphous(mdat
) && !webmaker(mdat
)
1436 && !is_whirly(mdat
) && !unsolid(mdat
)))
1437 && (ttmp
->ttyp
!= ANTI_MAGIC
|| !resists_magm(mon
))) {
1438 if (!(flag
& ALLOW_TRAPS
)) {
1439 if (mon
->mtrapseen
& (1L << (ttmp
->ttyp
- 1)))
1442 info
[cnt
] |= ALLOW_TRAPS
;
1450 if (!cnt
&& wantpool
&& !is_pool(x
, y
)) {
1457 /* Monster against monster special attacks; for the specified monster
1458 combinations, this allows one monster to attack another adjacent one
1459 in the absence of Conflict. There is no provision for targetting
1460 other monsters; just hand to hand fighting when they happen to be
1461 next to each other. */
1463 mm_aggression(magr
, mdef
)
1464 struct monst
*magr
, /* monster that is currently deciding where to move */
1465 *mdef
; /* another monster which is next to it */
1467 /* supposedly purple worms are attracted to shrieking because they
1468 like to eat shriekers, so attack the latter when feasible */
1469 if (magr
->data
== &mons
[PM_PURPLE_WORM
]
1470 && mdef
->data
== &mons
[PM_SHRIEKER
])
1471 return ALLOW_M
| ALLOW_TM
;
1472 /* Various other combinations such as dog vs cat, cat vs rat, and
1473 elf vs orc have been suggested. For the time being we don't
1478 /* Monster displacing another monster out of the way */
1480 mm_displacement(magr
, mdef
)
1481 struct monst
*magr
, /* monster that is currently deciding where to move */
1482 *mdef
; /* another monster which is next to it */
1484 struct permonst
*pa
= magr
->data
, *pd
= mdef
->data
;
1486 /* if attacker can't barge through, there's nothing to do;
1487 or if defender can barge through too, don't let attacker
1488 do so, otherwise they might just end up swapping places
1489 again when defender gets its chance to move */
1490 if ((pa
->mflags3
& M3_DISPLACES
) != 0 && (pd
->mflags3
& M3_DISPLACES
) == 0
1491 /* no displacing grid bugs diagonally */
1492 && !(magr
->mx
!= mdef
->mx
&& magr
->my
!= mdef
->my
1493 && NODIAG(monsndx(pd
)))
1494 /* no displacing trapped monsters or multi-location longworms */
1495 && !mdef
->mtrapped
&& (!mdef
->wormno
|| !count_wsegs(mdef
))
1496 /* riders can move anything; others, same size or smaller only */
1497 && (is_rider(pa
) || pa
->msize
>= pd
->msize
))
1502 /* Is the square close enough for the monster to move or attack into? */
1508 int distance
= dist2(mon
->mx
, mon
->my
, x
, y
);
1510 if (distance
== 2 && NODIAG(mon
->data
- mons
))
1512 return (boolean
) (distance
< 3);
1515 /* really free dead monsters */
1519 struct monst
**mtmp
, *freetmp
;
1522 for (mtmp
= &fmon
; *mtmp
;) {
1524 if (freetmp
->mhp
<= 0 && !freetmp
->isgd
) {
1525 *mtmp
= freetmp
->nmon
;
1526 freetmp
->nmon
= NULL
;
1527 dealloc_monst(freetmp
);
1530 mtmp
= &(freetmp
->nmon
);
1533 if (count
!= iflags
.purge_monsters
)
1534 impossible("dmonsfree: %d removed doesn't match %d pending",
1535 count
, iflags
.purge_monsters
);
1536 iflags
.purge_monsters
= 0;
1539 /* called when monster is moved to larger structure */
1541 replmon(mtmp
, mtmp2
)
1542 struct monst
*mtmp
, *mtmp2
;
1546 /* transfer the monster's inventory */
1547 for (otmp
= mtmp2
->minvent
; otmp
; otmp
= otmp
->nobj
) {
1548 if (otmp
->where
!= OBJ_MINVENT
|| otmp
->ocarry
!= mtmp
)
1549 impossible("replmon: minvent inconsistency");
1550 otmp
->ocarry
= mtmp2
;
1554 /* remove the old monster from the map and from `fmon' list */
1555 relmon(mtmp
, (struct monst
**) 0);
1557 /* finish adding its replacement */
1558 if (mtmp
!= u
.usteed
) /* don't place steed onto the map */
1559 place_monster(mtmp2
, mtmp2
->mx
, mtmp2
->my
);
1560 if (mtmp2
->wormno
) /* update level.monsters[wseg->wx][wseg->wy] */
1561 place_wsegs(mtmp2
); /* locations to mtmp2 not mtmp. */
1562 if (emits_light(mtmp2
->data
)) {
1563 /* since this is so rare, we don't have any `mon_move_light_source' */
1564 new_light_source(mtmp2
->mx
, mtmp2
->my
, emits_light(mtmp2
->data
),
1565 LS_MONSTER
, monst_to_any(mtmp2
));
1566 /* here we rely on fact that `mtmp' hasn't actually been deleted */
1567 del_light_source(LS_MONSTER
, monst_to_any(mtmp
));
1571 if (u
.ustuck
== mtmp
)
1573 if (u
.usteed
== mtmp
)
1576 replshk(mtmp
, mtmp2
);
1578 /* discard the old monster */
1579 dealloc_monst(mtmp
);
1582 /* release mon from the display and the map's monster list,
1583 maybe transfer it to one of the other monster lists */
1585 relmon(mon
, monst_list
)
1587 struct monst
**monst_list
; /* &migrating_mons or &mydogs or null */
1590 boolean unhide
= (monst_list
!= 0);
1591 int mx
= mon
->mx
, my
= mon
->my
;
1594 panic("relmon: no fmon available.");
1597 /* can't remain hidden across level changes (exception: wizard
1598 clone can continue imitating some other monster form); also,
1599 might be imitating a boulder so need line-of-sight unblocking */
1600 mon
->mundetected
= 0;
1601 if (mon
->m_ap_type
&& mon
->m_ap_type
!= M_AP_MONSTER
)
1608 remove_monster(mx
, my
);
1613 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
1614 if (mtmp
->nmon
== mon
)
1618 mtmp
->nmon
= mon
->nmon
;
1620 panic("relmon: mon not in list.");
1625 /* insert into mydogs or migrating_mons */
1626 mon
->nmon
= *monst_list
;
1629 /* orphan has no next monster */
1635 copy_mextra(mtmp2
, mtmp1
)
1636 struct monst
*mtmp2
, *mtmp1
;
1638 if (!mtmp2
|| !mtmp1
|| !mtmp1
->mextra
)
1642 mtmp2
->mextra
= newmextra();
1644 new_mname(mtmp2
, (int) strlen(MNAME(mtmp1
)) + 1);
1645 Strcpy(MNAME(mtmp2
), MNAME(mtmp1
));
1650 *EGD(mtmp2
) = *EGD(mtmp1
);
1655 *EPRI(mtmp2
) = *EPRI(mtmp1
);
1660 *ESHK(mtmp2
) = *ESHK(mtmp1
);
1665 *EMIN(mtmp2
) = *EMIN(mtmp1
);
1670 *EDOG(mtmp2
) = *EDOG(mtmp1
);
1672 if (has_mcorpsenm(mtmp1
))
1673 MCORPSENM(mtmp2
) = MCORPSENM(mtmp1
);
1680 struct mextra
*x
= m
->mextra
;
1684 free((genericptr_t
) x
->mname
);
1686 free((genericptr_t
) x
->egd
);
1688 free((genericptr_t
) x
->epri
);
1690 free((genericptr_t
) x
->eshk
);
1692 free((genericptr_t
) x
->emin
);
1694 free((genericptr_t
) x
->edog
);
1695 /* [no action needed for x->mcorpsenm] */
1697 free((genericptr_t
) x
);
1698 m
->mextra
= (struct mextra
*) 0;
1707 panic("dealloc_monst with nmon");
1709 dealloc_mextra(mon
);
1710 free((genericptr_t
) mon
);
1713 /* remove effects of mtmp from other data structures */
1715 m_detach(mtmp
, mptr
)
1717 struct permonst
*mptr
; /* reflects mtmp->data _prior_ to mtmp's death */
1719 if (mtmp
== context
.polearm
.hitmon
)
1720 context
.polearm
.hitmon
= 0;
1722 m_unleash(mtmp
, FALSE
);
1723 /* to prevent an infinite relobj-flooreffects-hmon-killed loop */
1725 mtmp
->mhp
= 0; /* simplify some tests: force mhp to 0 */
1726 relobj(mtmp
, 0, FALSE
);
1727 remove_monster(mtmp
->mx
, mtmp
->my
);
1728 if (emits_light(mptr
))
1729 del_light_source(LS_MONSTER
, monst_to_any(mtmp
));
1730 if (mtmp
->m_ap_type
)
1732 newsym(mtmp
->mx
, mtmp
->my
);
1734 fill_pit(mtmp
->mx
, mtmp
->my
);
1740 iflags
.purge_monsters
++;
1743 /* find the worn amulet of life saving which will save a monster */
1748 if (!nonliving(mon
->data
) || is_vampshifter(mon
)) {
1749 struct obj
*otmp
= which_armor(mon
, W_AMUL
);
1751 if (otmp
&& otmp
->otyp
== AMULET_OF_LIFE_SAVING
)
1754 return (struct obj
*) 0;
1758 lifesaved_monster(mtmp
)
1762 struct obj
*lifesave
= mlifesaver(mtmp
);
1765 /* not canseemon; amulets are on the head, so you don't want
1766 * to show this for a long worm with only a tail visible.
1767 * Nor do you check invisibility, because glowing and
1768 * disintegrating amulets are always visible. */
1769 if (cansee(mtmp
->mx
, mtmp
->my
)) {
1770 pline("But wait...");
1771 pline("%s medallion begins to glow!", s_suffix(Monnam(mtmp
)));
1772 makeknown(AMULET_OF_LIFE_SAVING
);
1773 /* amulet is visible, but monster might not be */
1774 if (canseemon(mtmp
)) {
1775 if (attacktype(mtmp
->data
, AT_EXPL
)
1776 || attacktype(mtmp
->data
, AT_BOOM
))
1777 pline("%s reconstitutes!", Monnam(mtmp
));
1779 pline("%s looks much better!", Monnam(mtmp
));
1781 pline_The("medallion crumbles to dust!");
1783 m_useup(mtmp
, lifesave
);
1785 surviver
= !(mvitals
[monsndx(mtmp
->data
)].mvflags
& G_GENOD
);
1788 if (mtmp
->mtame
&& !mtmp
->isminion
) {
1789 wary_dog(mtmp
, !surviver
);
1791 if (mtmp
->mhpmax
<= 0)
1793 mtmp
->mhp
= mtmp
->mhpmax
;
1797 /* genocided monster can't be life-saved */
1798 if (cansee(mtmp
->mx
, mtmp
->my
))
1799 pline("Unfortunately, %s is still genocided...", mon_nam(mtmp
));
1806 register struct monst
*mtmp
;
1808 struct permonst
*mptr
;
1811 mtmp
->mhp
= 0; /* in case caller hasn't done this */
1812 lifesaved_monster(mtmp
);
1816 if (is_vampshifter(mtmp
)) {
1817 int mndx
= mtmp
->cham
;
1818 int x
= mtmp
->mx
, y
= mtmp
->my
;
1820 /* this only happens if shapeshifted */
1821 if (mndx
>= LOW_PM
&& mndx
!= monsndx(mtmp
->data
)
1822 && !(mvitals
[mndx
].mvflags
& G_GENOD
)) {
1824 boolean in_door
= (amorphous(mtmp
->data
)
1825 && closed_door(mtmp
->mx
, mtmp
->my
)),
1826 /* alternate message phrasing for some monster types */
1827 spec_mon
= (nonliving(mtmp
->data
)
1828 || noncorporeal(mtmp
->data
)
1829 || amorphous(mtmp
->data
));
1831 /* construct a format string before transformation */
1832 Sprintf(buf
, "The %s%s suddenly %s and rises as %%s!",
1833 spec_mon
? "" : "seemingly dead ",
1834 x_monnam(mtmp
, ARTICLE_NONE
, (char *) 0,
1835 SUPPRESS_SADDLE
| SUPPRESS_HALLUCINATION
1836 | SUPPRESS_INVISIBLE
| SUPPRESS_IT
,
1838 spec_mon
? "reconstitutes" : "transforms");
1841 if (mtmp
->mhpmax
<= 0)
1843 mtmp
->mhp
= mtmp
->mhpmax
;
1844 /* this can happen if previously a fog cloud */
1845 if (u
.uswallow
&& (mtmp
== u
.ustuck
))
1846 expels(mtmp
, mtmp
->data
, FALSE
);
1850 if (enexto(&new_xy
, mtmp
->mx
, mtmp
->my
, &mons
[mndx
])) {
1851 rloc_to(mtmp
, new_xy
.x
, new_xy
.y
);
1854 newcham(mtmp
, &mons
[mndx
], FALSE
, FALSE
);
1855 if (mtmp
->data
== &mons
[mndx
])
1856 mtmp
->cham
= NON_PM
;
1859 if (canspotmon(mtmp
)) {
1860 pline(buf
, a_monnam(mtmp
));
1861 vamp_rise_msg
= TRUE
;
1868 /* dead vault guard is actually kept at coordinate <0,0> until
1869 his temporary corridor to/from the vault has been removed;
1870 need to do this after life-saving and before m_detach() */
1871 if (mtmp
->isgd
&& !grddead(mtmp
))
1874 /* Player is thrown from his steed when it dies */
1875 if (mtmp
== u
.usteed
)
1876 dismount_steed(DISMOUNT_GENERIC
);
1878 mptr
= mtmp
->data
; /* save this for m_detach() */
1879 /* restore chameleon, lycanthropes to true form at death */
1880 if (mtmp
->cham
>= LOW_PM
) {
1881 set_mon_data(mtmp
, &mons
[mtmp
->cham
], -1);
1882 mtmp
->cham
= NON_PM
;
1883 } else if (mtmp
->data
== &mons
[PM_WEREJACKAL
])
1884 set_mon_data(mtmp
, &mons
[PM_HUMAN_WEREJACKAL
], -1);
1885 else if (mtmp
->data
== &mons
[PM_WEREWOLF
])
1886 set_mon_data(mtmp
, &mons
[PM_HUMAN_WEREWOLF
], -1);
1887 else if (mtmp
->data
== &mons
[PM_WERERAT
])
1888 set_mon_data(mtmp
, &mons
[PM_HUMAN_WERERAT
], -1);
1890 /* if MAXMONNO monsters of a given type have died, and it
1891 * can be done, extinguish that monster.
1893 * mvitals[].died does double duty as total number of dead monsters
1894 * and as experience factor for the player killing more monsters.
1895 * this means that a dragon dying by other means reduces the
1896 * experience the player gets for killing a dragon directly; this
1897 * is probably not too bad, since the player likely finagled the
1898 * first dead dragon via ring of conflict or pets, and extinguishing
1899 * based on only player kills probably opens more avenues of abuse
1900 * for rings of conflict and such.
1902 tmp
= monsndx(mtmp
->data
);
1903 if (mvitals
[tmp
].died
< 255)
1904 mvitals
[tmp
].died
++;
1906 /* if it's a (possibly polymorphed) quest leader, mark him as dead */
1907 if (mtmp
->m_id
== quest_status
.leader_m_id
)
1908 quest_status
.leader_is_dead
= TRUE
;
1910 /* if the mail daemon dies, no more mail delivery. -3. */
1911 if (tmp
== PM_MAIL_DAEMON
)
1912 mvitals
[tmp
].mvflags
|= G_GENOD
;
1915 if (mtmp
->data
->mlet
== S_KOP
) {
1916 /* Dead Kops may come back. */
1918 case 1: /* returns near the stairs */
1919 (void) makemon(mtmp
->data
, xdnstair
, ydnstair
, NO_MM_FLAGS
);
1921 case 2: /* randomly */
1922 (void) makemon(mtmp
->data
, 0, 0, NO_MM_FLAGS
);
1930 if (mtmp
->data
->msound
== MS_NEMESIS
)
1932 if (mtmp
->data
== &mons
[PM_MEDUSA
])
1933 u
.uachieve
.killed_medusa
= 1;
1934 if (glyph_is_invisible(levl
[mtmp
->mx
][mtmp
->my
].glyph
))
1935 unmap_object(mtmp
->mx
, mtmp
->my
);
1936 m_detach(mtmp
, mptr
);
1939 /* TRUE if corpse might be dropped, magr may die if mon was swallowed */
1941 corpse_chance(mon
, magr
, was_swallowed
)
1943 struct monst
*magr
; /* killer, if swallowed */
1944 boolean was_swallowed
; /* digestion */
1946 struct permonst
*mdat
= mon
->data
;
1949 if (mdat
== &mons
[PM_VLAD_THE_IMPALER
] || mdat
->mlet
== S_LICH
) {
1950 if (cansee(mon
->mx
, mon
->my
) && !was_swallowed
)
1951 pline("%s body crumbles into dust.", s_suffix(Monnam(mon
)));
1955 /* Gas spores always explode upon death */
1956 for (i
= 0; i
< NATTK
; i
++) {
1957 if (mdat
->mattk
[i
].aatyp
== AT_BOOM
) {
1958 if (mdat
->mattk
[i
].damn
)
1959 tmp
= d((int) mdat
->mattk
[i
].damn
, (int) mdat
->mattk
[i
].damd
);
1960 else if (mdat
->mattk
[i
].damd
)
1961 tmp
= d((int) mdat
->mlevel
+ 1, (int) mdat
->mattk
[i
].damd
);
1964 if (was_swallowed
&& magr
) {
1965 if (magr
== &youmonst
) {
1966 There("is an explosion in your %s!", body_part(STOMACH
));
1967 Sprintf(killer
.name
, "%s explosion",
1968 s_suffix(mdat
->mname
));
1969 losehp(Maybe_Half_Phys(tmp
), killer
.name
, KILLED_BY_AN
);
1971 You_hear("an explosion.");
1975 if (magr
->mhp
< 1) { /* maybe lifesaved */
1976 if (canspotmon(magr
))
1977 pline("%s rips open!", Monnam(magr
));
1978 } else if (canseemon(magr
))
1979 pline("%s seems to have indigestion.", Monnam(magr
));
1985 Sprintf(killer
.name
, "%s explosion", s_suffix(mdat
->mname
));
1986 killer
.format
= KILLED_BY_AN
;
1987 explode(mon
->mx
, mon
->my
, -1, tmp
, MON_EXPLODE
, EXPL_NOXIOUS
);
1992 /* must duplicate this below check in xkilled() since it results in
1993 * creating no objects as well as no corpse
1995 if (LEVEL_SPECIFIC_NOCORPSE(mdat
))
1998 if (((bigmonst(mdat
) || mdat
== &mons
[PM_LIZARD
]) && !mon
->mcloned
)
1999 || is_golem(mdat
) || is_mplayer(mdat
) || is_rider(mdat
) || mon
->isshk
)
2001 tmp
= 2 + ((mdat
->geno
& G_FREQ
) < 2) + verysmall(mdat
);
2002 return (boolean
) !rn2(tmp
);
2005 /* drop (perhaps) a cadaver and remove monster */
2008 register struct monst
*mdef
;
2012 return; /* lifesaved */
2014 if (corpse_chance(mdef
, (struct monst
*) 0, FALSE
)
2015 && (accessible(mdef
->mx
, mdef
->my
) || is_pool(mdef
->mx
, mdef
->my
)))
2016 (void) make_corpse(mdef
, CORPSTAT_NONE
);
2019 /* monster disappears, not dies */
2024 mdef
->mhp
= 0; /* can skip some inventory bookkeeping */
2026 /* dead vault guard is actually kept at coordinate <0,0> until
2027 his temporary corridor to/from the vault has been removed */
2028 if (mdef
->isgd
&& !grddead(mdef
))
2030 /* hero is thrown from his steed when it disappears */
2031 if (mdef
== u
.usteed
)
2032 dismount_steed(DISMOUNT_GENERIC
);
2033 /* stuck to you? release */
2035 /* drop special items like the Amulet so that a dismissed Kop or nurse
2036 can't remove them from the game */
2037 mdrop_special_objs(mdef
);
2038 /* release rest of monster's inventory--it is removed from game */
2039 discard_minvent(mdef
);
2040 m_detach(mdef
, mdef
->data
);
2043 /* drop a statue or rock and remove monster */
2048 struct obj
*otmp
, *obj
, *oldminvent
;
2049 xchar x
= mdef
->mx
, y
= mdef
->my
;
2050 boolean wasinside
= FALSE
;
2052 if (!vamp_stone(mdef
)) /* vampshifter reverts to vampire */
2055 /* we have to make the statue before calling mondead, to be able to
2056 * put inventory in it, and we have to check for lifesaving before
2057 * making the statue....
2059 mdef
->mhp
= 0; /* in case caller hasn't done this */
2060 lifesaved_monster(mdef
);
2064 mdef
->mtrapped
= 0; /* (see m_detach) */
2066 if ((int) mdef
->data
->msize
> MZ_TINY
2067 || !rn2(2 + ((int) (mdef
->data
->geno
& G_FREQ
) > 2))) {
2069 /* some objects may end up outside the statue */
2070 while ((obj
= mdef
->minvent
) != 0) {
2071 obj_extract_self(obj
);
2073 update_mon_intrinsics(mdef
, obj
, FALSE
, TRUE
);
2074 obj_no_longer_held(obj
);
2075 if (obj
->owornmask
& W_WEP
)
2076 setmnotwielded(mdef
, obj
);
2077 obj
->owornmask
= 0L;
2078 if (obj
->otyp
== BOULDER
2079 #if 0 /* monsters don't carry statues */
2080 || (obj
->otyp
== STATUE
2081 && mons
[obj
->corpsenm
].msize
>= mdef
->data
->msize
)
2083 /* invocation tools resist even with 0% resistance */
2084 || obj_resists(obj
, 0, 0)) {
2085 if (flooreffects(obj
, x
, y
, "fall"))
2087 place_object(obj
, x
, y
);
2090 end_burn(obj
, TRUE
);
2091 obj
->nobj
= oldminvent
;
2095 /* defer statue creation until after inventory removal
2096 so that saved monster traits won't retain any stale
2097 item-conferred attributes */
2098 otmp
= mkcorpstat(STATUE
, mdef
, mdef
->data
, x
, y
, CORPSTAT_NONE
);
2099 if (has_mname(mdef
))
2100 otmp
= oname(otmp
, MNAME(mdef
));
2101 while ((obj
= oldminvent
) != 0) {
2102 oldminvent
= obj
->nobj
;
2103 (void) add_to_container(otmp
, obj
);
2105 /* Archeologists should not break unique statues */
2106 if (mdef
->data
->geno
& G_UNIQ
)
2108 otmp
->owt
= weight(otmp
);
2110 otmp
= mksobj_at(ROCK
, x
, y
, TRUE
, FALSE
);
2113 /* mondead() already does this, but we must do it before the newsym */
2114 if (glyph_is_invisible(levl
[x
][y
].glyph
))
2118 /* We don't currently trap the hero in the statue in this case but we
2120 if (u
.uswallow
&& u
.ustuck
== mdef
)
2124 if (is_animal(mdef
->data
))
2125 You("%s through an opening in the new %s.",
2126 locomotion(youmonst
.data
, "jump"), xname(otmp
));
2130 /* another monster has killed the monster mdef */
2132 monkilled(mdef
, fltxt
, how
)
2137 boolean be_sad
= FALSE
; /* true if unseen pet is killed */
2139 if ((mdef
->wormno
? worm_known(mdef
) : cansee(mdef
->mx
, mdef
->my
))
2141 pline("%s is %s%s%s!", Monnam(mdef
),
2142 nonliving(mdef
->data
) ? "destroyed" : "killed",
2143 *fltxt
? " by the " : "", fltxt
);
2145 be_sad
= (mdef
->mtame
!= 0);
2147 /* no corpses if digested or disintegrated */
2148 if (how
== AD_DGST
|| how
== -AD_RBRE
)
2153 if (be_sad
&& mdef
->mhp
<= 0)
2154 You("have a sad feeling for a moment, then it passes.");
2161 if (u
.ustuck
== mtmp
) {
2167 if (Punished
&& uchain
->where
!= OBJ_FLOOR
)
2169 vision_full_recalc
= 1;
2171 /* prevent swallower (mtmp might have just poly'd into something
2172 without an engulf attack) from immediately re-engulfing */
2173 if (attacktype(mtmp
->data
, AT_ENGL
) && !mtmp
->mspec_used
)
2174 mtmp
->mspec_used
= rnd(2);
2184 xkilled(mtmp
, XKILL_GIVEMSG
);
2187 /* the player has killed the monster mtmp */
2189 xkilled(mtmp
, xkill_flags
)
2191 int xkill_flags
; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
2193 int tmp
, mndx
, x
= mtmp
->mx
, y
= mtmp
->my
;
2194 struct permonst
*mdat
;
2197 boolean wasinside
= u
.uswallow
&& (u
.ustuck
== mtmp
),
2199 nomsg
= (xkill_flags
& XKILL_NOMSG
) != 0,
2200 nocorpse
= (xkill_flags
& XKILL_NOCORPSE
) != 0,
2201 noconduct
= (xkill_flags
& XKILL_NOCONDUCT
) != 0;
2203 mtmp
->mhp
= 0; /* caller will usually have already done this */
2204 if (!noconduct
) /* KMH, conduct */
2205 u
.uconduct
.killer
++;
2208 boolean namedpet
= has_mname(mtmp
) && !Hallucination
;
2211 nonliving(mtmp
->data
) ? "destroy" : "kill",
2212 !(wasinside
|| canspotmon(mtmp
)) ? "it"
2213 : !mtmp
->mtame
? mon_nam(mtmp
)
2214 : x_monnam(mtmp
, namedpet
? ARTICLE_NONE
: ARTICLE_THE
,
2215 "poor", namedpet
? SUPPRESS_SADDLE
: 0, FALSE
));
2218 if (mtmp
->mtrapped
&& (t
= t_at(x
, y
)) != 0
2219 && (t
->ttyp
== PIT
|| t
->ttyp
== SPIKED_PIT
)) {
2220 if (sobj_at(BOULDER
, x
, y
))
2221 nocorpse
= TRUE
; /* Prevent corpses/treasure being created
2222 "on top" of boulder that is about to fall in.
2223 This is out of order, but cannot be helped
2224 unless this whole routine is rearranged. */
2225 if (m_carrying(mtmp
, BOULDER
))
2229 /* your pet knows who just killed it...watch out */
2230 if (mtmp
->mtame
&& !mtmp
->isminion
)
2231 EDOG(mtmp
)->killed_by_u
= 1;
2233 if (wasinside
&& thrownobj
&& thrownobj
!= uball
) {
2234 /* thrown object has killed hero's engulfer; add it to mon's
2235 inventory now so that it will be placed with mon's other
2236 stuff prior to lookhere/autopickup when hero is expelled
2237 below (as a side-effect, this missile has immunity from
2238 being consumed [for this shot/throw only]) */
2239 mpickobj(mtmp
, thrownobj
);
2240 /* let throwing code know that missile has been disposed of */
2244 vamp_rise_msg
= FALSE
; /* might get set in mondead() */
2245 /* dispose of monster and make cadaver */
2251 if (mtmp
->mhp
> 0) { /* monster lifesaved */
2252 /* Cannot put the non-visible lifesaving message in
2253 * lifesaved_monster() since the message appears only when you
2254 * kill it (as opposed to visible lifesaving which always appears).
2257 if (!cansee(x
, y
) && !vamp_rise_msg
)
2258 pline("Maybe not...");
2262 mdat
= mtmp
->data
; /* note: mondead can change mtmp->data */
2263 mndx
= monsndx(mdat
);
2270 if (nocorpse
|| LEVEL_SPECIFIC_NOCORPSE(mdat
))
2274 if (mdat
== &mons
[PM_MAIL_DAEMON
]) {
2275 stackobj(mksobj_at(SCR_MAIL
, x
, y
, FALSE
, FALSE
));
2278 if (accessible(x
, y
) || is_pool(x
, y
)) {
2279 struct obj
*cadaver
;
2282 /* illogical but traditional "treasure drop" */
2283 if (!rn2(6) && !(mvitals
[mndx
].mvflags
& G_NOCORPSE
)
2284 /* no extra item from swallower or steed */
2285 && (x
!= u
.ux
|| y
!= u
.uy
)
2286 /* no extra item from kops--too easy to abuse */
2287 && mdat
->mlet
!= S_KOP
2288 /* no items from cloned monsters */
2289 && !mtmp
->mcloned
) {
2290 otmp
= mkobj(RANDOM_CLASS
, TRUE
);
2291 /* don't create large objects from small monsters */
2293 if (mdat
->msize
< MZ_HUMAN
&& otyp
!= FIGURINE
2294 /* oc_big is also oc_bimanual and oc_bulky */
2295 && (otmp
->owt
> 30 || objects
[otyp
].oc_big
)) {
2297 } else if (!flooreffects(otmp
, x
, y
, nomsg
? "" : "fall")) {
2298 place_object(otmp
, x
, y
);
2302 /* corpse--none if hero was inside the monster */
2303 if (!wasinside
&& corpse_chance(mtmp
, (struct monst
*) 0, FALSE
)) {
2304 cadaver
= make_corpse(mtmp
, burycorpse
? CORPSTAT_BURIED
2306 if (burycorpse
&& cadaver
&& cansee(x
, y
) && !mtmp
->minvis
2307 && cadaver
->where
== OBJ_BURIED
&& !nomsg
) {
2308 pline("%s corpse ends up buried.", s_suffix(Monnam(mtmp
)));
2313 spoteffects(TRUE
); /* poor man's expels() */
2314 /* monster is gone, corpse or other object might now be visible */
2318 /* punish bad behaviour */
2320 && (!always_hostile(mdat
) && mtmp
->malign
<= 0)
2321 && (mndx
< PM_ARCHEOLOGIST
|| mndx
> PM_WIZARD
)
2322 && u
.ualign
.type
!= A_CHAOTIC
) {
2323 HTelepat
&= ~INTRINSIC
;
2326 if (Blind
&& !Blind_telepat
)
2327 see_monsters(); /* Can't sense monsters any more. */
2329 if ((mtmp
->mpeaceful
&& !rn2(2)) || mtmp
->mtame
)
2331 if (is_unicorn(mdat
) && sgn(u
.ualign
.type
) == sgn(mdat
->maligntyp
)) {
2333 You_feel("guilty...");
2336 /* give experience points */
2337 tmp
= experience(mtmp
, (int) mvitals
[mndx
].died
);
2338 more_experienced(tmp
, 0);
2339 newexplevel(); /* will decide if you go up */
2341 /* adjust alignment points */
2342 if (mtmp
->m_id
== quest_status
.leader_m_id
) { /* REAL BAD! */
2343 adjalign(-(u
.ualign
.record
+ (int) ALIGNLIM
/ 2));
2344 pline("That was %sa bad idea...",
2345 u
.uevent
.qcompleted
? "probably " : "");
2346 } else if (mdat
->msound
== MS_NEMESIS
) { /* Real good! */
2347 adjalign((int) (ALIGNLIM
/ 4));
2348 } else if (mdat
->msound
== MS_GUARDIAN
) { /* Bad */
2349 adjalign(-(int) (ALIGNLIM
/ 8));
2351 pline("That was probably a bad idea...");
2353 pline("Whoopsie-daisy!");
2354 } else if (mtmp
->ispriest
) {
2355 adjalign((p_coaligned(mtmp
)) ? -2 : 2);
2356 /* cancel divine protection for killing your priest */
2357 if (p_coaligned(mtmp
))
2359 if (mdat
->maligntyp
== A_NONE
)
2360 adjalign((int) (ALIGNLIM
/ 4)); /* BIG bonus */
2361 } else if (mtmp
->mtame
) {
2362 adjalign(-15); /* bad!! */
2363 /* your god is mighty displeased... */
2365 You_hear("the rumble of distant thunder...");
2367 You_hear("the studio audience applaud!");
2368 } else if (mtmp
->mpeaceful
)
2371 /* malign was already adjusted for u.ualign.type and randomization */
2372 adjalign(mtmp
->malign
);
2375 /* changes the monster into a stone monster of the same type
2376 this should only be called when poly_when_stoned() is true */
2381 if (mtmp
->data
->mlet
== S_GOLEM
) {
2382 /* it's a golem, and not a stone golem */
2383 if (canseemon(mtmp
))
2384 pline("%s solidifies...", Monnam(mtmp
));
2385 if (newcham(mtmp
, &mons
[PM_STONE_GOLEM
], FALSE
, FALSE
)) {
2386 if (canseemon(mtmp
))
2387 pline("Now it's %s.", an(mtmp
->data
->mname
));
2389 if (canseemon(mtmp
))
2390 pline("... and returns to normal.");
2393 impossible("Can't polystone %s!", a_monnam(mtmp
));
2400 if (is_vampshifter(mtmp
)) {
2401 int mndx
= mtmp
->cham
;
2402 int x
= mtmp
->mx
, y
= mtmp
->my
;
2404 /* this only happens if shapeshifted */
2405 if (mndx
>= LOW_PM
&& mndx
!= monsndx(mtmp
->data
)
2406 && !(mvitals
[mndx
].mvflags
& G_GENOD
)) {
2408 boolean in_door
= (amorphous(mtmp
->data
)
2409 && closed_door(mtmp
->mx
, mtmp
->my
));
2411 /* construct a format string before transformation */
2412 Sprintf(buf
, "The lapidifying %s %s %s",
2413 x_monnam(mtmp
, ARTICLE_NONE
, (char *) 0,
2414 (SUPPRESS_SADDLE
| SUPPRESS_HALLUCINATION
2415 | SUPPRESS_INVISIBLE
| SUPPRESS_IT
), FALSE
),
2416 amorphous(mtmp
->data
) ? "coalesces on the"
2417 : is_flyer(mtmp
->data
) ? "drops to the"
2422 if (mtmp
->mhpmax
<= 0)
2424 mtmp
->mhp
= mtmp
->mhpmax
;
2425 /* this can happen if previously a fog cloud */
2426 if (u
.uswallow
&& (mtmp
== u
.ustuck
))
2427 expels(mtmp
, mtmp
->data
, FALSE
);
2431 if (enexto(&new_xy
, mtmp
->mx
, mtmp
->my
, &mons
[mndx
])) {
2432 rloc_to(mtmp
, new_xy
.x
, new_xy
.y
);
2435 if (canspotmon(mtmp
)) {
2437 display_nhwindow(WIN_MESSAGE
, FALSE
);
2439 newcham(mtmp
, &mons
[mndx
], FALSE
, FALSE
);
2440 if (mtmp
->data
== &mons
[mndx
])
2441 mtmp
->cham
= NON_PM
;
2444 if (canspotmon(mtmp
)) {
2445 pline("%s rises from the %s with renewed agility!",
2446 Amonnam(mtmp
), surface(mtmp
->mx
, mtmp
->my
));
2448 newsym(mtmp
->mx
, mtmp
->my
);
2449 return FALSE
; /* didn't petrify */
2455 /* drop monster into "limbo" - that is, migrate to the current level */
2461 mdrop_special_objs(mtmp
);
2462 migrate_to_level(mtmp
, ledger_no(&u
.uz
), MIGR_APPROX_XY
, NULL
);
2465 /* make monster mtmp next to you (if possible);
2466 might place monst on far side of a wall or boulder */
2472 boolean couldspot
= canspotmon(mtmp
);
2474 if (mtmp
== u
.usteed
) {
2475 /* Keep your steed in sync with you instead */
2481 if (!enexto(&mm
, u
.ux
, u
.uy
, mtmp
->data
)) {
2485 if (!isok(mm
.x
, mm
.y
))
2487 rloc_to(mtmp
, mm
.x
, mm
.y
);
2488 if (!in_mklev
&& (mtmp
->mstrategy
& STRAT_APPEARMSG
)) {
2489 mtmp
->mstrategy
&= ~STRAT_APPEARMSG
; /* one chance only */
2490 if (!couldspot
&& canspotmon(mtmp
))
2491 pline("%s suddenly %s!", Amonnam(mtmp
),
2492 !Blind
? "appears" : "arrives");
2497 /* like mnexto() but requires destination to be directly accessible */
2503 struct permonst
*ptr
= mtmp
->data
;
2504 boolean diagok
= !NODIAG(ptr
- mons
);
2508 if (!enexto(&mm
, u
.ux
, u
.uy
, ptr
))
2510 if (couldsee(mm
.x
, mm
.y
)
2511 /* don't move grid bugs diagonally */
2512 && (diagok
|| mm
.x
== mtmp
->mx
|| mm
.y
== mtmp
->my
)) {
2513 rloc_to(mtmp
, mm
.x
, mm
.y
);
2516 } while (--tryct
> 0);
2520 * Put monster near (or at) location if possible.
2522 * true if relocation was successful
2526 mnearto(mtmp
, x
, y
, move_other
)
2527 register struct monst
*mtmp
;
2529 boolean move_other
; /* make sure mtmp gets to x, y! so move m_at(x, y) */
2531 struct monst
*othermon
= (struct monst
*) 0;
2535 if (mtmp
->mx
== x
&& mtmp
->my
== y
)
2538 if (move_other
&& (othermon
= m_at(x
, y
)) != 0) {
2539 if (othermon
->wormno
)
2540 remove_worm(othermon
);
2542 remove_monster(x
, y
);
2547 if (!goodpos(newx
, newy
, mtmp
, 0)) {
2548 /* Actually we have real problems if enexto ever fails.
2549 * Migrating_mons that need to be placed will cause
2550 * no end of trouble.
2552 if (!enexto(&mm
, newx
, newy
, mtmp
->data
))
2554 if (!isok(mm
.x
,mm
.y
))
2559 rloc_to(mtmp
, newx
, newy
);
2561 if (move_other
&& othermon
) {
2562 xchar oldx
= othermon
->mx
, oldy
= othermon
->my
;
2564 othermon
->mx
= othermon
->my
= 0;
2565 (void) mnearto(othermon
, x
, y
, FALSE
);
2566 if (othermon
->mx
== 0 && othermon
->my
== 0) {
2568 othermon
->mx
= oldx
;
2569 othermon
->my
= oldy
;
2570 m_into_limbo(othermon
);
2577 /* monster responds to player action; not the same as a passive attack;
2578 assumes reason for response has been tested, and response _must_ be made */
2583 if (mtmp
->data
->msound
== MS_SHRIEK
) {
2585 pline("%s shrieks.", Monnam(mtmp
));
2590 (void) makemon(&mons
[PM_PURPLE_WORM
], 0, 0, NO_MM_FLAGS
);
2592 (void) makemon((struct permonst
*) 0, 0, 0, NO_MM_FLAGS
);
2596 if (mtmp
->data
== &mons
[PM_MEDUSA
]) {
2599 for (i
= 0; i
< NATTK
; i
++)
2600 if (mtmp
->data
->mattk
[i
].aatyp
== AT_GAZE
) {
2601 (void) gazemu(mtmp
, &mtmp
->data
->mattk
[i
]);
2607 /* Called whenever the player attacks mtmp; also called in other situations
2608 where mtmp gets annoyed at the player. Handles mtmp getting annoyed at the
2609 attack and any ramifications that might have. Useful also in situations where
2610 mtmp was already hostile; it checks for situations where the player shouldn't
2611 be attacking and any ramifications /that/ might have. */
2613 setmangry(mtmp
, via_attack
)
2617 if (via_attack
&& sengr_at("Elbereth", u
.ux
, u
.uy
, TRUE
)) {
2618 You_feel("like a hypocrite.");
2619 /* AIS: Yes, I know alignment penalties and bonuses aren't balanced at
2620 the moment. This is about correct relative to other "small"
2621 penalties; it should be fairly large, as attacking while standing on
2622 an Elbereth means that you're requesting peace and then violating
2623 your own request. I know 5 isn't actually large, but it's
2624 intentionally larger than the 1s and 2s that are normally given for
2625 this sort of thing. */
2629 pline("The engraving beneath you fades.");
2630 del_engr_at(u
.ux
, u
.uy
);
2633 /* AIS: Should this be in both places, or just in wakeup()? */
2634 mtmp
->mstrategy
&= ~STRAT_WAITMASK
;
2635 if (!mtmp
->mpeaceful
)
2639 mtmp
->mpeaceful
= 0;
2640 if (mtmp
->ispriest
) {
2641 if (p_coaligned(mtmp
))
2642 adjalign(-5); /* very bad */
2646 adjalign(-1); /* attacking peaceful monsters is bad */
2647 if (couldsee(mtmp
->mx
, mtmp
->my
)) {
2648 if (humanoid(mtmp
->data
) || mtmp
->isshk
|| mtmp
->isgd
)
2649 pline("%s gets angry!", Monnam(mtmp
));
2650 else if (flags
.verbose
&& !Deaf
)
2654 /* attacking your own quest leader will anger his or her guardians */
2655 if (!context
.mon_moving
/* should always be the case here */
2656 && mtmp
->data
== &mons
[quest_info(MS_LEADER
)]) {
2658 struct permonst
*q_guardian
= &mons
[quest_info(MS_GUARDIAN
)];
2661 /* guardians will sense this attack even if they can't see it */
2662 for (mon
= fmon
; mon
; mon
= mon
->nmon
) {
2663 if (DEADMONSTER(mon
))
2665 if (mon
->data
== q_guardian
&& mon
->mpeaceful
) {
2671 if (got_mad
&& !Hallucination
)
2672 pline_The("%s appear%s to be angry too...",
2673 got_mad
== 1 ? q_guardian
->mname
2674 : makeplural(q_guardian
->mname
),
2675 got_mad
== 1 ? "s" : "");
2678 /* make other peaceful monsters react */
2679 if (!context
.mon_moving
) {
2682 for (mon
= fmon
; mon
; mon
= mon
->nmon
) {
2683 if (DEADMONSTER(mon
))
2685 if (!mindless(mon
->data
) && mon
->mpeaceful
2686 && couldsee(mon
->mx
, mon
->my
) && !mon
->msleeping
2687 && mon
->mcansee
&& m_canseeu(mon
)) {
2688 boolean exclaimed
= FALSE
;
2690 if (humanoid(mon
->data
) || mon
->isshk
|| mon
->ispriest
) {
2691 if (is_watch(mon
->data
)) {
2692 verbalize("Halt! You're under arrest!");
2693 (void) angry_guards(!!Deaf
);
2695 const char *exclam
[] = {
2696 "Gasp!", "Uh-oh.", "Oh my!", "What?", "Why?"
2699 verbalize("%s", exclam
[mon
->m_id
% SIZE(exclam
)]);
2702 if (!mon
->isshk
&& !mon
->ispriest
2703 && (mon
->data
->mlevel
< rn2(10))) {
2704 monflee(mon
, rn2(50)+25, TRUE
, !exclaimed
);
2707 if (!mon
->isshk
&& !mon
->ispriest
) {
2711 pline("%s gets angry!", Monnam(mon
));
2714 } else if ((mtmp
->data
== mon
->data
) && !rn2(3)) {
2720 monflee(mon
, rn2(25)+15, TRUE
, !exclaimed
);
2728 /* wake up a monster, possibly making it angry in the process */
2730 wakeup(mtmp
, via_attack
)
2731 register struct monst
*mtmp
;
2734 mtmp
->msleeping
= 0;
2735 finish_meating(mtmp
);
2737 setmangry(mtmp
, TRUE
);
2738 if (mtmp
->m_ap_type
) {
2740 } else if (context
.forcefight
&& !context
.mon_moving
2741 && mtmp
->mundetected
) {
2742 mtmp
->mundetected
= 0;
2743 newsym(mtmp
->mx
, mtmp
->my
);
2747 /* Wake up nearby monsters without angering them. */
2751 register struct monst
*mtmp
;
2753 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
2754 if (DEADMONSTER(mtmp
))
2756 if (distu(mtmp
->mx
, mtmp
->my
) < u
.ulevel
* 20) {
2757 mtmp
->msleeping
= 0;
2758 if (!unique_corpstat(mtmp
->data
))
2759 mtmp
->mstrategy
&= ~STRAT_WAITMASK
;
2760 if (mtmp
->mtame
&& !mtmp
->isminion
)
2761 EDOG(mtmp
)->whistletime
= moves
;
2766 /* Wake up monsters near some particular location. */
2768 wake_nearto(x
, y
, distance
)
2769 register int x
, y
, distance
;
2771 register struct monst
*mtmp
;
2773 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
2774 if (DEADMONSTER(mtmp
))
2776 if (distance
== 0 || dist2(mtmp
->mx
, mtmp
->my
, x
, y
) < distance
) {
2777 mtmp
->msleeping
= 0;
2778 if (!unique_corpstat(mtmp
->data
))
2779 mtmp
->mstrategy
&= ~STRAT_WAITMASK
;
2784 /* NOTE: we must check for mimicry before calling this routine */
2787 register struct monst
*mtmp
;
2789 boolean is_blocker_appear
= (is_lightblocker_mappear(mtmp
));
2791 if (has_mcorpsenm(mtmp
))
2792 freemcorpsenm(mtmp
);
2794 mtmp
->m_ap_type
= M_AP_NOTHING
;
2795 mtmp
->mappearance
= 0;
2798 * Discovered mimics don't block light.
2800 if (is_blocker_appear
2801 && !does_block(mtmp
->mx
, mtmp
->my
, &levl
[mtmp
->mx
][mtmp
->my
]))
2802 unblock_point(mtmp
->mx
, mtmp
->my
);
2804 newsym(mtmp
->mx
, mtmp
->my
);
2807 /* force all chameleons to become normal */
2811 register struct monst
*mtmp
;
2814 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
2815 if (DEADMONSTER(mtmp
))
2817 mcham
= (int) mtmp
->cham
;
2818 if (mcham
>= LOW_PM
) {
2819 (void) newcham(mtmp
, &mons
[mcham
], FALSE
, FALSE
);
2820 mtmp
->cham
= NON_PM
;
2822 if (is_were(mtmp
->data
) && mtmp
->data
->mlet
!= S_HUMAN
)
2824 if (mtmp
->m_ap_type
&& cansee(mtmp
->mx
, mtmp
->my
)) {
2826 /* we pretend that the mimic doesn't
2827 know that it has been unmasked */
2828 mtmp
->msleeping
= 1;
2833 /* Let the chameleons change again -dgk */
2837 register struct monst
*mtmp
;
2839 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
2840 if (DEADMONSTER(mtmp
))
2842 mtmp
->cham
= pm_to_cham(monsndx(mtmp
->data
));
2843 if (mtmp
->data
->mlet
== S_MIMIC
&& mtmp
->msleeping
2844 && cansee(mtmp
->mx
, mtmp
->my
)) {
2845 set_mimic_sym(mtmp
);
2846 newsym(mtmp
->mx
, mtmp
->my
);
2851 /* called when restoring a monster from a saved level; protection
2852 against shape-changing might be different now than it was at the
2853 time the level was saved. */
2860 if (Protection_from_shape_changers
) {
2861 mcham
= (int) mon
->cham
;
2862 if (mcham
>= LOW_PM
) {
2864 (void) newcham(mon
, &mons
[mcham
], FALSE
, FALSE
);
2865 } else if (is_were(mon
->data
) && !is_human(mon
->data
)) {
2868 } else if (mon
->cham
== NON_PM
) {
2869 mon
->cham
= pm_to_cham(monsndx(mon
->data
));
2873 /* unwatched hiders may hide again; if so, returns True */
2876 register struct monst
*mtmp
;
2880 if (mtmp
->mcan
|| mtmp
->m_ap_type
|| cansee(mtmp
->mx
, mtmp
->my
)
2881 || rn2(3) || mtmp
== u
.ustuck
2882 /* can't hide while trapped except in pits */
2883 || (mtmp
->mtrapped
&& (t
= t_at(mtmp
->mx
, mtmp
->my
)) != 0
2884 && !(t
->ttyp
== PIT
|| t
->ttyp
== SPIKED_PIT
))
2885 || (sensemon(mtmp
) && distu(mtmp
->mx
, mtmp
->my
) <= 2))
2888 if (mtmp
->data
->mlet
== S_MIMIC
) {
2889 set_mimic_sym(mtmp
);
2891 } else if (levl
[mtmp
->mx
][mtmp
->my
].typ
== ROOM
) {
2892 mtmp
->mundetected
= 1;
2899 /* monster/hero tries to hide under something at the current location */
2905 boolean undetected
= FALSE
, is_u
= (mtmp
== &youmonst
);
2906 xchar x
= is_u
? u
.ux
: mtmp
->mx
, y
= is_u
? u
.uy
: mtmp
->my
;
2908 if (mtmp
== u
.ustuck
) {
2909 ; /* can't hide if holding you or held by you */
2910 } else if (is_u
? (u
.utrap
&& u
.utraptype
!= TT_PIT
)
2911 : (mtmp
->mtrapped
&& (t
= t_at(x
, y
)) != 0
2912 && !(t
->ttyp
== PIT
|| t
->ttyp
== SPIKED_PIT
))) {
2913 ; /* can't hide while stuck in a non-pit trap */
2914 } else if (mtmp
->data
->mlet
== S_EEL
) {
2915 undetected
= (is_pool(x
, y
) && !Is_waterlevel(&u
.uz
));
2916 } else if (hides_under(mtmp
->data
) && OBJ_AT(x
, y
)) {
2917 struct obj
*otmp
= level
.objects
[x
][y
];
2919 /* most monsters won't hide under cockatrice corpse */
2920 if (otmp
->nexthere
|| otmp
->otyp
!= CORPSE
2921 || (mtmp
== &youmonst
? Stone_resistance
: resists_ston(mtmp
))
2922 || !touch_petrifies(&mons
[otmp
->corpsenm
]))
2927 u
.uundetected
= undetected
;
2929 mtmp
->mundetected
= undetected
;
2933 /* called when returning to a previously visited level */
2938 boolean hider_under
= hides_under(mon
->data
) || mon
->data
->mlet
== S_EEL
;
2940 if ((is_hider(mon
->data
) || hider_under
)
2941 && !(mon
->mundetected
|| mon
->m_ap_type
)) {
2942 xchar x
= mon
->mx
, y
= mon
->my
;
2943 char save_viz
= viz_array
[y
][x
];
2945 /* override vision, forcing hero to be unable to see monster's spot */
2946 viz_array
[y
][x
] &= ~(IN_SIGHT
| COULD_SEE
);
2947 if (is_hider(mon
->data
))
2948 (void) restrap(mon
);
2949 /* try again if mimic missed its 1/3 chance to hide */
2950 if (mon
->data
->mlet
== S_MIMIC
&& !mon
->m_ap_type
)
2951 (void) restrap(mon
);
2953 (void) hideunder(mon
);
2954 viz_array
[y
][x
] = save_viz
;
2958 static short *animal_list
= 0; /* list of PM values for animal monsters */
2959 static int animal_list_count
;
2962 mon_animal_list(construct
)
2966 short animal_temp
[SPECIAL_PM
];
2969 /* if (animal_list) impossible("animal_list already exists"); */
2971 for (n
= 0, i
= LOW_PM
; i
< SPECIAL_PM
; i
++)
2972 if (is_animal(&mons
[i
]))
2973 animal_temp
[n
++] = i
;
2974 /* if (n == 0) animal_temp[n++] = NON_PM; */
2976 animal_list
= (short *) alloc(n
* sizeof *animal_list
);
2977 (void) memcpy((genericptr_t
) animal_list
, (genericptr_t
) animal_temp
,
2978 n
* sizeof *animal_list
);
2979 animal_list_count
= n
;
2980 } else { /* release */
2982 free((genericptr_t
) animal_list
), animal_list
= 0;
2983 animal_list_count
= 0;
2993 mon_animal_list(TRUE
);
2995 res
= animal_list
[rn2(animal_list_count
)];
2996 /* rogue level should use monsters represented by uppercase letters
2997 only, but since chameleons aren't generated there (not uppercase!)
2998 we don't perform a lot of retries */
2999 if (Is_rogue_level(&u
.uz
) && !isupper((uchar
) mons
[res
].mlet
))
3000 res
= animal_list
[rn2(animal_list_count
)];
3005 decide_to_shapeshift(mon
, shiftflags
)
3009 struct permonst
*ptr
;
3010 unsigned was_female
= mon
->female
;
3011 boolean msg
= FALSE
;
3013 if ((shiftflags
& SHIFT_MSG
)
3014 || ((shiftflags
& SHIFT_SEENMSG
) && sensemon(mon
)))
3017 if (!is_vampshifter(mon
)) {
3018 /* regular shapeshifter */
3020 (void) newcham(mon
, (struct permonst
*) 0, FALSE
, msg
);
3022 /* The vampire has to be in good health (mhp) to maintain
3025 * If we're shifted and getting low on hp, maybe shift back.
3026 * If we're not already shifted and in good health, maybe shift.
3028 if (mon
->data
->mlet
!= S_VAMPIRE
) {
3029 if ((mon
->mhp
<= (mon
->mhpmax
+ 5) / 6) && rn2(4)
3030 && mon
->cham
>= LOW_PM
)
3031 (void) newcham(mon
, &mons
[mon
->cham
], FALSE
, msg
);
3033 if (mon
->mhp
>= 9 * mon
->mhpmax
/ 10 && !rn2(6)
3035 || distu(mon
->mx
, mon
->my
) > BOLT_LIM
* BOLT_LIM
))
3036 (void) newcham(mon
, (struct permonst
*) 0, FALSE
, msg
);
3038 /* override the 10% chance for sex change */
3040 if (!is_male(ptr
) && !is_female(ptr
) && !is_neuter(ptr
))
3041 mon
->female
= was_female
;
3049 int mndx
= mon
->cham
, wolfchance
= 10;
3050 /* avoid picking monsters with lowercase display symbols ('d' for wolf
3051 and 'v' for fog cloud) on rogue level*/
3052 boolean uppercase_only
= Is_rogue_level(&u
.uz
);
3055 case PM_VLAD_THE_IMPALER
:
3056 /* ensure Vlad can keep carrying the Candelabrum */
3057 if (mon_has_special(mon
))
3058 break; /* leave mndx as is */
3061 case PM_VAMPIRE_LORD
: /* vampire lord or Vlad can become wolf */
3062 if (!rn2(wolfchance
) && !uppercase_only
) {
3067 case PM_VAMPIRE
: /* any vampire can become fog or bat */
3068 mndx
= (!rn2(4) && !uppercase_only
) ? PM_FOG_CLOUD
: PM_VAMPIRE_BAT
;
3074 /* nonshapechangers who warrant special polymorph handling */
3079 return (mon
->isshk
|| mon
->ispriest
|| mon
->isgd
3080 || mon
->m_id
== quest_status
.leader_m_id
);
3083 /* restrict certain special monsters (shopkeepers, aligned priests,
3084 vault guards) to forms that allow them to behave sensibly (catching
3085 gold, speaking?) so that they don't need too much extra code */
3087 validspecmon(mon
, mndx
)
3092 return TRUE
; /* caller wants random */
3094 if (!accept_newcham_form(mndx
))
3095 return FALSE
; /* geno'd or !polyok */
3097 if (isspecmon(mon
)) {
3098 struct permonst
*ptr
= &mons
[mndx
];
3100 /* reject notake because object manipulation is expected
3101 and nohead because speech capability is expected */
3102 if (notake(ptr
) || !has_head(ptr
))
3104 /* [should we check ptr->msound here too?] */
3106 return TRUE
; /* potential new form is ok */
3109 /* prevent wizard mode user from specifying invalid vampshifter shape */
3111 validvamp(mon
, mndx_p
, monclass
)
3113 int *mndx_p
, monclass
;
3115 /* simplify caller's usage */
3116 if (!is_vampshifter(mon
))
3117 return validspecmon(mon
, *mndx_p
);
3119 if (*mndx_p
== PM_VAMPIRE
|| *mndx_p
== PM_VAMPIRE_LORD
3120 || *mndx_p
== PM_VLAD_THE_IMPALER
) {
3121 /* player picked some type of vampire; use mon's self */
3122 *mndx_p
= mon
->cham
;
3125 if (mon
->cham
== PM_VLAD_THE_IMPALER
&& mon_has_special(mon
)) {
3126 /* Vlad with Candelabrum; override choice, then accept it */
3127 *mndx_p
= PM_VLAD_THE_IMPALER
;
3130 /* basic vampires can't become wolves; any can become fog or bat
3131 (we don't enforce upper-case only for rogue level here) */
3132 if (*mndx_p
== PM_WOLF
)
3133 return (boolean
) (mon
->cham
!= PM_VAMPIRE
);
3134 if (*mndx_p
== PM_FOG_CLOUD
|| *mndx_p
== PM_VAMPIRE_BAT
)
3137 /* if we get here, specific type was no good; try by class */
3140 *mndx_p
= mon
->cham
;
3143 *mndx_p
= PM_VAMPIRE_BAT
;
3146 *mndx_p
= PM_FOG_CLOUD
;
3149 if (mon
->cham
!= PM_VAMPIRE
) {
3158 return (boolean
) (*mndx_p
!= NON_PM
);
3162 select_newcham_form(mon
)
3165 int mndx
= NON_PM
, tryct
;
3167 switch (mon
->cham
) {
3170 mndx
= pick_nasty();
3172 case PM_DOPPELGANGER
:
3174 mndx
= pick_nasty();
3175 } else if (rn2(3)) { /* role monsters */
3176 mndx
= rn1(PM_WIZARD
- PM_ARCHEOLOGIST
+ 1, PM_ARCHEOLOGIST
);
3177 } else if (!rn2(3)) { /* quest guardians */
3178 mndx
= rn1(PM_APPRENTICE
- PM_STUDENT
+ 1, PM_STUDENT
);
3179 /* avoid own role's guardian */
3180 if (mndx
== urole
.guardnum
)
3182 } else { /* general humanoids */
3185 mndx
= rn1(SPECIAL_PM
- LOW_PM
, LOW_PM
);
3186 if (humanoid(&mons
[mndx
]) && polyok(&mons
[mndx
]))
3188 } while (--tryct
> 0);
3195 mndx
= pick_animal();
3197 case PM_VLAD_THE_IMPALER
:
3198 case PM_VAMPIRE_LORD
:
3200 mndx
= pickvampshape(mon
);
3202 case NON_PM
: /* ordinary */
3204 struct obj
*m_armr
= which_armor(mon
, W_ARM
);
3206 if (m_armr
&& Is_dragon_scales(m_armr
))
3207 mndx
= (int) (Dragon_scales_to_pm(m_armr
) - mons
);
3208 else if (m_armr
&& Is_dragon_mail(m_armr
))
3209 mndx
= (int) (Dragon_mail_to_pm(m_armr
) - mons
);
3214 /* for debugging: allow control of polymorphed monster */
3215 if (wizard
&& iflags
.mon_polycontrol
) {
3216 char pprompt
[BUFSZ
], buf
[BUFSZ
];
3219 Sprintf(pprompt
, "Change %s @ %s into what kind of monster?",
3221 coord_desc((int) mon
->mx
, (int) mon
->my
, buf
,
3222 (iflags
.getpos_coords
!= GPCOORDS_NONE
)
3223 ? iflags
.getpos_coords
: GPCOORDS_MAP
));
3227 getlin(pprompt
, buf
);
3229 /* for ESC, take form selected above (might be NON_PM) */
3232 /* for "*", use NON_PM to pick an arbitrary shape below */
3233 if (!strcmp(buf
, "*") || !strcmp(buf
, "random")) {
3237 mndx
= name_to_mon(buf
);
3238 if (mndx
== NON_PM
) {
3239 /* didn't get a type, so check whether it's a class
3240 (single letter or text match with def_monsyms[]) */
3241 monclass
= name_to_monclass(buf
, &mndx
);
3242 if (monclass
&& mndx
== NON_PM
)
3243 mndx
= mkclass_poly(monclass
);
3245 if (mndx
>= LOW_PM
) {
3246 /* got a specific type of monster; use it if we can */
3247 if (validvamp(mon
, &mndx
, monclass
))
3249 /* can't; revert to random in case we exhaust tryct */
3253 pline("It can't become that.");
3254 } while (--tryct
> 0);
3256 pline1(thats_enough_tries
);
3257 if (is_vampshifter(mon
) && !validvamp(mon
, &mndx
, monclass
))
3258 mndx
= pickvampshape(mon
); /* don't resort to arbitrary */
3261 /* if no form was specified above, pick one at random now */
3262 if (mndx
== NON_PM
) {
3265 mndx
= rn1(SPECIAL_PM
- LOW_PM
, LOW_PM
);
3266 } while (--tryct
> 0 && !validspecmon(mon
, mndx
)
3267 /* try harder to select uppercase monster on rogue level */
3268 && (tryct
> 40 && Is_rogue_level(&u
.uz
)
3269 && !isupper((uchar
) mons
[mndx
].mlet
)));
3274 /* this used to be inline within newcham() but monpolycontrol needs it too */
3275 STATIC_OVL
struct permonst
*
3276 accept_newcham_form(mndx
)
3279 struct permonst
*mdat
;
3284 if ((mvitals
[mndx
].mvflags
& G_GENOD
) != 0)
3286 if (is_placeholder(mdat
))
3288 /* select_newcham_form() might deliberately pick a player
3289 character type (random selection never does) which
3290 polyok() rejects, so we need a special case here */
3291 if (is_mplayer(mdat
))
3293 /* polyok() rules out M2_PNAME, M2_WERE, and all humans except Kops */
3294 return polyok(mdat
) ? mdat
: 0;
3298 mgender_from_permonst(mtmp
, mdat
)
3300 struct permonst
*mdat
;
3302 if (is_male(mdat
)) {
3304 mtmp
->female
= FALSE
;
3305 } else if (is_female(mdat
)) {
3307 mtmp
->female
= TRUE
;
3308 } else if (!is_neuter(mdat
)) {
3310 mtmp
->female
= !mtmp
->female
;
3314 /* make a chameleon take on another shape, or a polymorph target
3315 (possibly self-inflicted) become a different monster;
3316 returns 1 if it actually changes form */
3318 newcham(mtmp
, mdat
, polyspot
, msg
)
3320 struct permonst
*mdat
;
3321 boolean polyspot
; /* change is the result of wand or spell of polymorph */
3322 boolean msg
; /* "The oldmon turns into a newmon!" */
3326 struct permonst
*olddata
= mtmp
->data
;
3327 char *p
, oldname
[BUFSZ
], l_oldname
[BUFSZ
], newname
[BUFSZ
];
3329 /* Riders are immune to polymorph and green slime
3330 (but apparent Rider might actually be a doppelganger) */
3331 if (mtmp
->cham
== NON_PM
) { /* not a shapechanger */
3332 if (is_rider(olddata
))
3334 /* make Nazgul and erinyes immune too, to reduce chance of
3335 anomalous extinction feedback during final disclsoure */
3336 if (mbirth_limit(monsndx(olddata
)) < MAXMONNO
)
3341 /* like Monnam() but never mention saddle */
3342 Strcpy(oldname
, x_monnam(mtmp
, ARTICLE_THE
, (char *) 0,
3343 SUPPRESS_SADDLE
, FALSE
));
3344 oldname
[0] = highc(oldname
[0]);
3346 /* we need this one whether msg is true or not */
3347 Strcpy(l_oldname
, x_monnam(mtmp
, ARTICLE_THE
, (char *) 0,
3348 has_mname(mtmp
) ? SUPPRESS_SADDLE
: 0, FALSE
));
3350 /* mdat = 0 -> caller wants a random monster shape */
3352 /* select_newcham_form() loops when resorting to random but
3353 it doesn't always pick that so we still retry here too */
3356 mndx
= select_newcham_form(mtmp
);
3357 mdat
= accept_newcham_form(mndx
);
3358 /* for the first several tries we require upper-case on
3359 the rogue level (after that, we take whatever we get) */
3360 if (tryct
> 15 && Is_rogue_level(&u
.uz
)
3361 && mdat
&& !isupper((uchar
) mdat
->mlet
))
3365 } while (--tryct
> 0);
3368 } else if (mvitals
[monsndx(mdat
)].mvflags
& G_GENOD
)
3369 return 0; /* passed in mdat is genocided */
3371 if (mdat
== olddata
)
3372 return 0; /* still the same monster */
3374 mgender_from_permonst(mtmp
, mdat
);
3375 /* Endgame mplayers start out as "Foo the Bar", but some of the
3376 * titles are inappropriate when polymorphed, particularly into
3377 * the opposite sex. Player characters don't use ranks when
3378 * polymorphed, so dropping rank for mplayers seems reasonable.
3380 if (In_endgame(&u
.uz
) && is_mplayer(olddata
)
3381 && has_mname(mtmp
) && (p
= strstr(MNAME(mtmp
), " the ")) != 0)
3384 if (mtmp
->wormno
) { /* throw tail away */
3386 place_monster(mtmp
, mtmp
->mx
, mtmp
->my
);
3388 if (mtmp
->m_ap_type
&& mdat
->mlet
!= S_MIMIC
)
3389 seemimic(mtmp
); /* revert to normal monster */
3391 /* (this code used to try to adjust the monster's health based on
3392 a normal one of its type but there are too many special cases
3393 which need to handled in order to do that correctly, so just
3394 give the new form the same proportion of HP as its old one had) */
3397 /* set level and hit points */
3398 newmonhp(mtmp
, monsndx(mdat
));
3399 /* new hp: same fraction of max as before */
3401 mtmp
->mhp
= (int) (((long) hpn
* (long) mtmp
->mhp
) / (long) hpd
);
3403 /* sanity check (potential overflow) */
3404 if (mtmp
->mhp
< 0 || mtmp
->mhp
> mtmp
->mhpmax
)
3405 mtmp
->mhp
= mtmp
->mhpmax
;
3406 /* unlikely but not impossible; a 1HD creature with 1HP that changes
3407 into a 0HD creature will require this statement */
3411 /* take on the new form... */
3412 set_mon_data(mtmp
, mdat
, 0);
3414 if (emits_light(olddata
) != emits_light(mtmp
->data
)) {
3415 /* used to give light, now doesn't, or vice versa,
3416 or light's range has changed */
3417 if (emits_light(olddata
))
3418 del_light_source(LS_MONSTER
, monst_to_any(mtmp
));
3419 if (emits_light(mtmp
->data
))
3420 new_light_source(mtmp
->mx
, mtmp
->my
, emits_light(mtmp
->data
),
3421 LS_MONSTER
, monst_to_any(mtmp
));
3423 if (!mtmp
->perminvis
|| pm_invisible(olddata
))
3424 mtmp
->perminvis
= pm_invisible(mdat
);
3425 mtmp
->minvis
= mtmp
->invis_blkd
? 0 : mtmp
->perminvis
;
3426 if (mtmp
->mundetected
)
3427 (void) hideunder(mtmp
);
3428 if (u
.ustuck
== mtmp
) {
3430 if (!attacktype(mdat
, AT_ENGL
)) {
3431 /* Does mdat care? */
3432 if (!noncorporeal(mdat
) && !amorphous(mdat
)
3433 && !is_whirly(mdat
) && (mdat
!= &mons
[PM_YELLOW_LIGHT
])) {
3434 char msgtrail
[BUFSZ
];
3436 if (is_vampshifter(mtmp
)) {
3437 Sprintf(msgtrail
, " which was a shapeshifted %s",
3439 } else if (is_animal(mdat
)) {
3440 Strcpy(msgtrail
, "'s stomach");
3445 /* Do this even if msg is FALSE */
3447 (amorphous(olddata
) || is_whirly(olddata
))
3448 ? "emerge from" : "break out of",
3449 l_oldname
, msgtrail
);
3450 msg
= FALSE
; /* message has been given */
3451 mtmp
->mhp
= 1; /* almost dead */
3453 expels(mtmp
, olddata
, FALSE
);
3455 /* update swallow glyphs for new monster */
3458 } else if (!sticks(mdat
) && !sticks(youmonst
.data
))
3463 if (mdat
== &mons
[PM_LONG_WORM
] && (mtmp
->wormno
= get_wormno()) != 0) {
3465 /* DICE 3.0 doesn't like assigning and comparing mtmp->wormno in the
3468 if (mdat
== &mons
[PM_LONG_WORM
]
3469 && (mtmp
->wormno
= get_wormno(), mtmp
->wormno
!= 0)) {
3471 /* we can now create worms with tails - 11/91 */
3472 initworm(mtmp
, rn2(5));
3473 if (count_wsegs(mtmp
))
3474 place_worm_tail_randomly(mtmp
, mtmp
->mx
, mtmp
->my
);
3477 newsym(mtmp
->mx
, mtmp
->my
);
3480 char *save_mname
= 0;
3482 if (has_mname(mtmp
)) {
3483 save_mname
= MNAME(mtmp
);
3484 MNAME(mtmp
) = (char *) 0;
3486 Strcpy(newname
, (mdat
== &mons
[PM_GREEN_SLIME
])
3488 : x_monnam(mtmp
, ARTICLE_A
, (char *) 0,
3489 SUPPRESS_SADDLE
, FALSE
));
3490 /* oldname was capitalized above; newname will be lower case */
3491 if (!strcmpi(newname
, "it")) { /* can't see or sense it now */
3492 if (!!strcmpi(oldname
, "it")) /* could see or sense it before */
3493 pline("%s disappears!", oldname
);
3494 (void) usmellmon(mdat
);
3495 } else { /* can see or sense it now */
3496 if (!strcmpi(oldname
, "it")) /* couldn't see or sense it before */
3497 pline("%s appears!", upstart(newname
));
3499 pline("%s turns into %s!", oldname
, newname
);
3502 MNAME(mtmp
) = save_mname
;
3505 /* when polymorph trap/wand/potion produces a vampire, turn in into
3506 a full-fledged vampshifter unless shape-changing is blocked */
3507 if (mtmp
->cham
== NON_PM
&& mdat
->mlet
== S_VAMPIRE
3508 && !Protection_from_shape_changers
)
3509 mtmp
->cham
= pm_to_cham(monsndx(mdat
));
3511 possibly_unwield(mtmp
, polyspot
); /* might lose use of weapon */
3512 mon_break_armor(mtmp
, polyspot
);
3513 if (!(mtmp
->misc_worn_check
& W_ARMG
))
3514 mselftouch(mtmp
, "No longer petrify-resistant, ",
3515 !context
.mon_moving
);
3516 m_dowear(mtmp
, FALSE
);
3518 /* This ought to re-test can_carry() on each item in the inventory
3519 * rather than just checking ex-giants & boulders, but that'd be
3520 * pretty expensive to perform. If implemented, then perhaps
3521 * minvent should be sorted in order to drop heaviest items first.
3523 /* former giants can't continue carrying boulders */
3524 if (mtmp
->minvent
&& !throws_rocks(mdat
)) {
3525 register struct obj
*otmp
, *otmp2
;
3527 for (otmp
= mtmp
->minvent
; otmp
; otmp
= otmp2
) {
3529 if (otmp
->otyp
== BOULDER
) {
3530 /* this keeps otmp from being polymorphed in the
3531 same zap that the monster that held it is polymorphed */
3534 obj_extract_self(otmp
);
3535 /* probably ought to give some "drop" message here */
3536 if (flooreffects(otmp
, mtmp
->mx
, mtmp
->my
, ""))
3538 place_object(otmp
, mtmp
->mx
, mtmp
->my
);
3546 /* sometimes an egg will be special */
3547 #define BREEDER_EGG (!rn2(77))
3550 * Determine if the given monster number can be hatched from an egg.
3551 * Return the monster number to use as the egg's corpsenm. Return
3552 * NON_PM if the given monster can't be hatched.
3555 can_be_hatched(mnum
)
3558 /* ranger quest nemesis has the oviparous bit set, making it
3559 be possible to wish for eggs of that unique monster; turn
3560 such into ordinary eggs rather than forbidding them outright */
3561 if (mnum
== PM_SCORPIUS
)
3564 mnum
= little_to_big(mnum
);
3566 * Queen bees lay killer bee eggs (usually), but killer bees don't
3567 * grow into queen bees. Ditto for [winged-]gargoyles.
3569 if (mnum
== PM_KILLER_BEE
|| mnum
== PM_GARGOYLE
3570 || (lays_eggs(&mons
[mnum
])
3572 || (mnum
!= PM_QUEEN_BEE
&& mnum
!= PM_WINGED_GARGOYLE
))))
3577 /* type of egg laid by #sit; usually matches parent */
3579 egg_type_from_parent(mnum
, force_ordinary
)
3580 int mnum
; /* parent monster; caller must handle lays_eggs() check */
3581 boolean force_ordinary
;
3583 if (force_ordinary
|| !BREEDER_EGG
) {
3584 if (mnum
== PM_QUEEN_BEE
)
3585 mnum
= PM_KILLER_BEE
;
3586 else if (mnum
== PM_WINGED_GARGOYLE
)
3592 /* decide whether an egg of the indicated monster type is viable;
3593 also used to determine whether an egg or tin can be created... */
3595 dead_species(m_idx
, egg
)
3601 /* generic eggs are unhatchable and have corpsenm of NON_PM */
3605 * For monsters with both baby and adult forms, genociding either
3606 * form kills all eggs of that monster. Monsters with more than
3607 * two forms (small->large->giant mimics) are more or less ignored;
3608 * fortunately, none of them have eggs. Species extinction due to
3609 * overpopulation does not kill eggs.
3611 alt_idx
= egg
? big_to_little(m_idx
) : m_idx
;
3612 return (boolean
) ((mvitals
[m_idx
].mvflags
& G_GENOD
) != 0
3613 || (mvitals
[alt_idx
].mvflags
& G_GENOD
) != 0);
3616 /* kill off any eggs of genocided monsters */
3619 struct obj
*obj_list
;
3623 for (otmp
= obj_list
; otmp
; otmp
= otmp
->nobj
)
3624 if (otmp
->otyp
== EGG
) {
3625 if (dead_species(otmp
->corpsenm
, TRUE
)) {
3627 * It seems we could also just catch this when
3628 * it attempted to hatch, so we wouldn't have to
3629 * search all of the objlists.. or stop all
3630 * hatch timers based on a corpsenm.
3634 #if 0 /* not used */
3635 } else if (otmp
->otyp
== TIN
) {
3636 if (dead_species(otmp
->corpsenm
, FALSE
))
3637 otmp
->corpsenm
= NON_PM
; /* empty tin */
3638 } else if (otmp
->otyp
== CORPSE
) {
3639 if (dead_species(otmp
->corpsenm
, FALSE
))
3640 ; /* not yet implemented... */
3642 } else if (Has_contents(otmp
)) {
3643 kill_eggs(otmp
->cobj
);
3647 /* kill all members of genocided species */
3649 kill_genocided_monsters()
3651 struct monst
*mtmp
, *mtmp2
;
3656 * Called during genocide, and again upon level change. The latter
3657 * catches up with any migrating monsters as they finally arrive at
3658 * their intended destinations, so possessions get deposited there.
3660 * Chameleon handling:
3661 * 1) if chameleons have been genocided, destroy them
3662 * regardless of current form;
3663 * 2) otherwise, force every chameleon which is imitating
3664 * any genocided species to take on a new form.
3666 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp2
) {
3668 if (DEADMONSTER(mtmp
))
3670 mndx
= monsndx(mtmp
->data
);
3671 kill_cham
= (mtmp
->cham
>= LOW_PM
3672 && (mvitals
[mtmp
->cham
].mvflags
& G_GENOD
));
3673 if ((mvitals
[mndx
].mvflags
& G_GENOD
) || kill_cham
) {
3674 if (mtmp
->cham
>= LOW_PM
&& !kill_cham
)
3675 (void) newcham(mtmp
, (struct permonst
*) 0, FALSE
, FALSE
);
3680 kill_eggs(mtmp
->minvent
);
3685 kill_eggs(migrating_objs
);
3686 kill_eggs(level
.buriedobjlist
);
3690 golemeffects(mon
, damtype
, dam
)
3691 register struct monst
*mon
;
3694 int heal
= 0, slow
= 0;
3696 if (mon
->data
== &mons
[PM_FLESH_GOLEM
]) {
3697 if (damtype
== AD_ELEC
)
3698 heal
= (dam
+ 5) / 6;
3699 else if (damtype
== AD_FIRE
|| damtype
== AD_COLD
)
3701 } else if (mon
->data
== &mons
[PM_IRON_GOLEM
]) {
3702 if (damtype
== AD_ELEC
)
3704 else if (damtype
== AD_FIRE
)
3710 if (mon
->mspeed
!= MSLOW
)
3711 mon_adjust_speed(mon
, -1, (struct obj
*) 0);
3714 if (mon
->mhp
< mon
->mhpmax
) {
3716 if (mon
->mhp
> mon
->mhpmax
)
3717 mon
->mhp
= mon
->mhpmax
;
3718 if (cansee(mon
->mx
, mon
->my
))
3719 pline("%s seems healthier.", Monnam(mon
));
3725 angry_guards(silent
)
3729 int ct
= 0, nct
= 0, sct
= 0, slct
= 0;
3731 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
3732 if (DEADMONSTER(mtmp
))
3734 if (is_watch(mtmp
->data
) && mtmp
->mpeaceful
) {
3736 if (cansee(mtmp
->mx
, mtmp
->my
) && mtmp
->mcanmove
) {
3737 if (distu(mtmp
->mx
, mtmp
->my
) == 2)
3742 if (mtmp
->msleeping
|| mtmp
->mfrozen
) {
3744 mtmp
->msleeping
= mtmp
->mfrozen
= 0;
3746 mtmp
->mpeaceful
= 0;
3750 if (!silent
) { /* do we want pline msgs? */
3752 pline_The("guard%s wake%s up!", slct
> 1 ? "s" : "",
3753 slct
== 1 ? "s" : "");
3756 pline_The("guard%s get%s angry!", nct
== 1 ? "" : "s",
3757 nct
== 1 ? "s" : "");
3759 You_see("%sangry guard%s approaching!",
3760 sct
== 1 ? "an " : "", sct
> 1 ? "s" : "");
3762 You_hear("the shrill sound of a guard's whistle.");
3774 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
3775 if (DEADMONSTER(mtmp
))
3777 if (is_watch(mtmp
->data
))
3778 mtmp
->mpeaceful
= 1;
3783 mimic_hit_msg(mtmp
, otyp
)
3787 short ap
= mtmp
->mappearance
;
3789 switch (mtmp
->m_ap_type
) {
3791 case M_AP_FURNITURE
:
3795 if (otyp
== SPE_HEALING
|| otyp
== SPE_EXTRA_HEALING
) {
3796 pline("%s seems a more vivid %s than before.",
3797 The(simple_typename(ap
)),
3798 c_obj_colors
[objects
[ap
].oc_color
]);
3806 struct permonst
*mdat
;
3809 boolean nonspecific
= FALSE
;
3810 boolean msg_given
= FALSE
;
3813 if (!olfaction(youmonst
.data
))
3815 mndx
= monsndx(mdat
);
3819 You("notice a bovine smell.");
3825 case PM_NEANDERTHAL
:
3826 You("smell body odor.");
3835 case PM_HORNED_DEVIL
:
3842 case PM_HUMAN_WEREJACKAL
:
3843 case PM_HUMAN_WERERAT
:
3844 case PM_HUMAN_WEREWOLF
:
3849 You("detect an odor reminiscent of an animal's den.");
3853 case PM_PURPLE_WORM:
3856 case PM_STEAM_VORTEX
:
3857 You("smell steam.");
3860 case PM_GREEN_SLIME
:
3861 pline("%s stinks.", Something
);
3864 case PM_VIOLET_FUNGUS
:
3866 You("smell mushrooms.");
3869 /* These are here to avoid triggering the
3870 nonspecific treatment through the default case below*/
3871 case PM_WHITE_UNICORN
:
3872 case PM_GRAY_UNICORN
:
3873 case PM_BLACK_UNICORN
:
3882 switch (mdat
->mlet
) {
3884 You("notice a dog smell.");
3888 You("smell a dragon!");
3892 pline("%s smells moldy.", Something
);
3896 You("detect a%s odor reminiscent of a stable.",
3897 (mndx
== PM_PONY
) ? "n" : " strong");
3901 You("smell rotting flesh.");
3909 if (maybe_polyd(is_orc(youmonst
.data
), Race_if(PM_ORC
)))
3910 You("notice an attractive smell.");
3912 pline("A foul stench makes you feel a little nauseated.");
3919 return msg_given
? TRUE
: FALSE
;