1 /* NetHack 3.6 mon.c $NHDT-Date: 1569276991 2019/09/23 22:16:31 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.297 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Derek S. Ray, 2015. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2021 */
9 /* JNetHack may be freely redistributed. See license for details. */
11 /* If you're using precompiled headers, you don't want this either */
20 STATIC_VAR boolean vamp_rise_msg, disintegested;
22 STATIC_DCL void FDECL(sanity_check_single_mon, (struct monst *, BOOLEAN_P,
24 STATIC_DCL boolean FDECL(restrap, (struct monst *));
25 STATIC_DCL long FDECL(mm_aggression, (struct monst *, struct monst *));
26 STATIC_DCL long FDECL(mm_displacement, (struct monst *, struct monst *));
27 STATIC_DCL int NDECL(pick_animal);
28 STATIC_DCL void FDECL(kill_eggs, (struct obj *));
29 STATIC_DCL int FDECL(pickvampshape, (struct monst *));
30 STATIC_DCL boolean FDECL(isspecmon, (struct monst *));
31 STATIC_DCL boolean FDECL(validspecmon, (struct monst *, int));
32 STATIC_DCL struct permonst *FDECL(accept_newcham_form, (struct monst *, int));
33 STATIC_DCL struct obj *FDECL(make_corpse, (struct monst *, unsigned));
34 STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *));
35 STATIC_DCL void FDECL(lifesaved_monster, (struct monst *));
36 STATIC_DCL void FDECL(migrate_mon, (struct monst *, XCHAR_P, XCHAR_P));
37 STATIC_DCL boolean FDECL(ok_to_obliterate, (struct monst *));
38 STATIC_DCL void FDECL(deal_with_overcrowding, (struct monst *));
40 /* note: duplicated in dog.c */
41 #define LEVEL_SPECIFIC_NOCORPSE(mdat) \
42 (Is_rogue_level(&u.uz) \
43 || (level.flags.graveyard && is_undead(mdat) && rn2(3)))
46 /* part of the original warning code which was replaced in 3.3.1 */
47 const char *warnings[] = {
49 "white", "pink", "red", "ruby", "purple", "black"
51 "
\94\92\82¢", "
\83s
\83\93\83N
\90F
\82Ì", "
\90Ô
\82¢", "
\83\8b\83r
\81[
\90F
\82Ì", "
\8e\87\82Ì", "
\8d\95\82¢"
57 sanity_check_single_mon(mtmp, chk_geno, msg)
62 if (mtmp->data < &mons[LOW_PM] || mtmp->data >= &mons[NUMMONS]) {
63 impossible("illegal mon data %s; mnum=%d (%s)",
64 fmt_ptr((genericptr_t) mtmp->data), mtmp->mnum, msg);
66 int mndx = monsndx(mtmp->data);
68 if (mtmp->mnum != mndx) {
69 impossible("monster mnum=%d, monsndx=%d (%s)",
70 mtmp->mnum, mndx, msg);
73 if (DEADMONSTER(mtmp)) {
75 /* bad if not fmons list or if not vault guard */
76 if (strcmp(msg, "fmon") || !mtmp->isgd)
77 impossible("dead monster on %s; %s at <%d,%d>",
78 msg, mons[mndx].mname, mtmp->mx, mtmp->my);
82 if (chk_geno && (mvitals[mndx].mvflags & G_GENOD) != 0)
83 impossible("genocided %s in play (%s)", mons[mndx].mname, msg);
85 if (mtmp->isshk && !has_eshk(mtmp))
86 impossible("shk without eshk (%s)", msg);
87 if (mtmp->ispriest && !has_epri(mtmp))
88 impossible("priest without epri (%s)", msg);
89 if (mtmp->isgd && !has_egd(mtmp))
90 impossible("guard without egd (%s)", msg);
91 if (mtmp->isminion && !has_emin(mtmp))
92 impossible("minion without emin (%s)", msg);
93 /* guardian angel on astral level is tame but has emin rather than edog */
94 if (mtmp->mtame && !has_edog(mtmp) && !mtmp->isminion)
95 impossible("pet without edog (%s)", msg);
102 struct monst *mtmp, *m;
104 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
105 /* dead monsters should still have sane data */
106 sanity_check_single_mon(mtmp, TRUE, "fmon");
107 if (DEADMONSTER(mtmp) && !mtmp->isgd)
110 x = mtmp->mx, y = mtmp->my;
111 if (!isok(x, y) && !(mtmp->isgd && x == 0 && y == 0)) {
112 impossible("mon (%s) claims to be at <%d,%d>?",
113 fmt_ptr((genericptr_t) mtmp), x, y);
114 } else if (mtmp == u.usteed) {
115 /* steed is in fmon list but not on the map; its
116 <mx,my> coordinates should match hero's location */
117 if (x != u.ux || y != u.uy)
118 impossible("steed (%s) claims to be at <%d,%d>?",
119 fmt_ptr((genericptr_t) mtmp), x, y);
120 } else if (level.monsters[x][y] != mtmp) {
121 impossible("mon (%s) at <%d,%d> is not there!",
122 fmt_ptr((genericptr_t) mtmp), x, y);
123 } else if (mtmp->wormno) {
124 sanity_check_worm(mtmp);
128 for (x = 1; x < COLNO; x++)
129 for (y = 0; y < ROWNO; y++)
130 if ((mtmp = level.monsters[x][y]) != 0) {
131 for (m = fmon; m; m = m->nmon)
135 impossible("map mon (%s) at <%d,%d> not in fmon list!",
136 fmt_ptr((genericptr_t) mtmp), x, y);
137 else if (mtmp == u.usteed)
138 impossible("steed (%s) is on the map at <%d,%d>!",
139 fmt_ptr((genericptr_t) mtmp), x, y);
140 else if ((mtmp->mx != x || mtmp->my != y)
141 && mtmp->data != &mons[PM_LONG_WORM])
142 impossible("map mon (%s) at <%d,%d> is found at <%d,%d>?",
143 fmt_ptr((genericptr_t) mtmp),
144 mtmp->mx, mtmp->my, x, y);
147 for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon) {
148 sanity_check_single_mon(mtmp, FALSE, "migr");
153 /* convert the monster index of an undead to its living counterpart */
155 undead_to_corpse(mndx)
159 case PM_KOBOLD_ZOMBIE:
160 case PM_KOBOLD_MUMMY:
163 case PM_DWARF_ZOMBIE:
167 case PM_GNOME_ZOMBIE:
180 case PM_VAMPIRE_LORD:
182 case PM_VAMPIRE_MAGE:
184 case PM_HUMAN_ZOMBIE:
188 case PM_GIANT_ZOMBIE:
192 case PM_ETTIN_ZOMBIE:
202 /* Convert the monster index of some monsters (such as quest guardians)
203 * to their generic species type.
205 * Return associated character class monster, rather than species
213 /* Quest guardians */
215 mndx = mode ? PM_ARCHEOLOGIST : PM_HUMAN;
218 mndx = mode ? PM_BARBARIAN : PM_HUMAN;
221 mndx = mode ? PM_CAVEMAN : PM_HUMAN;
224 mndx = mode ? PM_HEALER : PM_HUMAN;
227 mndx = mode ? PM_KNIGHT : PM_HUMAN;
230 mndx = mode ? PM_MONK : PM_HUMAN;
233 mndx = mode ? PM_PRIEST : PM_HUMAN;
236 mndx = mode ? PM_RANGER : PM_HUMAN;
239 mndx = mode ? PM_ROGUE : PM_HUMAN;
242 mndx = mode ? PM_SAMURAI : PM_HUMAN;
245 mndx = mode ? PM_TOURIST : PM_HUMAN;
248 mndx = mode ? PM_WIZARD : PM_HUMAN;
251 mndx = mode ? PM_VALKYRIE : PM_HUMAN;
254 if (mndx >= LOW_PM && mndx < NUMMONS) {
255 struct permonst *ptr = &mons[mndx];
259 else if (is_elf(ptr))
261 else if (is_dwarf(ptr))
263 else if (is_gnome(ptr))
265 else if (is_orc(ptr))
273 /* return monster index if chameleon, or NON_PM if not */
281 * As of 3.6.0 we just check M2_SHAPESHIFTER instead of having a
282 * big switch statement with hardcoded shapeshifter types here.
284 if (mndx >= LOW_PM && is_shapeshifter(&mons[mndx]))
289 /* for deciding whether corpse will carry along full monster data */
290 #define KEEPTRAITS(mon) \
291 ((mon)->isshk || (mon)->mtame || unique_corpstat((mon)->data) \
292 || is_reviver((mon)->data) \
293 /* normally quest leader will be unique, */ \
294 /* but he or she might have been polymorphed */ \
295 || (mon)->m_id == quest_status.leader_m_id \
296 /* special cancellation handling for these */ \
297 || (dmgtype((mon)->data, AD_SEDU) || dmgtype((mon)->data, AD_SSEX)))
299 /* Creates a monster corpse, a "special" corpse, or nothing if it doesn't
300 * leave corpses. Monsters which leave "special" corpses should have
301 * G_NOCORPSE set in order to prevent wishing for one, finding tins of one,
304 STATIC_OVL struct obj *
305 make_corpse(mtmp, corpseflags)
306 register struct monst *mtmp;
307 unsigned corpseflags;
309 register struct permonst *mdat = mtmp->data;
311 struct obj *obj = (struct obj *) 0;
312 struct obj *otmp = (struct obj *) 0;
313 int x = mtmp->mx, y = mtmp->my;
314 int mndx = monsndx(mdat);
315 unsigned corpstatflags = corpseflags;
316 boolean burythem = ((corpstatflags & CORPSTAT_BURIED) != 0);
320 case PM_SILVER_DRAGON:
322 case PM_SHIMMERING_DRAGON:
325 case PM_ORANGE_DRAGON:
326 case PM_WHITE_DRAGON:
327 case PM_BLACK_DRAGON:
329 case PM_GREEN_DRAGON:
330 case PM_YELLOW_DRAGON:
331 /* Make dragon scales. This assumes that the order of the
332 dragons is the same as the order of the scales. */
333 if (!rn2(mtmp->mrevived ? 20 : 3)) {
334 num = GRAY_DRAGON_SCALES + monsndx(mdat) - PM_GRAY_DRAGON;
335 obj = mksobj_at(num, x, y, FALSE, FALSE);
337 obj->cursed = obj->blessed = FALSE;
340 case PM_WHITE_UNICORN:
341 case PM_GRAY_UNICORN:
342 case PM_BLACK_UNICORN:
343 if (mtmp->mrevived && rn2(2)) {
346 pline("%s recently regrown horn crumbles to dust.",
347 s_suffix(Monnam(mtmp)));
349 pline("
\8dÅ
\8bß
\8dÄ
\90¶
\82µ
\82½%s
\82Ì
\8ap
\82Í
\95²
\81X
\82É
\82È
\82Á
\82½
\81D",
353 obj = mksobj_at(UNICORN_HORN, x, y, TRUE, FALSE);
354 if (obj && mtmp->mrevived)
355 obj->degraded_horn = 1;
359 (void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE);
362 case PM_VAMPIRE_LORD:
363 /* include mtmp in the mkcorpstat() call */
364 num = undead_to_corpse(mndx);
365 corpstatflags |= CORPSTAT_INIT;
366 obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags);
367 obj->age -= 100; /* this is an *OLD* corpse */
369 case PM_KOBOLD_MUMMY:
377 case PM_KOBOLD_ZOMBIE:
378 case PM_DWARF_ZOMBIE:
379 case PM_GNOME_ZOMBIE:
382 case PM_HUMAN_ZOMBIE:
383 case PM_GIANT_ZOMBIE:
384 case PM_ETTIN_ZOMBIE:
385 num = undead_to_corpse(mndx);
386 corpstatflags |= CORPSTAT_INIT;
387 obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags);
388 obj->age -= 100; /* this is an *OLD* corpse */
393 obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE);
394 free_mname(mtmp); /* don't christen obj */
397 num = d(2, 4); /* very low chance of creating all glass gems */
399 obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE);
403 obj = mksobj_at(ROCK, x, y, FALSE, FALSE);
404 obj->quan = (long) (rn2(20) + 50);
405 obj->owt = weight(obj);
409 corpstatflags &= ~CORPSTAT_INIT;
411 mkcorpstat(STATUE, (struct monst *) 0, mdat, x, y, corpstatflags);
416 obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE);
420 case PM_LEATHER_GOLEM:
423 obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE);
427 /* Good luck gives more coins */
428 obj = mkgold((long) (200 - rnl(101)), x, y);
434 obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE);
437 /* expired puddings will congeal into a large blob;
438 like dragons, relies on the order remaining consistent */
440 case PM_BROWN_PUDDING:
442 case PM_BLACK_PUDDING:
443 /* we have to do this here because most other places
444 expect there to be an object coming back; not this one */
445 obj = mksobj_at(GLOB_OF_BLACK_PUDDING - (PM_BLACK_PUDDING - mndx),
448 while (obj && (otmp = obj_nexto(obj)) != (struct obj *) 0) {
449 pudding_merge_message(obj, otmp);
450 obj = obj_meld(&obj, &otmp);
456 if (mvitals[mndx].mvflags & G_NOCORPSE) {
457 return (struct obj *) 0;
459 corpstatflags |= CORPSTAT_INIT;
460 /* preserve the unique traits of some creatures */
461 obj = mkcorpstat(CORPSE, KEEPTRAITS(mtmp) ? mtmp : 0,
462 mdat, x, y, corpstatflags);
466 (void) bury_an_obj(obj, &dealloc);
468 return dealloc ? (struct obj *) 0 : obj;
473 /* All special cases should precede the G_NOCORPSE check */
476 return (struct obj *) 0;
478 /* if polymorph or undead turning has killed this monster,
479 prevent the same attack beam from hitting its corpse */
480 if (context.bypasses)
484 obj = oname(obj, MNAME(mtmp));
486 /* Avoid "It was hidden under a green mold corpse!"
487 * during Blind combat. An unseen monster referred to as "it"
488 * could be killed and leave a corpse. If a hider then hid
489 * underneath it, you could be told the corpse type of a
490 * monster that you never knew was there without this.
491 * The code in hitmu() substitutes the word "something"
492 * if the corpse's obj->dknown is 0.
494 if (Blind && !sensemon(mtmp))
502 /* check mtmp and water/lava for compatibility, 0 (survived), 1 (died) */
505 register struct monst *mtmp;
507 boolean inpool, inlava, infountain;
509 /* [ceiling clingers are handled below] */
510 inpool = (is_pool(mtmp->mx, mtmp->my)
511 && (!(is_flyer(mtmp->data) || is_floater(mtmp->data))
512 /* there's no "above the surface" on the plane of water */
513 || Is_waterlevel(&u.uz)));
514 inlava = (is_lava(mtmp->mx, mtmp->my)
515 && !(is_flyer(mtmp->data) || is_floater(mtmp->data)));
516 infountain = IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ);
518 /* Flying and levitation keeps our steed out of the liquid
519 (but not water-walking or swimming; note: if hero is in a
520 water location on the Plane of Water, flight and levitating
521 are blocked so this (Flying || Levitation) test fails there
522 and steed will be subject to water effects, as intended) */
523 if (mtmp == u.usteed && (Flying || Levitation))
526 /* Gremlin multiplying won't go on forever since the hit points
527 * keep going down, and when it gets to 1 hit point the clone
528 * function will fail.
530 if (mtmp->data == &mons[PM_GREMLIN] && (inpool || infountain) && rn2(3)) {
531 if (split_mon(mtmp, (struct monst *) 0))
532 dryup(mtmp->mx, mtmp->my, FALSE);
534 water_damage_chain(mtmp->minvent, FALSE);
536 } else if (mtmp->data == &mons[PM_IRON_GOLEM] && inpool && !rn2(5)) {
539 if (cansee(mtmp->mx, mtmp->my))
541 pline("%s rusts.", Monnam(mtmp));
543 pline("%s
\82Í
\8eK
\82Ñ
\82½
\81D", Monnam(mtmp));
545 if (mtmp->mhpmax > dam)
547 if (DEADMONSTER(mtmp)) {
549 if (DEADMONSTER(mtmp))
552 water_damage_chain(mtmp->minvent, FALSE);
558 * Lava effects much as water effects. Lava likers are able to
559 * protect their stuff. Fire resistant monsters can only protect
562 if (!is_clinger(mtmp->data) && !likes_lava(mtmp->data)) {
563 /* not fair...? hero doesn't automatically teleport away
564 from lava, just from water */
565 if (can_teleport(mtmp->data) && !tele_restrict(mtmp)) {
566 if (rloc(mtmp, TRUE))
569 if (!resists_fire(mtmp)) {
570 if (cansee(mtmp->mx, mtmp->my)) {
571 struct attack *dummy = &mtmp->data->mattk[0];
572 const char *how = on_fire(mtmp->data, dummy);
575 pline("%s %s.", Monnam(mtmp),
576 !strcmp(how, "boiling") ? "boils away"
577 : !strcmp(how, "melting") ? "melts away"
578 : "burns to a crisp");
579 #else /*mon.c:on_fire()
\82Ì
\95Ô
\82è
\92l*/
580 pline("%s
\82Í%s
\82½
\81D", Monnam(mtmp),
581 !strcmp(how, "
\95¦
\93«
\82µ
\82½") ? "
\95¦
\93«
\82µ"
582 : !strcmp(how, "
\97n
\82¯
\82½") ? "
\97n
\82¯
\82½"
583 : "
\94R
\82¦
\82Ä
\83p
\83\8a\83p
\83\8a\82É
\82È
\82Á");
586 /* unlike fire -> melt ice -> pool, there's no way for the
587 hero to create lava beneath a monster, so the !mon_moving
588 case is not expected to happen (and we haven't made a
589 player-against-monster variation of the message above) */
590 if (context.mon_moving)
593 xkilled(mtmp, XKILL_NOMSG);
596 if (DEADMONSTER(mtmp)) {
597 if (cansee(mtmp->mx, mtmp->my))
599 pline("%s surrenders to the fire.", Monnam(mtmp));
601 pline("%s
\82Í
\89\8a\82É
\93Û
\82Ü
\82ê
\82½
\81D", Monnam(mtmp));
603 } else if (cansee(mtmp->mx, mtmp->my))
605 pline("%s burns slightly.", Monnam(mtmp));
607 pline("%s
\82Í
\82¿
\82å
\82Á
\82Æ
\8fÅ
\82°
\82½
\81D", Monnam(mtmp));
609 if (!DEADMONSTER(mtmp)) {
610 (void) fire_damage_chain(mtmp->minvent, FALSE, FALSE,
612 (void) rloc(mtmp, FALSE);
618 /* Most monsters drown in pools. flooreffects() will take care of
619 * water damage to dead monsters' inventory, but survivors need to
620 * be handled here. Swimmers are able to protect their stuff...
622 if (!is_clinger(mtmp->data) && !is_swimmer(mtmp->data)
623 && !amphibious(mtmp->data)) {
624 /* like hero with teleport intrinsic or spell, teleport away
626 if (can_teleport(mtmp->data) && !tele_restrict(mtmp)) {
627 if (rloc(mtmp, TRUE))
630 if (cansee(mtmp->mx, mtmp->my)) {
631 if (context.mon_moving)
633 pline("%s drowns.", Monnam(mtmp));
635 pline("%s
\82Í
\93M
\82ê
\82½
\81D", Monnam(mtmp));
637 /* hero used fire to melt ice that monster was on */
639 You("drown %s.", mon_nam(mtmp));
641 You("%s
\82É
\93M
\82ê
\82½
\81D", mon_nam(mtmp));
643 if (u.ustuck && u.uswallow && u.ustuck == mtmp) {
644 /* This can happen after a purple worm plucks you off a
645 flying steed while you are over water. */
647 pline("%s sinks as %s rushes in and flushes you out.",
648 Monnam(mtmp), hliquid("water"));
649 #else /*hliquid
\82Í
\95s
\8e©
\91R
\82É
\82È
\82é
\82Ì
\82Å
\82Æ
\82è
\82 \82¦
\82¸
\8eg
\82í
\82È
\82¢*/
650 pline("%s
\82Í
\90\85\97¬
\82É
\92¾
\82Ý
\81D
\82 \82È
\82½
\82ð
\93f
\82«
\8fo
\82µ
\82½
\81D",
654 if (context.mon_moving)
657 xkilled(mtmp, XKILL_NOMSG);
658 if (!DEADMONSTER(mtmp)) {
659 water_damage_chain(mtmp->minvent, FALSE);
660 if (!rloc(mtmp, TRUE))
661 deal_with_overcrowding(mtmp);
667 /* but eels have a difficult time outside */
668 if (mtmp->data->mlet == S_EEL && !Is_waterlevel(&u.uz)) {
669 /* as mhp gets lower, the rate of further loss slows down */
670 if (mtmp->mhp > 1 && rn2(mtmp->mhp) > rn2(8))
672 monflee(mtmp, 2, FALSE, FALSE);
682 int mmove = mon->data->mmove;
685 /* Note: MSLOW's `+ 1' prevents slowed speed 1 getting reduced to 0;
686 * MFAST's `+ 2' prevents hasted speed 1 from becoming a no-op;
687 * both adjustments have negligible effect on higher speeds.
689 if (mon->mspeed == MSLOW)
690 mmove = (2 * mmove + 1) / 3;
691 else if (mon->mspeed == MFAST)
692 mmove = (4 * mmove + 2) / 3;
694 if (mon == u.usteed && u.ugallop && context.mv) {
695 /* increase movement by a factor of 1.5; also increase variance of
696 movement speed (if it's naturally 24, we don't want it to always
698 mmove = ((rn2(2) ? 4 : 5) * mmove) / 3;
701 /* Randomly round the monster's speed to a multiple of NORMAL_SPEED.
702 This makes it impossible for the player to predict when they'll get
703 a free turn (thus preventing exploits like "melee kiting"), while
704 retaining guarantees about shopkeepers not being outsped by a
705 normal-speed player, normal-speed players being unable to open up
706 a gap when fleeing a normal-speed monster, etc. */
707 mmove_adj = mmove % NORMAL_SPEED;
709 if (rn2(NORMAL_SPEED) < mmove_adj)
710 mmove += NORMAL_SPEED;
715 /* actions that happen once per ``turn'', regardless of each
716 individual monster's metabolism; some of these might need to
717 be reclassified to occur more in proportion with movement rate */
723 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
724 if (DEADMONSTER(mtmp))
727 /* must check non-moving monsters once/turn in case they managed
728 to end up in water or lava; note: when not in liquid they regen,
729 shape-shift, timeout temporary maladies just like other monsters */
730 if (mtmp->data->mmove == 0) {
731 if (vision_full_recalc)
737 /* regenerate hit points */
738 mon_regen(mtmp, FALSE);
740 /* possibly polymorph shapechangers and lycanthropes */
741 if (mtmp->cham >= LOW_PM)
742 decide_to_shapeshift(mtmp, (canspotmon(mtmp)
743 || (u.uswallow && mtmp == u.ustuck))
747 /* gradually time out temporary problems */
748 if (mtmp->mblinded && !--mtmp->mblinded)
750 if (mtmp->mfrozen && !--mtmp->mfrozen)
752 if (mtmp->mfleetim && !--mtmp->mfleetim)
755 /* FIXME: mtmp->mlstmv ought to be updated here */
762 register struct monst *mtmp, *nmtmp;
763 register boolean somebody_can_move = FALSE;
766 * Some of you may remember the former assertion here that
767 * because of deaths and other actions, a simple one-pass
768 * algorithm wasn't possible for movemon. Deaths are no longer
769 * removed to the separate list fdmon; they are simply left in
770 * the chain with hit points <= 0, to be cleaned up at the end
773 * The only other actions which cause monsters to be removed from
774 * the chain are level migrations and losedogs(). I believe losedogs()
775 * is a cleanup routine not associated with monster movements, and
776 * monsters can only affect level migrations on themselves, not others
777 * (hence the fetching of nmon before moving the monster). Currently,
778 * monsters can jump into traps, read cursed scrolls of teleportation,
779 * and drink cursed potions of raise level to change levels. These are
780 * all reflexive at this point. Should one monster be able to level
781 * teleport another, this scheme would have problems.
784 for (mtmp = fmon; mtmp; mtmp = nmtmp) {
785 /* end monster movement early if hero is flagged to leave the level */
788 /* or if the program has lost contact with the user */
789 || program_state.done_hup
792 somebody_can_move = FALSE;
796 /* one dead monster needs to perform a move after death: vault
797 guard whose temporary corridor is still on the map; live
798 guards who have led the hero back to civilization get moved
799 off the map too; gd_move() decides whether the temporary
800 corridor can be removed and guard discarded (via clearing
801 mon->isgd flag so that dmonsfree() will get rid of mon) */
802 if (mtmp->isgd && !mtmp->mx) {
803 /* parked at <0,0>; eventually isgd should get set to false */
804 if (monstermoves > mtmp->mlstmv) {
805 (void) gd_move(mtmp);
806 mtmp->mlstmv = monstermoves;
810 if (DEADMONSTER(mtmp))
813 /* Find a monster that we have not treated yet. */
814 if (mtmp->movement < NORMAL_SPEED)
817 mtmp->movement -= NORMAL_SPEED;
818 if (mtmp->movement >= NORMAL_SPEED)
819 somebody_can_move = TRUE;
821 if (vision_full_recalc)
822 vision_recalc(0); /* vision! */
824 /* reset obj bypasses before next monster moves */
825 if (context.bypasses)
831 /* after losing equipment, try to put on replacement */
832 if (mtmp->misc_worn_check & I_SPECIAL) {
835 mtmp->misc_worn_check &= ~I_SPECIAL;
836 oldworn = mtmp->misc_worn_check;
837 m_dowear(mtmp, FALSE);
838 if (mtmp->misc_worn_check != oldworn || !mtmp->mcanmove)
842 if (is_hider(mtmp->data)) {
843 /* unwatched mimics and piercers may hide again [MRS] */
846 if (M_AP_TYPE(mtmp) == M_AP_FURNITURE
847 || M_AP_TYPE(mtmp) == M_AP_OBJECT)
849 if (mtmp->mundetected)
851 } else if (mtmp->data->mlet == S_EEL && !mtmp->mundetected
852 && (mtmp->mflee || distu(mtmp->mx, mtmp->my) > 2)
853 && !canseemon(mtmp) && !rn2(4)) {
854 /* some eels end up stuck in isolated pools, where they
855 can't--or at least won't--move, so they never reach
856 their post-move chance to re-hide */
861 /* continue if the monster died fighting */
862 if (Conflict && !mtmp->iswiz && mtmp->mcansee) {
864 * Conflict does not take effect in the first round.
865 * Therefore, A monster when stepping into the area will
866 * get to swing at you.
868 * The call to fightm() must be _last_. The monster might
869 * have died if it returns 1.
871 if (couldsee(mtmp->mx, mtmp->my)
872 && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM)
874 continue; /* mon might have died */
876 if (dochugw(mtmp)) /* otherwise just move the monster */
880 if (any_light_source())
881 vision_full_recalc = 1; /* in case a mon moved with a light source */
882 /* reset obj bypasses after last monster has moved */
883 if (context.bypasses)
886 /* remove dead monsters; dead vault guard will be left at <0,0>
887 if temporary corridor out of vault hasn't been removed yet */
890 /* a monster may have levteleported player -dlc */
893 /* changed levels, so these monsters are dormant */
894 somebody_can_move = FALSE;
897 return somebody_can_move;
900 #define mstoning(obj) \
901 (ofood(obj) && (touch_petrifies(&mons[(obj)->corpsenm]) \
902 || (obj)->corpsenm == PM_MEDUSA))
905 * Maybe eat a metallic object (not just gold).
906 * Return value: 0 => nothing happened, 1 => monster ate something,
907 * 2 => monster died (it must have grown into a genocided form, but
908 * that can't happen at present because nothing which eats objects
909 * has young and old forms).
913 register struct monst *mtmp;
915 register struct obj *otmp;
916 struct permonst *ptr;
917 int poly, grow, heal, mstone;
919 /* If a pet, eating is handled separately, in dog.c */
923 /* Eats topmost metal object if it is there */
924 for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp;
925 otmp = otmp->nexthere) {
926 /* Don't eat indigestible/choking/inappropriate objects */
927 if ((mtmp->data == &mons[PM_RUST_MONSTER] && !is_rustprone(otmp))
928 || (otmp->otyp == AMULET_OF_STRANGULATION)
929 || (otmp->otyp == RIN_SLOW_DIGESTION))
931 if (is_metallic(otmp) && !obj_resists(otmp, 5, 95)
932 && touch_artifact(otmp, mtmp)) {
933 if (mtmp->data == &mons[PM_RUST_MONSTER] && otmp->oerodeproof) {
934 if (canseemon(mtmp) && flags.verbose) {
936 pline("%s eats %s!", Monnam(mtmp),
937 distant_name(otmp, doname));
939 pline("%s
\82Í%s
\82ð
\90H
\82×
\82Ä
\82¢
\82é
\81I", Monnam(mtmp),
940 distant_name(otmp,doname));
943 /* The object's rustproofing is gone now */
944 otmp->oerodeproof = 0;
946 if (canseemon(mtmp) && flags.verbose) {
948 pline("%s spits %s out in disgust!", Monnam(mtmp),
949 distant_name(otmp, doname));
951 pline("%s
\82Í%s
\82ð
\83y
\83b
\82Æ
\93f
\82«
\8fo
\82µ
\82½
\81I", Monnam(mtmp),
952 distant_name(otmp,doname));
956 if (cansee(mtmp->mx, mtmp->my) && flags.verbose)
958 pline("%s eats %s!", Monnam(mtmp),
959 distant_name(otmp, doname));
961 pline("%s
\82Í%s
\82ð
\90H
\82×
\82Ä
\82¢
\82é
\81I", Monnam(mtmp),
962 distant_name(otmp,doname));
964 else if (flags.verbose)
966 You_hear("a crunching sound.");
968 You_hear("
\83o
\83\8a\83o
\83\8a\82Æ
\90H
\82×
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D");
969 mtmp->meating = otmp->owt / 2 + 1;
970 /* Heal up to the object's weight in hp */
971 if (mtmp->mhp < mtmp->mhpmax) {
972 mtmp->mhp += objects[otmp->otyp].oc_weight;
973 if (mtmp->mhp > mtmp->mhpmax)
974 mtmp->mhp = mtmp->mhpmax;
979 } else if (otmp == uchain) {
980 unpunish(); /* frees uchain */
982 poly = polyfodder(otmp);
983 grow = mlevelgain(otmp);
984 heal = mhealup(otmp);
985 mstone = mstoning(otmp);
989 if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE))
992 ptr = grow_up(mtmp, (struct monst *) 0);
994 if (poly_when_stoned(ptr)) {
997 } else if (!resists_ston(mtmp)) {
1000 pline("%s turns to stone!", Monnam(mtmp));
1002 pline("%s
\82Í
\90Î
\82É
\82È
\82Á
\82½
\81I", Monnam(mtmp));
1004 ptr = (struct permonst *) 0;
1007 mtmp->mhp = mtmp->mhpmax;
1010 return 2; /* it died */
1012 /* Left behind a pile? */
1014 (void) mksobj_at(ROCK, mtmp->mx, mtmp->my, TRUE, FALSE);
1015 newsym(mtmp->mx, mtmp->my);
1023 /* monster eats a pile of objects */
1025 meatobj(mtmp) /* for gelatinous cubes */
1028 struct obj *otmp, *otmp2;
1029 struct permonst *ptr, *original_ptr = mtmp->data;
1030 int poly, grow, heal, eyes, count = 0, ecount = 0;
1034 /* If a pet, eating is handled separately, in dog.c */
1038 /* eat organic objects, including cloth and wood, if present;
1039 engulf others, except huge rocks and metal attached to player
1040 [despite comment at top, doesn't assume that eater is a g.cube] */
1041 for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
1042 otmp2 = otmp->nexthere;
1044 /* touch sensitive items */
1045 if (otmp->otyp == CORPSE && is_rider(&mons[otmp->corpsenm])) {
1046 /* Rider corpse isn't just inedible; can't engulf it either */
1047 (void) revive_corpse(otmp);
1049 /* untouchable (or inaccessible) items */
1050 } else if ((otmp->otyp == CORPSE
1051 && touch_petrifies(&mons[otmp->corpsenm])
1052 && !resists_ston(mtmp))
1053 /* don't engulf boulders and statues or ball&chain */
1054 || otmp->oclass == ROCK_CLASS
1055 || otmp == uball || otmp == uchain
1056 /* normally mtmp won't have stepped onto scare monster
1057 scroll, but if it does, don't eat or engulf that
1058 (note: scrolls inside eaten containers will still
1060 || otmp->otyp == SCR_SCARE_MONSTER) {
1061 /* do nothing--neither eaten nor engulfed */
1064 /* inedible items -- engulf these */
1065 } else if (!is_organic(otmp) || obj_resists(otmp, 5, 95)
1066 || !touch_artifact(otmp, mtmp)
1067 /* redundant due to non-organic composition but
1068 included for emphasis */
1069 || (otmp->otyp == AMULET_OF_STRANGULATION
1070 || otmp->otyp == RIN_SLOW_DIGESTION)
1071 /* cockatrice corpses handled above; this
1072 touch_petrifies() check catches eggs */
1073 || ((otmp->otyp == CORPSE || otmp->otyp == EGG
1075 && ((touch_petrifies(&mons[otmp->corpsenm])
1076 && !resists_ston(mtmp))
1077 || (otmp->corpsenm == PM_GREEN_SLIME
1078 && !slimeproof(mtmp->data))))) {
1083 Sprintf(buf, "%s engulfs %s.", Monnam(mtmp),
1084 distant_name(otmp, doname));
1086 Sprintf(buf, "%s
\82Í%s
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82¾
\81D", Monnam(mtmp),
1087 distant_name(otmp,doname));
1089 else if (ecount == 2)
1091 Sprintf(buf, "%s engulfs several objects.", Monnam(mtmp));
1093 Sprintf(buf, "%s
\82Í
\82¢
\82
\82Â
\82©
\82Ì
\95¨
\82ð
\88ù
\82Ý
\8d\9e\82ñ
\82¾
\81D", Monnam(mtmp));
1094 obj_extract_self(otmp);
1095 (void) mpickobj(mtmp, otmp); /* slurp */
1097 /* lastly, edible items; yum! */
1101 if (cansee(mtmp->mx, mtmp->my)) {
1104 pline("%s eats %s!", Monnam(mtmp),
1105 distant_name(otmp, doname));
1107 pline("%s
\82Í%s
\82ð
\90H
\82×
\82Ä
\82¢
\82é
\81I", Monnam(mtmp),
1108 distant_name(otmp, doname));
1110 /* give this one even if !verbose */
1111 #if 0 /*JP*//*
\93ú
\96{
\8cê
\94Å
\82Å
\82Í
\82±
\82ê
\82Í
\82È
\82¢*/
1112 if (otmp->oclass == SCROLL_CLASS
1113 && !strcmpi(OBJ_DESCR(objects[otmp->otyp]), "YUM YUM"))
1114 pline("Yum%c", otmp->blessed ? '!' : '.');
1119 You_hear("a slurping sound.");
1121 You_hear("
\82²
\82
\82ñ
\82Æ
\88ù
\82Ý
\8d\9e\82Þ
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1123 /* Heal up to the object's weight in hp */
1124 if (mtmp->mhp < mtmp->mhpmax) {
1125 mtmp->mhp += objects[otmp->otyp].oc_weight;
1126 if (mtmp->mhp > mtmp->mhpmax)
1127 mtmp->mhp = mtmp->mhpmax;
1129 if (Has_contents(otmp)) {
1130 register struct obj *otmp3;
1132 /* contents of eaten containers become engulfed; this
1133 is arbitrary, but otherwise g.cubes are too powerful */
1134 while ((otmp3 = otmp->cobj) != 0) {
1135 obj_extract_self(otmp3);
1136 if (otmp->otyp == ICE_BOX && otmp3->otyp == CORPSE) {
1137 otmp3->age = monstermoves - otmp3->age;
1138 start_corpse_timeout(otmp3);
1140 (void) mpickobj(mtmp, otmp3);
1143 poly = polyfodder(otmp);
1144 grow = mlevelgain(otmp);
1145 heal = mhealup(otmp);
1146 eyes = (otmp->otyp == CARROT);
1147 delobj(otmp); /* munch */
1150 if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE))
1153 ptr = grow_up(mtmp, (struct monst *) 0);
1155 mtmp->mhp = mtmp->mhpmax;
1157 if ((eyes || heal) && !mtmp->mcansee)
1158 mcureblindness(mtmp, canseemon(mtmp));
1159 /* in case it polymorphed or died */
1160 if (ptr != original_ptr)
1161 return !ptr ? 2 : 1;
1164 /* Engulf & devour is instant, so don't set meating */
1166 newsym(mtmp->mx, mtmp->my);
1170 if (cansee(mtmp->mx, mtmp->my) && flags.verbose && buf[0])
1172 else if (flags.verbose)
1174 You_hear("%s slurping sound%s.",
1175 (ecount == 1) ? "a" : "several", plur(ecount));
1177 You_hear("
\83Y
\83\8b\83Y
\83\8b\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1180 return (count > 0 || ecount > 0) ? 1 : 0;
1185 register struct monst *mtmp;
1187 register struct obj *gold;
1192 if ((gold = g_at(mtmp->mx, mtmp->my)) != 0) {
1194 mat_idx = objects[gold->otyp].oc_material;
1196 obj_extract_self(gold);
1197 add_to_minv(mtmp, gold);
1198 if (cansee(mtmp->mx, mtmp->my)) {
1199 if (flags.verbose && !mtmp->isgd)
1201 pline("%s picks up some %s.", Monnam(mtmp),
1202 mat_idx == GOLD ? "gold" : "money");
1204 pline("%s
\82Í
\82¨
\8bà
\82ð
\8fE
\82Á
\82½
\81D", Monnam(mtmp));
1206 newsym(mtmp->mx, mtmp->my);
1212 mpickstuff(mtmp, str)
1213 register struct monst *mtmp;
1214 register const char *str;
1216 register struct obj *otmp, *otmp2, *otmp3;
1219 /* prevent shopkeepers from leaving the door of their shop */
1220 if (mtmp->isshk && inhishop(mtmp))
1223 for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
1224 otmp2 = otmp->nexthere;
1225 /* Nymphs take everything. Most monsters don't pick up corpses. */
1226 if (!str ? searches_for_item(mtmp, otmp)
1227 : !!(index(str, otmp->oclass))) {
1228 if (otmp->otyp == CORPSE && mtmp->data->mlet != S_NYMPH
1229 /* let a handful of corpse types thru to can_carry() */
1230 && !touch_petrifies(&mons[otmp->corpsenm])
1231 && otmp->corpsenm != PM_LIZARD
1232 && !acidic(&mons[otmp->corpsenm]))
1234 if (!touch_artifact(otmp, mtmp))
1236 carryamt = can_carry(mtmp, otmp);
1239 if (is_pool(mtmp->mx, mtmp->my))
1241 /* handle cases where the critter can only get some */
1243 if (carryamt != otmp->quan) {
1244 otmp3 = splitobj(otmp, carryamt);
1246 if (cansee(mtmp->mx, mtmp->my) && flags.verbose)
1248 pline("%s picks up %s.", Monnam(mtmp),
1249 (distu(mtmp->mx, mtmp->my) <= 5)
1251 : distant_name(otmp3, doname));
1253 pline("%s
\82Í%s
\82ð
\8fE
\82Á
\82½
\81D", Monnam(mtmp),
1254 (distu(mtmp->mx, mtmp->my) <= 5)
1256 : distant_name(otmp3, doname));
1258 obj_extract_self(otmp3); /* remove from floor */
1259 (void) mpickobj(mtmp, otmp3); /* may merge and free otmp3 */
1260 m_dowear(mtmp, FALSE);
1261 newsym(mtmp->mx, mtmp->my);
1262 return TRUE; /* pick only one object */
1275 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
1276 if (obj->otyp != BOULDER || !throws_rocks(mtmp->data))
1277 curload += obj->owt;
1289 /* Base monster carrying capacity is equal to human maximum
1290 * carrying capacity, or half human maximum if not strong.
1291 * (for a polymorphed player, the value used would be the
1292 * non-polymorphed carrying capacity instead of max/half max).
1293 * This is then modified by the ratio between the monster weights
1294 * and human weights. Corpseless monsters are given a capacity
1295 * proportional to their size instead of weight.
1297 if (!mtmp->data->cwt)
1298 maxload = (MAX_CARR_CAP * (long) mtmp->data->msize) / MZ_HUMAN;
1299 else if (!strongmonst(mtmp->data)
1300 || (strongmonst(mtmp->data) && (mtmp->data->cwt > WT_HUMAN)))
1301 maxload = (MAX_CARR_CAP * (long) mtmp->data->cwt) / WT_HUMAN;
1303 maxload = MAX_CARR_CAP; /*strong monsters w/cwt <= WT_HUMAN*/
1305 if (!strongmonst(mtmp->data))
1311 return (int) maxload;
1314 /* for restricting monsters' object-pickup.
1316 * to support the new pet behavior, this now returns the max # of objects
1317 * that a given monster could pick up from a pile. frequently this will be
1318 * otmp->quan, but special cases for 'only one' now exist so.
1320 * this will probably cause very amusing behavior with pets and gold coins.
1322 * TODO: allow picking up 2-N objects from a pile of N based on weight.
1323 * Change from 'int' to 'long' to accomate big stacks of gold.
1324 * Right now we fake it by reporting a partial quantity, but the
1325 * likesgold handling m_move results in picking up the whole stack.
1328 can_carry(mtmp, otmp)
1332 int iquan, otyp = otmp->otyp, newload = otmp->owt;
1333 struct permonst *mdat = mtmp->data;
1337 return 0; /* can't carry anything */
1339 if (otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm])
1340 && !(mtmp->misc_worn_check & W_ARMG) && !resists_ston(mtmp))
1342 if (otyp == CORPSE && is_rider(&mons[otmp->corpsenm]))
1344 if (objects[otyp].oc_material == SILVER && mon_hates_silver(mtmp)
1345 && (otyp != BELL_OF_OPENING || !is_covetous(mdat)))
1348 /* hostile monsters who like gold will pick up the whole stack;
1349 tame mosnters with hands will pick up the partial stack */
1350 iquan = (otmp->quan > (long) LARGEST_INT)
1351 ? 20000 + rn2(LARGEST_INT - 20000 + 1)
1354 /* monsters without hands can't pick up multiple objects at once
1355 * unless they have an engulfing attack
1357 * ...dragons, of course, can always carry gold pieces and gems somehow
1360 boolean glomper = FALSE;
1362 if (mtmp->data->mlet == S_DRAGON
1363 && (otmp->oclass == COIN_CLASS
1364 || otmp->oclass == GEM_CLASS))
1367 for (nattk = 0; nattk < NATTK; nattk++)
1368 if (mtmp->data->mattk[nattk].aatyp == AT_ENGL) {
1372 if ((mtmp->data->mflags1 & M1_NOHANDS) && !glomper)
1376 /* steeds don't pick up stuff (to avoid shop abuse) */
1377 if (mtmp == u.usteed)
1380 return iquan; /* no limit */
1381 if (mtmp->mpeaceful && !mtmp->mtame)
1383 /* otherwise players might find themselves obligated to violate
1384 * their alignment if the monster takes something they need
1387 /* special--boulder throwers carry unlimited amounts of boulders */
1388 if (throws_rocks(mdat) && otyp == BOULDER)
1391 /* nymphs deal in stolen merchandise, but not boulders or statues */
1392 if (mdat->mlet == S_NYMPH)
1393 return (otmp->oclass == ROCK_CLASS) ? 0 : iquan;
1395 if (curr_mon_load(mtmp) + newload > max_mon_load(mtmp))
1401 /* return number of acceptable neighbour positions */
1403 mfndpos(mon, poss, info, flag)
1405 coord *poss; /* coord poss[9] */
1406 long *info; /* long info[9] */
1409 struct permonst *mdat = mon->data;
1410 register struct trap *ttmp;
1415 boolean wantpool, poolok, lavaok, nodiag;
1416 boolean rockok = FALSE, treeok = FALSE, thrudoor;
1418 boolean poisongas_ok, in_poisongas;
1420 int gas_glyph = cmap_to_glyph(S_poisoncloud);
1424 nowtyp = levl[x][y].typ;
1426 nodiag = NODIAG(mdat - mons);
1427 wantpool = (mdat->mlet == S_EEL);
1428 poolok = ((!Is_waterlevel(&u.uz)
1429 && (is_flyer(mdat) || is_floater(mdat) || is_clinger(mdat)))
1430 || (is_swimmer(mdat) && !wantpool));
1431 /* note: floating eye is the only is_floater() so this could be
1432 simplified, but then adding another floater would be error prone */
1433 lavaok = (is_flyer(mdat) || is_floater(mdat) || is_clinger(mdat)
1434 || likes_lava(mdat));
1435 if (mdat == &mons[PM_FLOATING_EYE]) /* prefers to avoid heat */
1437 thrudoor = ((flag & (ALLOW_WALL | BUSTDOOR)) != 0L);
1438 poisongas_ok = ((nonliving(mdat) || is_vampshifter(mon)
1439 || breathless(mdat)) || resists_poison(mon));
1440 in_poisongas = ((gas_reg = visible_region_at(x,y)) != 0
1441 && gas_reg->glyph == gas_glyph);
1443 if (flag & ALLOW_DIG) {
1446 /* need to be specific about what can currently be dug */
1447 if (!needspick(mdat)) {
1448 rockok = treeok = TRUE;
1449 } else if ((mw_tmp = MON_WEP(mon)) && mw_tmp->cursed
1450 && mon->weapon_check == NO_WEAPON_WANTED) {
1451 rockok = is_pick(mw_tmp);
1452 treeok = is_axe(mw_tmp);
1454 rockok = (m_carrying(mon, PICK_AXE)
1455 || (m_carrying(mon, DWARVISH_MATTOCK)
1456 && !which_armor(mon, W_ARMS)));
1457 treeok = (m_carrying(mon, AXE) || (m_carrying(mon, BATTLE_AXE)
1458 && !which_armor(mon, W_ARMS)));
1460 if (rockok || treeok)
1464 nexttry: /* eels prefer the water, but if there is no water nearby,
1465 they will crawl over land */
1472 maxx = min(x + 1, COLNO - 1);
1473 maxy = min(y + 1, ROWNO - 1);
1474 for (nx = max(1, x - 1); nx <= maxx; nx++)
1475 for (ny = max(0, y - 1); ny <= maxy; ny++) {
1476 if (nx == x && ny == y)
1478 ntyp = levl[nx][ny].typ;
1480 && !((flag & ALLOW_WALL) && may_passwall(nx, ny))
1481 && !((IS_TREE(ntyp) ? treeok : rockok) && may_dig(nx, ny)))
1483 /* KMH -- Added iron bars */
1484 if (ntyp == IRONBARS
1485 && (!(flag & ALLOW_BARS)
1486 || ((levl[nx][ny].wall_info & W_NONDIGGABLE)
1487 && (dmgtype(mdat, AD_RUST)
1488 || dmgtype(mdat, AD_CORR)))))
1490 if (IS_DOOR(ntyp) && !(amorphous(mdat) || can_fog(mon))
1491 && (((levl[nx][ny].doormask & D_CLOSED) && !(flag & OPENDOOR))
1492 || ((levl[nx][ny].doormask & D_LOCKED)
1493 && !(flag & UNLOCKDOOR))) && !thrudoor)
1495 /* avoid poison gas? */
1496 if (!poisongas_ok && !in_poisongas
1497 && (gas_reg = visible_region_at(nx,ny)) != 0
1498 && gas_reg->glyph == gas_glyph)
1500 /* first diagonal checks (tight squeezes handled below) */
1501 if (nx != x && ny != y
1503 || (IS_DOOR(nowtyp) && (levl[x][y].doormask & ~D_BROKEN))
1504 || (IS_DOOR(ntyp) && (levl[nx][ny].doormask & ~D_BROKEN))
1505 || ((IS_DOOR(nowtyp) || IS_DOOR(ntyp))
1506 && Is_rogue_level(&u.uz))
1507 /* mustn't pass between adjacent long worm segments,
1508 but can attack that way */
1509 || (m_at(x, ny) && m_at(nx, y) && worm_cross(x, y, nx, ny)
1510 && !m_at(nx, ny) && (nx != u.ux || ny != u.uy))))
1512 if ((is_pool(nx, ny) == wantpool || poolok)
1513 && (lavaok || !is_lava(nx, ny))) {
1515 boolean monseeu = (mon->mcansee
1516 && (!Invis || perceives(mdat)));
1517 boolean checkobj = OBJ_AT(nx, ny);
1519 /* Displacement also displaces the Elbereth/scare monster,
1520 * as long as you are visible.
1522 if (Displaced && monseeu && mon->mux == nx && mon->muy == ny) {
1531 if (onscary(dispx, dispy, mon)) {
1532 if (!(flag & ALLOW_SSM))
1534 info[cnt] |= ALLOW_SSM;
1536 if ((nx == u.ux && ny == u.uy)
1537 || (nx == mon->mux && ny == mon->muy)) {
1538 if (nx == u.ux && ny == u.uy) {
1539 /* If it's right next to you, it found you,
1540 * displaced or no. We must set mux and muy
1541 * right now, so when we return we can tell
1542 * that the ALLOW_U means to attack _you_ and
1548 if (!(flag & ALLOW_U))
1550 info[cnt] |= ALLOW_U;
1552 if (MON_AT(nx, ny)) {
1553 struct monst *mtmp2 = m_at(nx, ny);
1554 long mmflag = flag | mm_aggression(mon, mtmp2);
1556 if (mmflag & ALLOW_M) {
1557 info[cnt] |= ALLOW_M;
1559 if (!(mmflag & ALLOW_TM))
1561 info[cnt] |= ALLOW_TM;
1564 mmflag = flag | mm_displacement(mon, mtmp2);
1565 if (!(mmflag & ALLOW_MDISP))
1567 info[cnt] |= ALLOW_MDISP;
1570 /* Note: ALLOW_SANCT only prevents movement, not
1571 attack, into a temple. */
1572 if (level.flags.has_temple && *in_rooms(nx, ny, TEMPLE)
1573 && !*in_rooms(x, y, TEMPLE)
1574 && in_your_sanctuary((struct monst *) 0, nx, ny)) {
1575 if (!(flag & ALLOW_SANCT))
1577 info[cnt] |= ALLOW_SANCT;
1580 if (checkobj && sobj_at(CLOVE_OF_GARLIC, nx, ny)) {
1581 if (flag & NOGARLIC)
1583 info[cnt] |= NOGARLIC;
1585 if (checkobj && sobj_at(BOULDER, nx, ny)) {
1586 if (!(flag & ALLOW_ROCK))
1588 info[cnt] |= ALLOW_ROCK;
1590 if (monseeu && onlineu(nx, ny)) {
1593 info[cnt] |= NOTONL;
1595 /* check for diagonal tight squeeze */
1596 if (nx != x && ny != y && bad_rock(mdat, x, ny)
1597 && bad_rock(mdat, nx, y) && cant_squeeze_thru(mon))
1599 /* The monster avoids a particular type of trap if it's
1600 * familiar with the trap type. Pets get ALLOW_TRAPS
1601 * and checking is done in dogmove.c. In either case,
1602 * "harmless" traps are neither avoided nor marked in info[].
1604 if ((ttmp = t_at(nx, ny)) != 0) {
1605 if (ttmp->ttyp >= TRAPNUM || ttmp->ttyp == 0) {
1607 "A monster looked at a very strange trap of type %d.",
1611 if ((ttmp->ttyp != RUST_TRAP
1612 || mdat == &mons[PM_IRON_GOLEM])
1613 && ttmp->ttyp != STATUE_TRAP
1614 && ttmp->ttyp != VIBRATING_SQUARE
1615 && ((!is_pit(ttmp->ttyp) && !is_hole(ttmp->ttyp))
1616 || (!is_flyer(mdat) && !is_floater(mdat)
1617 && !is_clinger(mdat)) || Sokoban)
1618 && (ttmp->ttyp != SLP_GAS_TRAP || !resists_sleep(mon))
1619 && (ttmp->ttyp != BEAR_TRAP
1620 || (mdat->msize > MZ_SMALL && !amorphous(mdat)
1621 && !is_flyer(mdat) && !is_floater(mdat)
1622 && !is_whirly(mdat) && !unsolid(mdat)))
1623 && (ttmp->ttyp != FIRE_TRAP || !resists_fire(mon))
1624 && (ttmp->ttyp != SQKY_BOARD || !is_flyer(mdat))
1625 && (ttmp->ttyp != WEB
1626 || (!amorphous(mdat) && !webmaker(mdat)
1627 && !is_whirly(mdat) && !unsolid(mdat)))
1628 && (ttmp->ttyp != ANTI_MAGIC || !resists_magm(mon))) {
1629 if (!(flag & ALLOW_TRAPS)) {
1630 if (mon->mtrapseen & (1L << (ttmp->ttyp - 1)))
1633 info[cnt] |= ALLOW_TRAPS;
1641 if (!cnt && wantpool && !is_pool(x, y)) {
1648 /* Monster against monster special attacks; for the specified monster
1649 combinations, this allows one monster to attack another adjacent one
1650 in the absence of Conflict. There is no provision for targetting
1651 other monsters; just hand to hand fighting when they happen to be
1652 next to each other. */
1654 mm_aggression(magr, mdef)
1655 struct monst *magr, /* monster that is currently deciding where to move */
1656 *mdef; /* another monster which is next to it */
1658 /* supposedly purple worms are attracted to shrieking because they
1659 like to eat shriekers, so attack the latter when feasible */
1660 if (magr->data == &mons[PM_PURPLE_WORM]
1661 && mdef->data == &mons[PM_SHRIEKER])
1662 return ALLOW_M | ALLOW_TM;
1663 /* Various other combinations such as dog vs cat, cat vs rat, and
1664 elf vs orc have been suggested. For the time being we don't
1669 /* Monster displacing another monster out of the way */
1671 mm_displacement(magr, mdef)
1672 struct monst *magr, /* monster that is currently deciding where to move */
1673 *mdef; /* another monster which is next to it */
1675 struct permonst *pa = magr->data, *pd = mdef->data;
1677 /* if attacker can't barge through, there's nothing to do;
1678 or if defender can barge through too, don't let attacker
1679 do so, otherwise they might just end up swapping places
1680 again when defender gets its chance to move */
1681 if ((pa->mflags3 & M3_DISPLACES) != 0 && (pd->mflags3 & M3_DISPLACES) == 0
1682 /* no displacing grid bugs diagonally */
1683 && !(magr->mx != mdef->mx && magr->my != mdef->my
1684 && NODIAG(monsndx(pd)))
1685 /* no displacing trapped monsters or multi-location longworms */
1686 && !mdef->mtrapped && (!mdef->wormno || !count_wsegs(mdef))
1687 /* riders can move anything; others, same size or smaller only */
1688 && (is_rider(pa) || pa->msize >= pd->msize))
1693 /* Is the square close enough for the monster to move or attack into? */
1699 int distance = dist2(mon->mx, mon->my, x, y);
1701 if (distance == 2 && NODIAG(mon->data - mons))
1703 return (boolean) (distance < 3);
1706 /* really free dead monsters */
1710 struct monst **mtmp, *freetmp;
1715 for (mtmp = &fmon; *mtmp;) {
1717 if (DEADMONSTER(freetmp) && !freetmp->isgd) {
1718 *mtmp = freetmp->nmon;
1719 freetmp->nmon = NULL;
1720 dealloc_monst(freetmp);
1723 mtmp = &(freetmp->nmon);
1726 if (count != iflags.purge_monsters) {
1727 describe_level(buf);
1728 impossible("dmonsfree: %d removed doesn't match %d pending on %s",
1729 count, iflags.purge_monsters, buf);
1731 iflags.purge_monsters = 0;
1734 /* called when monster is moved to larger structure */
1736 replmon(mtmp, mtmp2)
1737 struct monst *mtmp, *mtmp2;
1741 /* transfer the monster's inventory */
1742 for (otmp = mtmp2->minvent; otmp; otmp = otmp->nobj) {
1743 if (otmp->where != OBJ_MINVENT || otmp->ocarry != mtmp)
1744 impossible("replmon: minvent inconsistency");
1745 otmp->ocarry = mtmp2;
1749 /* remove the old monster from the map and from `fmon' list */
1750 relmon(mtmp, (struct monst **) 0);
1752 /* finish adding its replacement */
1753 if (mtmp != u.usteed) /* don't place steed onto the map */
1754 place_monster(mtmp2, mtmp2->mx, mtmp2->my);
1755 if (mtmp2->wormno) /* update level.monsters[wseg->wx][wseg->wy] */
1756 place_wsegs(mtmp2, NULL); /* locations to mtmp2 not mtmp. */
1757 if (emits_light(mtmp2->data)) {
1758 /* since this is so rare, we don't have any `mon_move_light_source' */
1759 new_light_source(mtmp2->mx, mtmp2->my, emits_light(mtmp2->data),
1760 LS_MONSTER, monst_to_any(mtmp2));
1761 /* here we rely on fact that `mtmp' hasn't actually been deleted */
1762 del_light_source(LS_MONSTER, monst_to_any(mtmp));
1766 if (u.ustuck == mtmp)
1768 if (u.usteed == mtmp)
1771 replshk(mtmp, mtmp2);
1773 /* discard the old monster */
1774 dealloc_monst(mtmp);
1777 /* release mon from the display and the map's monster list,
1778 maybe transfer it to one of the other monster lists */
1780 relmon(mon, monst_list)
1782 struct monst **monst_list; /* &migrating_mons or &mydogs or null */
1785 int mx = mon->mx, my = mon->my;
1786 boolean on_map = (m_at(mx, my) == mon),
1787 unhide = (monst_list != 0);
1790 panic("relmon: no fmon available.");
1793 /* can't remain hidden across level changes (exception: wizard
1794 clone can continue imitating some other monster form); also,
1795 might be imitating a boulder so need line-of-sight unblocking */
1796 mon->mundetected = 0;
1797 if (M_AP_TYPE(mon) && M_AP_TYPE(mon) != M_AP_MONSTER)
1806 remove_monster(mx, my);
1812 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
1813 if (mtmp->nmon == mon)
1817 mtmp->nmon = mon->nmon;
1819 panic("relmon: mon not in list.");
1825 /* insert into mydogs or migrating_mons */
1826 mon->nmon = *monst_list;
1829 /* orphan has no next monster */
1835 copy_mextra(mtmp2, mtmp1)
1836 struct monst *mtmp2, *mtmp1;
1838 if (!mtmp2 || !mtmp1 || !mtmp1->mextra)
1842 mtmp2->mextra = newmextra();
1844 new_mname(mtmp2, (int) strlen(MNAME(mtmp1)) + 1);
1845 Strcpy(MNAME(mtmp2), MNAME(mtmp1));
1850 *EGD(mtmp2) = *EGD(mtmp1);
1855 *EPRI(mtmp2) = *EPRI(mtmp1);
1860 *ESHK(mtmp2) = *ESHK(mtmp1);
1865 *EMIN(mtmp2) = *EMIN(mtmp1);
1870 *EDOG(mtmp2) = *EDOG(mtmp1);
1872 if (has_mcorpsenm(mtmp1))
1873 MCORPSENM(mtmp2) = MCORPSENM(mtmp1);
1880 struct mextra *x = m->mextra;
1884 free((genericptr_t) x->mname);
1886 free((genericptr_t) x->egd);
1888 free((genericptr_t) x->epri);
1890 free((genericptr_t) x->eshk);
1892 free((genericptr_t) x->emin);
1894 free((genericptr_t) x->edog);
1895 /* [no action needed for x->mcorpsenm] */
1897 free((genericptr_t) x);
1898 m->mextra = (struct mextra *) 0;
1910 describe_level(buf);
1911 panic("dealloc_monst with nmon on %s", buf);
1914 dealloc_mextra(mon);
1915 free((genericptr_t) mon);
1918 /* remove effects of mtmp from other data structures */
1920 m_detach(mtmp, mptr)
1922 struct permonst *mptr; /* reflects mtmp->data _prior_ to mtmp's death */
1924 boolean onmap = (mtmp->mx > 0);
1926 if (mtmp == context.polearm.hitmon)
1927 context.polearm.hitmon = 0;
1929 m_unleash(mtmp, FALSE);
1930 /* to prevent an infinite relobj-flooreffects-hmon-killed loop */
1932 mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */
1933 relobj(mtmp, 0, FALSE);
1934 if (onmap || mtmp == level.monsters[0][0]) {
1938 remove_monster(mtmp->mx, mtmp->my);
1940 if (emits_light(mptr))
1941 del_light_source(LS_MONSTER, monst_to_any(mtmp));
1942 if (M_AP_TYPE(mtmp))
1945 newsym(mtmp->mx, mtmp->my);
1948 fill_pit(mtmp->mx, mtmp->my);
1954 if (In_endgame(&u.uz))
1955 mtmp->mstate |= MON_ENDGAME_FREE;
1957 mtmp->mstate |= MON_DETACH;
1958 iflags.purge_monsters++;
1961 /* find the worn amulet of life saving which will save a monster */
1966 if (!nonliving(mon->data) || is_vampshifter(mon)) {
1967 struct obj *otmp = which_armor(mon, W_AMUL);
1969 if (otmp && otmp->otyp == AMULET_OF_LIFE_SAVING)
1972 return (struct obj *) 0;
1976 lifesaved_monster(mtmp)
1980 struct obj *lifesave = mlifesaver(mtmp);
1983 /* not canseemon; amulets are on the head, so you don't want
1984 * to show this for a long worm with only a tail visible.
1985 * Nor do you check invisibility, because glowing and
1986 * disintegrating amulets are always visible. */
1987 if (cansee(mtmp->mx, mtmp->my)) {
1989 pline("But wait...");
1991 pline("
\82¿
\82å
\82Á
\82Æ
\82Ü
\82Á
\82½
\81D
\81D
\81D");
1993 pline("%s medallion begins to glow!", s_suffix(Monnam(mtmp)));
1995 pline("%s
\82Ì
\96\82\8f\9c\82¯
\82ª
\8bP
\82«
\82Í
\82¶
\82ß
\82½
\81I", Monnam(mtmp));
1996 makeknown(AMULET_OF_LIFE_SAVING);
1997 /* amulet is visible, but monster might not be */
1998 if (canseemon(mtmp)) {
1999 if (attacktype(mtmp->data, AT_EXPL)
2000 || attacktype(mtmp->data, AT_BOOM))
2002 pline("%s reconstitutes!", Monnam(mtmp));
2004 pline("%s
\82Í
\8dÄ
\8d\
\90¬
\82³
\82ê
\82½
\81I", Monnam(mtmp));
2007 pline("%s looks much better!", Monnam(mtmp));
2009 pline("%s
\82Í
\82·
\82Á
\82©
\82è
\89ñ
\95\9c\82µ
\82½
\82æ
\82¤
\82¾
\81I", Monnam(mtmp));
2012 pline_The("medallion crumbles to dust!");
2014 pline("
\96\82\8f\9c\82¯
\82Í
\82±
\82È
\82²
\82È
\82É
\82
\82¾
\82¯
\82½
\81I");
2016 m_useup(mtmp, lifesave);
2017 /* equip replacement amulet, if any, on next move */
2018 mtmp->misc_worn_check |= I_SPECIAL;
2020 surviver = !(mvitals[monsndx(mtmp->data)].mvflags & G_GENOD);
2023 if (mtmp->mtame && !mtmp->isminion) {
2024 wary_dog(mtmp, !surviver);
2026 if (mtmp->mhpmax <= 0)
2028 mtmp->mhp = mtmp->mhpmax;
2031 /* genocided monster can't be life-saved */
2032 if (cansee(mtmp->mx, mtmp->my))
2034 pline("Unfortunately, %s is still genocided...",
2036 pline("
\8ec
\94O
\82È
\82ª
\82ç%s
\82Í
\8bs
\8eE
\82³
\82ê
\82Ä
\82¢
\82é
\81D
\81D
\81D",
2045 register struct monst *mtmp;
2047 struct permonst *mptr;
2050 mtmp->mhp = 0; /* in case caller hasn't done this */
2051 lifesaved_monster(mtmp);
2052 if (!DEADMONSTER(mtmp))
2055 if (is_vampshifter(mtmp)) {
2056 int mndx = mtmp->cham;
2057 int x = mtmp->mx, y = mtmp->my;
2059 /* this only happens if shapeshifted */
2060 if (mndx >= LOW_PM && mndx != monsndx(mtmp->data)
2061 && !(mvitals[mndx].mvflags & G_GENOD)) {
2063 boolean in_door = (amorphous(mtmp->data)
2064 && closed_door(mtmp->mx, mtmp->my)),
2066 /* alternate message phrasing for some monster types */
2067 spec_mon = (nonliving(mtmp->data)
2068 || noncorporeal(mtmp->data)
2069 || amorphous(mtmp->data)),
2071 spec_death = (disintegested /* disintegrated or digested */
2072 || noncorporeal(mtmp->data)
2073 || amorphous(mtmp->data));
2075 /* construct a format string before transformation;
2076 will be capitalized when used, expects one %s arg */
2078 Sprintf(buf, "%s suddenly %s and rises as %%s!",
2079 x_monnam(mtmp, ARTICLE_THE,
2080 spec_mon ? (char *) 0 : "seemingly dead",
2081 (SUPPRESS_INVISIBLE | SUPPRESS_IT), FALSE),
2082 spec_death ? "reconstitutes" : "transforms");
2084 Sprintf(buf, "%s%s
\82Í
\93Ë
\91R%s
\81C%%s
\82Æ
\82µ
\82Ä
\91h
\82Á
\82½
\81I",
2085 spec_death ? "" : "
\8e\80\82ñ
\82¾
\82æ
\82¤
\82É
\8ev
\82í
\82ê
\82½",
2086 x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
2087 SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION
2088 | SUPPRESS_INVISIBLE | SUPPRESS_IT,
2090 spec_death ? "
\8dÄ
\8d\
\90¬
\82³
\82ê" : "
\95Ï
\89»
\82µ");
2094 if (mtmp->mhpmax <= 0)
2096 mtmp->mhp = mtmp->mhpmax;
2097 /* mtmp==u.ustuck can happen if previously a fog cloud
2098 or poly'd hero is hugging a vampire bat */
2099 if (mtmp == u.ustuck) {
2101 expels(mtmp, mtmp->data, FALSE);
2108 if (enexto(&new_xy, mtmp->mx, mtmp->my, &mons[mndx])) {
2109 rloc_to(mtmp, new_xy.x, new_xy.y);
2112 newcham(mtmp, &mons[mndx], FALSE, FALSE);
2113 if (mtmp->data == &mons[mndx])
2114 mtmp->cham = NON_PM;
2117 if (canspotmon(mtmp)) {
2118 /* 3.6.0 used a_monnam(mtmp); that was weird if mtmp was
2119 named: "Dracula suddenly transforms and rises as Dracula";
2120 3.6.1 used mtmp->data->mname; that ignored hallucination */
2122 x_monnam(mtmp, ARTICLE_A, (char *) 0,
2123 (SUPPRESS_NAME | SUPPRESS_IT
2124 | SUPPRESS_INVISIBLE), FALSE));
2125 vamp_rise_msg = TRUE;
2132 /* dead vault guard is actually kept at coordinate <0,0> until
2133 his temporary corridor to/from the vault has been removed;
2134 need to do this after life-saving and before m_detach() */
2135 if (mtmp->isgd && !grddead(mtmp))
2138 /* Player is thrown from his steed when it dies */
2139 if (mtmp == u.usteed)
2140 dismount_steed(DISMOUNT_GENERIC);
2142 mptr = mtmp->data; /* save this for m_detach() */
2143 /* restore chameleon, lycanthropes to true form at death */
2144 if (mtmp->cham >= LOW_PM) {
2145 set_mon_data(mtmp, &mons[mtmp->cham]);
2146 mtmp->cham = NON_PM;
2147 } else if (mtmp->data == &mons[PM_WEREJACKAL])
2148 set_mon_data(mtmp, &mons[PM_HUMAN_WEREJACKAL]);
2149 else if (mtmp->data == &mons[PM_WEREWOLF])
2150 set_mon_data(mtmp, &mons[PM_HUMAN_WEREWOLF]);
2151 else if (mtmp->data == &mons[PM_WERERAT])
2152 set_mon_data(mtmp, &mons[PM_HUMAN_WERERAT]);
2155 * mvitals[].died does double duty as total number of dead monsters
2156 * and as experience factor for the player killing more monsters.
2157 * this means that a dragon dying by other means reduces the
2158 * experience the player gets for killing a dragon directly; this
2159 * is probably not too bad, since the player likely finagled the
2160 * first dead dragon via ring of conflict or pets, and extinguishing
2161 * based on only player kills probably opens more avenues of abuse
2162 * for rings of conflict and such.
2164 tmp = monsndx(mtmp->data);
2165 if (mvitals[tmp].died < 255)
2166 mvitals[tmp].died++;
2168 /* if it's a (possibly polymorphed) quest leader, mark him as dead */
2169 if (mtmp->m_id == quest_status.leader_m_id)
2170 quest_status.leader_is_dead = TRUE;
2172 /* if the mail daemon dies, no more mail delivery. -3. */
2173 if (tmp == PM_MAIL_DAEMON)
2174 mvitals[tmp].mvflags |= G_GENOD;
2177 if (mtmp->data->mlet == S_KOP) {
2178 /* Dead Kops may come back. */
2180 case 1: /* returns near the stairs */
2181 (void) makemon(mtmp->data, xdnstair, ydnstair, NO_MM_FLAGS);
2183 case 2: /* randomly */
2184 (void) makemon(mtmp->data, 0, 0, NO_MM_FLAGS);
2192 if (mtmp->data->msound == MS_NEMESIS)
2194 if (mtmp->data == &mons[PM_MEDUSA])
2195 u.uachieve.killed_medusa = 1;
2196 if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
2197 unmap_object(mtmp->mx, mtmp->my);
2198 m_detach(mtmp, mptr);
2201 /* TRUE if corpse might be dropped, magr may die if mon was swallowed */
2203 corpse_chance(mon, magr, was_swallowed)
2205 struct monst *magr; /* killer, if swallowed */
2206 boolean was_swallowed; /* digestion */
2208 struct permonst *mdat = mon->data;
2211 if (mdat == &mons[PM_VLAD_THE_IMPALER] || mdat->mlet == S_LICH) {
2212 if (cansee(mon->mx, mon->my) && !was_swallowed)
2214 pline("%s body crumbles into dust.", s_suffix(Monnam(mon)));
2216 pline("%s
\82Ì
\91Ì
\82Í
\95²
\81X
\82É
\82È
\82Á
\82½
\81D", Monnam(mon));
2220 /* Gas spores always explode upon death */
2221 for (i = 0; i < NATTK; i++) {
2222 if (mdat->mattk[i].aatyp == AT_BOOM) {
2223 if (mdat->mattk[i].damn)
2224 tmp = d((int) mdat->mattk[i].damn, (int) mdat->mattk[i].damd);
2225 else if (mdat->mattk[i].damd)
2226 tmp = d((int) mdat->mlevel + 1, (int) mdat->mattk[i].damd);
2229 if (was_swallowed && magr) {
2230 if (magr == &youmonst) {
2232 There("is an explosion in your %s!", body_part(STOMACH));
2234 pline("%s
\82Ì
\92\86\82Å
\94\9a\94
\82ª
\8bN
\82«
\82½
\81I", body_part(STOMACH));
2236 Sprintf(killer.name, "%s explosion",
2237 s_suffix(mdat->mname));
2239 Sprintf(killer.name, "%s
\82Ì
\94\9a\94
\82Å", mdat->mname);
2241 losehp(Maybe_Half_Phys(tmp), killer.name, KILLED_BY_AN);
2244 You_hear("an explosion.");
2246 You_hear("
\94\9a\94
\89¹
\82ð
\95·
\82¢
\82½
\81D");
2248 if (DEADMONSTER(magr))
2250 if (DEADMONSTER(magr)) { /* maybe lifesaved */
2251 if (canspotmon(magr))
2253 pline("%s rips open!", Monnam(magr));
2255 pline("%s
\82Í
\83r
\83\8a\82Á
\82Æ
\94j
\82ê
\82½
\81I", Monnam(magr));
2256 } else if (canseemon(magr))
2258 pline("%s seems to have indigestion.", Monnam(magr));
2260 pline("%s
\82Í
\8fÁ
\89»
\95s
\97Ç
\82Ì
\82æ
\82¤
\82¾
\81D", Monnam(magr));
2267 Sprintf(killer.name, "%s explosion", s_suffix(mdat->mname));
2269 Sprintf(killer.name, "%s
\82Ì
\94\9a\94
\82Å", mdat->mname);
2270 killer.format = KILLED_BY_AN;
2271 explode(mon->mx, mon->my, -1, tmp, MON_EXPLODE, EXPL_NOXIOUS);
2272 killer.name[0] = '\0';
2278 /* must duplicate this below check in xkilled() since it results in
2279 * creating no objects as well as no corpse
2281 if (LEVEL_SPECIFIC_NOCORPSE(mdat))
2284 if (((bigmonst(mdat) || mdat == &mons[PM_LIZARD]) && !mon->mcloned)
2285 || is_golem(mdat) || is_mplayer(mdat) || is_rider(mdat) || mon->isshk)
2287 tmp = 2 + ((mdat->geno & G_FREQ) < 2) + verysmall(mdat);
2288 return (boolean) !rn2(tmp);
2291 /* drop (perhaps) a cadaver and remove monster */
2294 register struct monst *mdef;
2297 if (!DEADMONSTER(mdef))
2298 return; /* lifesaved */
2300 if (corpse_chance(mdef, (struct monst *) 0, FALSE)
2301 && (accessible(mdef->mx, mdef->my) || is_pool(mdef->mx, mdef->my)))
2302 (void) make_corpse(mdef, CORPSTAT_NONE);
2305 /* monster disappears, not dies */
2310 mdef->mhp = 0; /* can skip some inventory bookkeeping */
2312 /* dead vault guard is actually kept at coordinate <0,0> until
2313 his temporary corridor to/from the vault has been removed */
2314 if (mdef->isgd && !grddead(mdef))
2316 /* hero is thrown from his steed when it disappears */
2317 if (mdef == u.usteed)
2318 dismount_steed(DISMOUNT_GENERIC);
2319 /* stuck to you? release */
2321 /* drop special items like the Amulet so that a dismissed Kop or nurse
2322 can't remove them from the game */
2323 mdrop_special_objs(mdef);
2324 /* release rest of monster's inventory--it is removed from game */
2325 discard_minvent(mdef);
2326 m_detach(mdef, mdef->data);
2329 /* drop a statue or rock and remove monster */
2334 struct obj *otmp, *obj, *oldminvent;
2335 xchar x = mdef->mx, y = mdef->my;
2336 boolean wasinside = FALSE;
2338 /* vampshifter reverts to vampire;
2339 3.6.3: also used to unshift shape-changed sandestin */
2340 if (!vamp_stone(mdef))
2343 /* we have to make the statue before calling mondead, to be able to
2344 * put inventory in it, and we have to check for lifesaving before
2345 * making the statue....
2347 mdef->mhp = 0; /* in case caller hasn't done this */
2348 lifesaved_monster(mdef);
2349 if (!DEADMONSTER(mdef))
2352 mdef->mtrapped = 0; /* (see m_detach) */
2354 if ((int) mdef->data->msize > MZ_TINY
2355 || !rn2(2 + ((int) (mdef->data->geno & G_FREQ) > 2))) {
2357 /* some objects may end up outside the statue */
2358 while ((obj = mdef->minvent) != 0) {
2359 obj_extract_self(obj);
2361 update_mon_intrinsics(mdef, obj, FALSE, TRUE);
2362 obj_no_longer_held(obj);
2363 if (obj->owornmask & W_WEP)
2364 setmnotwielded(mdef, obj);
2365 obj->owornmask = 0L;
2366 if (obj->otyp == BOULDER
2367 #if 0 /* monsters don't carry statues */
2368 || (obj->otyp == STATUE
2369 && mons[obj->corpsenm].msize >= mdef->data->msize)
2371 /* invocation tools resist even with 0% resistance */
2372 || obj_resists(obj, 0, 0)) {
2374 if (flooreffects(obj, x, y, "fall"))
2376 if (flooreffects(obj, x, y, "
\97\8e\82¿
\82é"))
2378 place_object(obj, x, y);
2381 end_burn(obj, TRUE);
2382 obj->nobj = oldminvent;
2386 /* defer statue creation until after inventory removal
2387 so that saved monster traits won't retain any stale
2388 item-conferred attributes */
2389 otmp = mkcorpstat(STATUE, mdef, mdef->data, x, y, CORPSTAT_NONE);
2390 if (has_mname(mdef))
2391 otmp = oname(otmp, MNAME(mdef));
2392 while ((obj = oldminvent) != 0) {
2393 oldminvent = obj->nobj;
2394 obj->nobj = 0; /* avoid merged-> obfree-> dealloc_obj-> panic */
2395 (void) add_to_container(otmp, obj);
2397 /* Archeologists should not break unique statues */
2398 if (mdef->data->geno & G_UNIQ)
2400 otmp->owt = weight(otmp);
2402 otmp = mksobj_at(ROCK, x, y, TRUE, FALSE);
2405 /* mondead() already does this, but we must do it before the newsym */
2406 if (glyph_is_invisible(levl[x][y].glyph))
2410 /* We don't currently trap the hero in the statue in this case but we
2412 if (u.uswallow && u.ustuck == mdef)
2416 if (is_animal(mdef->data))
2418 You("%s through an opening in the new %s.",
2419 locomotion(youmonst.data, "jump"), xname(otmp));
2421 You("
\90V
\82µ
\82
\82Å
\82«
\82½%s
\82©
\82ç%s
\81D",
2422 xname(otmp), jumpedthrough(youmonst.data, "
\94ò
\82Ñ
\8fo
\82½"));
2427 /* another monster has killed the monster mdef */
2429 monkilled(mdef, fltxt, how)
2434 boolean be_sad = FALSE; /* true if unseen pet is killed */
2436 if ((mdef->wormno ? worm_known(mdef) : cansee(mdef->mx, mdef->my))
2439 pline("%s is %s%s%s!", Monnam(mdef),
2440 nonliving(mdef->data) ? "destroyed" : "killed",
2441 *fltxt ? " by the " : "", fltxt);
2445 pline("%s
\82Í%s
\82É
\82æ
\82Á
\82Ä%s
\81I", Monnam(mdef), fltxt,
2446 nonliving(mdef->data) ? "
\93|
\82³
\82ê
\82½" : "
\8eE
\82³
\82ê
\82½");
2448 pline("%s
\82Í%s
\81I", Monnam(mdef),
2449 nonliving(mdef->data) ? "
\93|
\82³
\82ê
\82½" : "
\8eE
\82³
\82ê
\82½");
2453 be_sad = (mdef->mtame != 0);
2455 /* no corpses if digested or disintegrated */
2456 disintegested = (how == AD_DGST || how == -AD_RBRE);
2462 if (be_sad && DEADMONSTER(mdef))
2464 You("have a sad feeling for a moment, then it passes.");
2466 You("
\94ß
\82µ
\82¢
\8bC
\8e\9d\82É
\82¨
\82»
\82í
\82ê
\82½
\82ª
\81C
\82·
\82®
\82É
\89ß
\82¬
\82³
\82Á
\82½
\81D");
2473 if (u.ustuck == mtmp) {
2479 if (Punished && uchain->where != OBJ_FLOOR)
2481 vision_full_recalc = 1;
2483 /* prevent swallower (mtmp might have just poly'd into something
2484 without an engulf attack) from immediately re-engulfing */
2485 if (attacktype(mtmp->data, AT_ENGL) && !mtmp->mspec_used)
2486 mtmp->mspec_used = rnd(2);
2496 xkilled(mtmp, XKILL_GIVEMSG);
2499 /* the player has killed the monster mtmp */
2501 xkilled(mtmp, xkill_flags)
2503 int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
2505 int tmp, mndx, x = mtmp->mx, y = mtmp->my;
2506 struct permonst *mdat;
2509 boolean wasinside = u.uswallow && (u.ustuck == mtmp),
2511 nomsg = (xkill_flags & XKILL_NOMSG) != 0,
2512 nocorpse = (xkill_flags & XKILL_NOCORPSE) != 0,
2513 noconduct = (xkill_flags & XKILL_NOCONDUCT) != 0;
2515 mtmp->mhp = 0; /* caller will usually have already done this */
2516 if (!noconduct) /* KMH, conduct */
2517 u.uconduct.killer++;
2520 boolean namedpet = has_mname(mtmp) && !Hallucination;
2524 nonliving(mtmp->data) ? "destroy" : "kill",
2525 !(wasinside || canspotmon(mtmp)) ? "it"
2526 : !mtmp->mtame ? mon_nam(mtmp)
2527 : x_monnam(mtmp, namedpet ? ARTICLE_NONE : ARTICLE_THE,
2528 "poor", namedpet ? SUPPRESS_SADDLE : 0, FALSE));
2530 You("%s
\82ð
\93|
\82µ
\82½
\81I",
2531 !(wasinside || canspotmon(mtmp)) ? "
\89½
\8eÒ
\82©"
2532 : !mtmp->mtame ? mon_nam(mtmp)
2533 : x_monnam(mtmp, namedpet ? ARTICLE_NONE : ARTICLE_THE,
2534 "
\82©
\82í
\82¢
\82»
\82¤
\82È", namedpet ? SUPPRESS_SADDLE : 0, FALSE));
2538 if (mtmp->mtrapped && (t = t_at(x, y)) != 0
2539 && is_pit(t->ttyp)) {
2540 if (sobj_at(BOULDER, x, y))
2541 nocorpse = TRUE; /* Prevent corpses/treasure being created
2542 "on top" of boulder that is about to fall in.
2543 This is out of order, but cannot be helped
2544 unless this whole routine is rearranged. */
2545 if (m_carrying(mtmp, BOULDER))
2549 /* your pet knows who just killed it...watch out */
2550 if (mtmp->mtame && !mtmp->isminion)
2551 EDOG(mtmp)->killed_by_u = 1;
2553 if (wasinside && thrownobj && thrownobj != uball
2554 /* don't give to mon if missile is going to return to hero */
2555 && thrownobj != (struct obj *) iflags.returning_missile) {
2556 /* thrown object has killed hero's engulfer; add it to mon's
2557 inventory now so that it will be placed with mon's other
2558 stuff prior to lookhere/autopickup when hero is expelled
2559 below (as a side-effect, this missile has immunity from
2560 being consumed [for this shot/throw only]) */
2561 mpickobj(mtmp, thrownobj);
2562 /* let throwing code know that missile has been disposed of */
2566 vamp_rise_msg = FALSE; /* might get set in mondead(); only checked below */
2567 disintegested = nocorpse; /* alternate vamp_rise message needed if true */
2568 /* dispose of monster and make cadaver */
2573 disintegested = FALSE; /* reset */
2575 if (!DEADMONSTER(mtmp)) { /* monster lifesaved */
2576 /* Cannot put the non-visible lifesaving message in
2577 * lifesaved_monster() since the message appears only when _you_
2578 * kill it (as opposed to visible lifesaving which always appears).
2581 if (!cansee(x, y) && !vamp_rise_msg)
2583 pline("Maybe not...");
2585 pline("
\82¢
\82â
\81C
\88á
\82¤
\82©
\82à
\81D
\81D
\81D");
2589 mdat = mtmp->data; /* note: mondead can change mtmp->data */
2590 mndx = monsndx(mdat);
2597 if (nocorpse || LEVEL_SPECIFIC_NOCORPSE(mdat))
2601 if (mdat == &mons[PM_MAIL_DAEMON]) {
2602 stackobj(mksobj_at(SCR_MAIL, x, y, FALSE, FALSE));
2605 if (accessible(x, y) || is_pool(x, y)) {
2606 struct obj *cadaver;
2609 /* illogical but traditional "treasure drop" */
2610 if (!rn2(6) && !(mvitals[mndx].mvflags & G_NOCORPSE)
2611 /* no extra item from swallower or steed */
2612 && (x != u.ux || y != u.uy)
2613 /* no extra item from kops--too easy to abuse */
2614 && mdat->mlet != S_KOP
2615 /* no items from cloned monsters */
2616 && !mtmp->mcloned) {
2617 otmp = mkobj(RANDOM_CLASS, TRUE);
2618 /* don't create large objects from small monsters */
2620 if (mdat->msize < MZ_HUMAN && otyp != FIGURINE
2621 /* oc_big is also oc_bimanual and oc_bulky */
2622 && (otmp->owt > 30 || objects[otyp].oc_big)) {
2625 } else if (!flooreffects(otmp, x, y, nomsg ? "" : "fall")) {
2627 } else if (!flooreffects(otmp, x, y, nomsg ? "" : "
\97\8e\82¿
\82é")) {
2629 place_object(otmp, x, y);
2633 /* corpse--none if hero was inside the monster */
2634 if (!wasinside && corpse_chance(mtmp, (struct monst *) 0, FALSE)) {
2635 cadaver = make_corpse(mtmp, burycorpse ? CORPSTAT_BURIED
2637 if (burycorpse && cadaver && cansee(x, y) && !mtmp->minvis
2638 && cadaver->where == OBJ_BURIED && !nomsg) {
2640 pline("%s corpse ends up buried.", s_suffix(Monnam(mtmp)));
2642 pline("%s
\82Ì
\8e\80\91Ì
\82Í
\96\84\82Ü
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D", Monnam(mtmp));
2647 spoteffects(TRUE); /* poor man's expels() */
2648 /* monster is gone, corpse or other object might now be visible */
2652 /* punish bad behaviour */
2654 && (!always_hostile(mdat) && mtmp->malign <= 0)
2655 && (mndx < PM_ARCHEOLOGIST || mndx > PM_WIZARD)
2656 && u.ualign.type != A_CHAOTIC) {
2657 HTelepat &= ~INTRINSIC;
2662 You("
\8eE
\90l
\8bS
\82¾
\81I");
2663 if (Blind && !Blind_telepat)
2664 see_monsters(); /* Can't sense monsters any more. */
2666 if ((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame)
2668 if (is_unicorn(mdat) && sgn(u.ualign.type) == sgn(mdat->maligntyp)) {
2671 You_feel("guilty...");
2673 You("
\8dß
\82ð
\8a´
\82¶
\82½
\81D
\81D
\81D");
2676 /* give experience points */
2677 tmp = experience(mtmp, (int) mvitals[mndx].died);
2678 more_experienced(tmp, 0);
2679 newexplevel(); /* will decide if you go up */
2681 /* adjust alignment points */
2682 if (mtmp->m_id == quest_status.leader_m_id) { /* REAL BAD! */
2683 adjalign(-(u.ualign.record + (int) ALIGNLIM / 2));
2685 pline("That was %sa bad idea...",
2686 u.uevent.qcompleted ? "probably " : "");
2688 pline("%s
\82æ
\82
\82È
\82¢
\8ds
\88×
\82¾
\82Á
\82½
\81D
\81D
\81D",
2689 u.uevent.qcompleted ? "
\82½
\82Ô
\82ñ" : "");
2691 } else if (mdat->msound == MS_NEMESIS) { /* Real good! */
2692 adjalign((int) (ALIGNLIM / 4));
2693 } else if (mdat->msound == MS_GUARDIAN) { /* Bad */
2694 adjalign(-(int) (ALIGNLIM / 8));
2697 pline("That was probably a bad idea...");
2699 pline("
\82æ
\82
\82È
\82¢
\8ds
\88×
\82¾
\82Á
\82½
\81D
\81D
\81D");
2702 pline("Whoopsie-daisy!");
2704 pline("
\83V
\83\93\83W
\83}
\83b
\83^
\81[
\81I");
2705 } else if (mtmp->ispriest) {
2706 adjalign((p_coaligned(mtmp)) ? -2 : 2);
2707 /* cancel divine protection for killing your priest */
2708 if (p_coaligned(mtmp))
2710 if (mdat->maligntyp == A_NONE)
2711 adjalign((int) (ALIGNLIM / 4)); /* BIG bonus */
2712 } else if (mtmp->mtame) {
2713 adjalign(-15); /* bad!! */
2714 /* your god is mighty displeased... */
2717 You_hear("the rumble of distant thunder...");
2719 You_hear("
\89\93\82
\82Å
\97\8b\96Â
\82ð
\95·
\82¢
\82½
\81D
\81D
\81D");
2722 You_hear("the studio audience applaud!");
2724 pline("
\92®
\8fO
\82Ì
\8a\85\8dÑ
\82ð
\97\81\82Ñ
\82½
\81I");
2725 } else if (mtmp->mpeaceful)
2728 /* malign was already adjusted for u.ualign.type and randomization */
2729 adjalign(mtmp->malign);
2732 /* changes the monster into a stone monster of the same type
2733 this should only be called when poly_when_stoned() is true */
2738 if (mtmp->data->mlet == S_GOLEM) {
2739 /* it's a golem, and not a stone golem */
2740 if (canseemon(mtmp))
2742 pline("%s solidifies...", Monnam(mtmp));
2744 pline("%s
\82Í
\8bÃ
\8cÅ
\82µ
\82½
\81D
\81D
\81D", Monnam(mtmp));
2745 if (newcham(mtmp, &mons[PM_STONE_GOLEM], FALSE, FALSE)) {
2746 if (canseemon(mtmp))
2748 pline("Now it's %s.", an(mtmp->data->mname));
2750 pline("
\82È
\82ñ
\82Æ%s
\82É
\82È
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D", mtmp->data->mname);
2752 if (canseemon(mtmp))
2754 pline("... and returns to normal.");
2756 pline("
\81D
\81D
\81D
\82»
\82µ
\82Ä
\95\81\92Ê
\82É
\96ß
\82Á
\82½
\81D");
2759 impossible("Can't polystone %s!", a_monnam(mtmp));
2766 if (is_vampshifter(mtmp)) {
2767 int mndx = mtmp->cham;
2768 int x = mtmp->mx, y = mtmp->my;
2770 /* this only happens if shapeshifted */
2771 if (mndx >= LOW_PM && mndx != monsndx(mtmp->data)
2772 && !(mvitals[mndx].mvflags & G_GENOD)) {
2774 boolean in_door = (amorphous(mtmp->data)
2775 && closed_door(mtmp->mx, mtmp->my));
2777 /* construct a format string before transformation */
2779 Sprintf(buf, "The lapidifying %s %s %s",
2780 x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
2781 (SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION
2782 | SUPPRESS_INVISIBLE | SUPPRESS_IT), FALSE),
2783 amorphous(mtmp->data) ? "coalesces on the"
2784 : is_flyer(mtmp->data) ? "drops to the"
2788 Sprintf(buf, "
\90Î
\89»
\82µ
\82Â
\82Â
\82 \82é%s
\82ª%s%s",
2789 x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
2790 (SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION
2791 | SUPPRESS_INVISIBLE | SUPPRESS_IT), FALSE),
2793 amorphous(mtmp->data) ? "
\82Ì
\8fã
\82Å
\97Z
\8d\87\82µ
\82½"
2794 : is_flyer(mtmp->data) ? "
\82É
\97\8e\82¿
\82½"
2795 : "
\82Ì
\8fã
\82Å
\90g
\82à
\82¾
\82¦
\82½");
2799 if (mtmp->mhpmax <= 0)
2801 mtmp->mhp = mtmp->mhpmax;
2802 /* this can happen if previously a fog cloud */
2803 if (u.uswallow && (mtmp == u.ustuck))
2804 expels(mtmp, mtmp->data, FALSE);
2808 if (enexto(&new_xy, mtmp->mx, mtmp->my, &mons[mndx])) {
2809 rloc_to(mtmp, new_xy.x, new_xy.y);
2812 if (canspotmon(mtmp)) {
2816 pline("%s
\81I", buf);
2817 display_nhwindow(WIN_MESSAGE, FALSE);
2819 newcham(mtmp, &mons[mndx], FALSE, FALSE);
2820 if (mtmp->data == &mons[mndx])
2821 mtmp->cham = NON_PM;
2824 if (canspotmon(mtmp)) {
2826 pline("%s rises from the %s with renewed agility!",
2827 Amonnam(mtmp), surface(mtmp->mx, mtmp->my));
2829 pline("%s
\82Í
\8b@
\95q
\82³
\82ð
\8eæ
\82è
\96ß
\82µ
\82Ä%s
\82©
\82ç
\95\9c\8a\88\82µ
\82½
\81I",
2830 Amonnam(mtmp), surface(mtmp->mx, mtmp->my));
2833 newsym(mtmp->mx, mtmp->my);
2834 return FALSE; /* didn't petrify */
2836 } else if (mtmp->cham >= LOW_PM
2837 && (mons[mtmp->cham].mresists & MR_STONE)) {
2838 /* sandestins are stoning-immune so if hit by stoning damage
2839 they revert to innate shape rather than become a statue */
2842 if (mtmp->mhpmax <= 0)
2844 mtmp->mhp = mtmp->mhpmax;
2845 (void) newcham(mtmp, &mons[mtmp->cham], FALSE, TRUE);
2846 newsym(mtmp->mx, mtmp->my);
2847 return FALSE; /* didn't petrify */
2852 /* drop monster into "limbo" - that is, migrate to the current level */
2857 xchar target_lev = ledger_no(&u.uz), xyloc = MIGR_APPROX_XY;
2859 mtmp->mstate |= MON_LIMBO;
2860 migrate_mon(mtmp, target_lev, xyloc);
2864 migrate_mon(mtmp, target_lev, xyloc)
2866 xchar target_lev, xyloc;
2869 mdrop_special_objs(mtmp);
2870 migrate_to_level(mtmp, target_lev, xyloc, (coord *) 0);
2871 mtmp->mstate |= MON_MIGRATING;
2875 ok_to_obliterate(mtmp)
2879 * Add checks for monsters that should not be obliterated
2880 * here (return FALSE).
2882 if (mtmp->data == &mons[PM_WIZARD_OF_YENDOR] || is_rider(mtmp->data)
2883 || has_emin(mtmp) || has_epri(mtmp) || has_eshk(mtmp)
2884 || (u.ustuck == mtmp) || (u.usteed == mtmp))
2894 static long msgmv = 0L;
2895 struct monst *mtmp, *m1, *m2, *m3, *m4, *m5, *zm;
2897 if (In_endgame(&u.uz)) {
2898 m1 = m2 = m3 = m4 = m5 = zm = (struct monst *) 0;
2899 if (!msgmv || (moves - msgmv) > 200L) {
2900 if (!msgmv || rn2(2))
2902 You_feel("besieged.");
2904 You_feel("
\95ï
\88Í
\82³
\82ê
\82½
\82æ
\82¤
\82É
\8a´
\82¶
\82½
\81D");
2908 * m1 an elemental from another plane.
2909 * m2 an elemental from this plane.
2910 * m3 the least powerful monst encountered in loop so far.
2911 * m4 some other non-tame monster.
2914 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2915 if (DEADMONSTER(mtmp) || mtmp == mon)
2917 if (mtmp->mx == 0 && mtmp->my == 0)
2919 if (mon_has_amulet(mtmp) || !ok_to_obliterate(mtmp))
2921 if (mtmp->data->mlet == S_ELEMENTAL) {
2922 if (!is_home_elemental(mtmp->data)) {
2931 if (!m_lev || mtmp->m_lev < m_lev) {
2932 m_lev = mtmp->m_lev;
2944 mtmp = m1 ? m1 : m2 ? m2 : m3 ? m3 : m4 ? m4 : m5 ? m5 : zm;
2946 int mx = mtmp->mx, my = mtmp->my;
2948 mtmp->mstate |= MON_OBLITERATE;
2950 /* places in the code might still reference mtmp->mx, mtmp->my */
2951 /* mtmp->mx = mtmp->my = 0; */
2952 rloc_to(mon, mx, my); /* note: mon, not mtmp */
2954 /* last resort - migrate mon to the next plane */
2955 } else if (!Is_astralevel(&u.uz)) {
2961 target_lev = ledger_no(&dest);
2962 mon->mstate |= MON_ENDGAME_MIGR;
2963 migrate_mon(mon, target_lev, MIGR_RANDOM);
2968 /* make monster mtmp next to you (if possible);
2969 might place monst on far side of a wall or boulder */
2975 boolean couldspot = canspotmon(mtmp);
2977 if (mtmp == u.usteed) {
2978 /* Keep your steed in sync with you instead */
2984 if (!enexto(&mm, u.ux, u.uy, mtmp->data) || !isok(mm.x, mm.y)) {
2985 deal_with_overcrowding(mtmp);
2988 rloc_to(mtmp, mm.x, mm.y);
2989 if (!in_mklev && (mtmp->mstrategy & STRAT_APPEARMSG)) {
2990 mtmp->mstrategy &= ~STRAT_APPEARMSG; /* one chance only */
2991 if (!couldspot && canspotmon(mtmp))
2993 pline("%s suddenly %s!", Amonnam(mtmp),
2994 !Blind ? "appears" : "arrives");
2996 pline("
\93Ë
\91R%s
\82ª
\8c»
\82ê
\82½
\81I", Amonnam(mtmp));
3003 deal_with_overcrowding(mtmp)
3006 if (In_endgame(&u.uz)) {
3007 debugpline1("overcrowding: elemental_clog on %s", m_monnam(mtmp));
3008 elemental_clog(mtmp);
3010 debugpline1("overcrowding: sending %s into limbo", m_monnam(mtmp));
3015 /* like mnexto() but requires destination to be directly accessible */
3021 struct permonst *ptr = mtmp->data;
3022 boolean diagok = !NODIAG(ptr - mons);
3026 if (!enexto(&mm, u.ux, u.uy, ptr))
3028 if (couldsee(mm.x, mm.y)
3029 /* don't move grid bugs diagonally */
3030 && (diagok || mm.x == mtmp->mx || mm.y == mtmp->my)) {
3031 rloc_to(mtmp, mm.x, mm.y);
3034 } while (--tryct > 0);
3038 * Put monster near (or at) location if possible.
3040 * 2 if another monster was moved out of this one's way;
3041 * 1 if relocation was successful (without moving another one);
3043 * Note: if already at the target spot, result is 1 rather than 0.
3045 * Might be called recursively if 'move_other' is True; if so, that argument
3046 * will be False on the nested call so there won't be any further recursion.
3049 mnearto(mtmp, x, y, move_other)
3050 register struct monst *mtmp;
3052 boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */
3054 struct monst *othermon = (struct monst *) 0;
3059 if (mtmp->mx == x && mtmp->my == y && m_at(x, y) == mtmp)
3062 if (move_other && (othermon = m_at(x, y)) != 0) {
3063 if (othermon->wormno)
3064 remove_worm(othermon);
3066 remove_monster(x, y);
3068 othermon->mx = othermon->my = 0; /* 'othermon' is not on the map */
3069 othermon->mstate |= MON_OFFMAP;
3074 if (!goodpos(newx, newy, mtmp, 0)) {
3075 /* Actually we have real problems if enexto ever fails.
3076 * Migrating_mons that need to be placed will cause
3077 * no end of trouble.
3079 if (!enexto(&mm, newx, newy, mtmp->data) || !isok(mm.x, mm.y)) {
3081 /* othermon already had its mx, my set to 0 above
3082 * and this would shortly cause a sanity check to fail
3083 * if we just return 0 here. The caller only possesses
3084 * awareness of mtmp, not othermon. */
3085 deal_with_overcrowding(othermon);
3092 rloc_to(mtmp, newx, newy);
3094 if (move_other && othermon) {
3095 res = 2; /* moving another monster out of the way */
3096 if (!mnearto(othermon, x, y, FALSE)) /* no 'move_other' this time */
3097 deal_with_overcrowding(othermon);
3103 /* monster responds to player action; not the same as a passive attack;
3104 assumes reason for response has been tested, and response _must_ be made */
3109 if (mtmp->data->msound == MS_SHRIEK) {
3112 pline("%s shrieks.", Monnam(mtmp));
3114 pline("%s
\82Í
\8bà
\90Ø
\82è
\90º
\82ð
\82 \82°
\82½
\81D", Monnam(mtmp));
3119 (void) makemon(&mons[PM_PURPLE_WORM], 0, 0, NO_MM_FLAGS);
3121 (void) makemon((struct permonst *) 0, 0, 0, NO_MM_FLAGS);
3125 if (mtmp->data == &mons[PM_MEDUSA]) {
3128 for (i = 0; i < NATTK; i++)
3129 if (mtmp->data->mattk[i].aatyp == AT_GAZE) {
3130 (void) gazemu(mtmp, &mtmp->data->mattk[i]);
3136 /* Called whenever the player attacks mtmp; also called in other situations
3137 where mtmp gets annoyed at the player. Handles mtmp getting annoyed at the
3138 attack and any ramifications that might have. Useful also in situations
3139 where mtmp was already hostile; it checks for situations where the player
3140 shouldn't be attacking and any ramifications /that/ might have. */
3142 setmangry(mtmp, via_attack)
3146 if (via_attack && sengr_at("Elbereth", u.ux, u.uy, TRUE)
3147 /* only hypocritical if monster is vulnerable to Elbereth (or
3148 peaceful--not vulnerable but attacking it is hypocritical) */
3149 && (onscary(u.ux, u.uy, mtmp) || mtmp->mpeaceful)) {
3151 You_feel("like a hypocrite.");
3153 You_feel("
\8bU
\91P
\8eÒ
\82Ì
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
3154 /* AIS: Yes, I know alignment penalties and bonuses aren't balanced
3155 at the moment. This is about correct relative to other "small"
3156 penalties; it should be fairly large, as attacking while standing
3157 on an Elbereth means that you're requesting peace and then
3158 violating your own request. I know 5 isn't actually large, but
3159 it's intentionally larger than the 1s and 2s that are normally
3160 given for this sort of thing. */
3161 /* reduce to 3 (average) when alignment is already very low */
3162 adjalign((u.ualign.record > 5) ? -5 : -rnd(5));
3166 pline("The engraving beneath you fades.");
3168 pline("
\82 \82È
\82½
\82Ì
\91«
\8c³
\82Ì
\95¶
\8e\9a\82ª
\94\96\82ê
\82½
\81D");
3169 del_engr_at(u.ux, u.uy);
3172 /* AIS: Should this be in both places, or just in wakeup()? */
3173 mtmp->mstrategy &= ~STRAT_WAITMASK;
3174 if (!mtmp->mpeaceful)
3178 mtmp->mpeaceful = 0;
3179 if (mtmp->ispriest) {
3180 if (p_coaligned(mtmp))
3181 adjalign(-5); /* very bad */
3185 adjalign(-1); /* attacking peaceful monsters is bad */
3186 if (couldsee(mtmp->mx, mtmp->my)) {
3187 if (humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd)
3189 pline("%s gets angry!", Monnam(mtmp));
3191 pline("%s
\82Í
\93{
\82Á
\82½
\81I", Monnam(mtmp));
3192 else if (flags.verbose && !Deaf)
3196 /* attacking your own quest leader will anger his or her guardians */
3197 if (!context.mon_moving /* should always be the case here */
3198 && mtmp->data == &mons[quest_info(MS_LEADER)]) {
3200 struct permonst *q_guardian = &mons[quest_info(MS_GUARDIAN)];
3203 /* guardians will sense this attack even if they can't see it */
3204 for (mon = fmon; mon; mon = mon->nmon) {
3205 if (DEADMONSTER(mon))
3207 if (mon->data == q_guardian && mon->mpeaceful) {
3213 if (got_mad && !Hallucination) {
3214 const char *who = q_guardian->mname;
3218 who = makeplural(who);
3219 pline_The("%s %s to be angry too...",
3220 who, vtense(who, "appear"));
3222 pline("%s
\82à
\93{
\82Á
\82½
\82æ
\82¤
\82¾
\81D
\81D
\81D", who);
3227 /* make other peaceful monsters react */
3228 if (!context.mon_moving) {
3229 static const char *const Exclam[] = {
3231 "Gasp!", "Uh-oh.", "Oh my!", "What?", "Why?",
3233 "
\82®
\82Í
\82Á
\81I", "
\82¤
\82í
\81D", "
\82È
\82ñ
\82Æ
\81I", "
\82È
\82É
\82Á
\81H", "
\82È
\82ñ
\82¾
\81H",
3236 int mndx = monsndx(mtmp->data);
3238 for (mon = fmon; mon; mon = mon->nmon) {
3239 if (DEADMONSTER(mon))
3241 if (mon == mtmp) /* the mpeaceful test catches this since mtmp */
3242 continue; /* is no longer peaceful, but be explicit... */
3244 if (!mindless(mon->data) && mon->mpeaceful
3245 && couldsee(mon->mx, mon->my) && !mon->msleeping
3246 && mon->mcansee && m_canseeu(mon)) {
3247 boolean exclaimed = FALSE;
3249 if (humanoid(mon->data) || mon->isshk || mon->ispriest) {
3250 if (is_watch(mon->data)) {
3252 verbalize("Halt! You're under arrest!");
3254 verbalize("
\8e~
\82Ü
\82ê
\81I
\91ß
\95ß
\82·
\82é
\81I");
3255 (void) angry_guards(!!Deaf);
3258 verbalize("%s", Exclam[mon->m_id % SIZE(Exclam)]);
3261 /* shopkeepers and temple priests might gasp in
3262 surprise, but they won't become angry here */
3263 if (mon->isshk || mon->ispriest)
3266 if (mon->data->mlevel < rn2(10)) {
3267 monflee(mon, rn2(50) + 25, TRUE, !exclaimed);
3271 /* mustn't set mpeaceful to 0 as below;
3272 perhaps reduce tameness? */
3278 pline("%s gets angry!", Monnam(mon));
3280 pline("%s
\82Í
\93{
\82Á
\82½
\81I", Monnam(mon));
3283 } else if (mon->data->mlet == mtmp->data->mlet
3284 && big_little_match(mndx, monsndx(mon->data))
3291 monflee(mon, rn2(25) + 15, TRUE, !exclaimed);
3298 /* wake up a monster, possibly making it angry in the process */
3300 wakeup(mtmp, via_attack)
3301 register struct monst *mtmp;
3304 mtmp->msleeping = 0;
3305 if (M_AP_TYPE(mtmp)) {
3307 } else if (context.forcefight && !context.mon_moving
3308 && mtmp->mundetected) {
3309 mtmp->mundetected = 0;
3310 newsym(mtmp->mx, mtmp->my);
3312 finish_meating(mtmp);
3314 setmangry(mtmp, TRUE);
3317 /* Wake up nearby monsters without angering them. */
3321 wake_nearto(u.ux, u.uy, u.ulevel * 20);
3324 /* Wake up monsters near some particular location. */
3326 wake_nearto(x, y, distance)
3331 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
3332 if (DEADMONSTER(mtmp))
3334 if (distance == 0 || dist2(mtmp->mx, mtmp->my, x, y) < distance) {
3335 /* sleep for N turns uses mtmp->mfrozen, but so does paralysis
3336 so we leave mfrozen monsters alone */
3337 mtmp->msleeping = 0; /* wake indeterminate sleep */
3338 if (!(mtmp->data->geno & G_UNIQ))
3339 mtmp->mstrategy &= ~STRAT_WAITMASK; /* wake 'meditation' */
3340 if (context.mon_moving)
3343 if (!mtmp->isminion)
3344 EDOG(mtmp)->whistletime = moves;
3345 /* Clear mtrack. This is to fix up a pet who is
3346 stuck "fleeing" its master. */
3347 memset(mtmp->mtrack, 0, sizeof mtmp->mtrack);
3353 /* NOTE: we must check for mimicry before calling this routine */
3356 register struct monst *mtmp;
3358 boolean is_blocker_appear = (is_lightblocker_mappear(mtmp));
3360 if (has_mcorpsenm(mtmp))
3361 freemcorpsenm(mtmp);
3363 mtmp->m_ap_type = M_AP_NOTHING;
3364 mtmp->mappearance = 0;
3367 * Discovered mimics don't block light.
3369 if (is_blocker_appear
3370 && !does_block(mtmp->mx, mtmp->my, &levl[mtmp->mx][mtmp->my]))
3371 unblock_point(mtmp->mx, mtmp->my);
3373 newsym(mtmp->mx, mtmp->my);
3376 /* force all chameleons to become normal */
3380 register struct monst *mtmp;
3383 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
3384 if (DEADMONSTER(mtmp))
3386 mcham = (int) mtmp->cham;
3387 if (mcham >= LOW_PM) {
3388 (void) newcham(mtmp, &mons[mcham], FALSE, FALSE);
3389 mtmp->cham = NON_PM;
3391 if (is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN)
3393 if (M_AP_TYPE(mtmp) && cansee(mtmp->mx, mtmp->my)) {
3395 /* we pretend that the mimic doesn't
3396 know that it has been unmasked */
3397 mtmp->msleeping = 1;
3402 /* Let the chameleons change again -dgk */
3406 register struct monst *mtmp;
3408 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
3409 if (DEADMONSTER(mtmp))
3412 mtmp->cham = pm_to_cham(monsndx(mtmp->data));
3413 if (mtmp->data->mlet == S_MIMIC && mtmp->msleeping
3414 && cansee(mtmp->mx, mtmp->my)) {
3415 set_mimic_sym(mtmp);
3416 newsym(mtmp->mx, mtmp->my);
3421 /* called when restoring a monster from a saved level; protection
3422 against shape-changing might be different now than it was at the
3423 time the level was saved. */
3430 if (Protection_from_shape_changers) {
3431 mcham = (int) mon->cham;
3432 if (mcham >= LOW_PM) {
3434 (void) newcham(mon, &mons[mcham], FALSE, FALSE);
3435 } else if (is_were(mon->data) && !is_human(mon->data)) {
3438 } else if (mon->cham == NON_PM) {
3439 mon->cham = pm_to_cham(monsndx(mon->data));
3443 /* unwatched hiders may hide again; if so, returns True */
3446 register struct monst *mtmp;
3450 if (mtmp->mcan || M_AP_TYPE(mtmp) || cansee(mtmp->mx, mtmp->my)
3451 || rn2(3) || mtmp == u.ustuck
3452 /* can't hide while trapped except in pits */
3453 || (mtmp->mtrapped && (t = t_at(mtmp->mx, mtmp->my)) != 0
3454 && !is_pit(t->ttyp))
3455 || (sensemon(mtmp) && distu(mtmp->mx, mtmp->my) <= 2))
3458 if (mtmp->data->mlet == S_MIMIC) {
3459 set_mimic_sym(mtmp);
3461 } else if (levl[mtmp->mx][mtmp->my].typ == ROOM) {
3462 mtmp->mundetected = 1;
3469 /* monster/hero tries to hide under something at the current location */
3475 boolean undetected = FALSE, is_u = (mtmp == &youmonst);
3476 xchar x = is_u ? u.ux : mtmp->mx, y = is_u ? u.uy : mtmp->my;
3478 if (mtmp == u.ustuck) {
3479 ; /* can't hide if holding you or held by you */
3480 } else if (is_u ? (u.utrap && u.utraptype != TT_PIT)
3481 : (mtmp->mtrapped && (t = t_at(x, y)) != 0
3482 && !is_pit(t->ttyp))) {
3483 ; /* can't hide while stuck in a non-pit trap */
3484 } else if (mtmp->data->mlet == S_EEL) {
3485 undetected = (is_pool(x, y) && !Is_waterlevel(&u.uz));
3486 } else if (hides_under(mtmp->data) && OBJ_AT(x, y)) {
3487 struct obj *otmp = level.objects[x][y];
3489 /* most monsters won't hide under cockatrice corpse */
3490 if (otmp->nexthere || otmp->otyp != CORPSE
3491 || (mtmp == &youmonst ? Stone_resistance : resists_ston(mtmp))
3492 || !touch_petrifies(&mons[otmp->corpsenm]))
3497 u.uundetected = undetected;
3499 mtmp->mundetected = undetected;
3503 /* called when returning to a previously visited level */
3508 boolean hider_under = hides_under(mon->data) || mon->data->mlet == S_EEL;
3510 if ((is_hider(mon->data) || hider_under)
3511 && !(mon->mundetected || M_AP_TYPE(mon))) {
3512 xchar x = mon->mx, y = mon->my;
3513 char save_viz = viz_array[y][x];
3515 /* override vision, forcing hero to be unable to see monster's spot */
3516 viz_array[y][x] &= ~(IN_SIGHT | COULD_SEE);
3517 if (is_hider(mon->data))
3518 (void) restrap(mon);
3519 /* try again if mimic missed its 1/3 chance to hide */
3520 if (mon->data->mlet == S_MIMIC && !M_AP_TYPE(mon))
3521 (void) restrap(mon);
3523 (void) hideunder(mon);
3524 viz_array[y][x] = save_viz;
3528 static short *animal_list = 0; /* list of PM values for animal monsters */
3529 static int animal_list_count;
3532 mon_animal_list(construct)
3536 short animal_temp[SPECIAL_PM];
3539 /* if (animal_list) impossible("animal_list already exists"); */
3541 for (n = 0, i = LOW_PM; i < SPECIAL_PM; i++)
3542 if (is_animal(&mons[i]))
3543 animal_temp[n++] = i;
3544 /* if (n == 0) animal_temp[n++] = NON_PM; */
3546 animal_list = (short *) alloc(n * sizeof *animal_list);
3547 (void) memcpy((genericptr_t) animal_list, (genericptr_t) animal_temp,
3548 n * sizeof *animal_list);
3549 animal_list_count = n;
3550 } else { /* release */
3552 free((genericptr_t) animal_list), animal_list = 0;
3553 animal_list_count = 0;
3563 mon_animal_list(TRUE);
3565 res = animal_list[rn2(animal_list_count)];
3566 /* rogue level should use monsters represented by uppercase letters
3567 only, but since chameleons aren't generated there (not uppercase!)
3568 we don't perform a lot of retries */
3569 if (Is_rogue_level(&u.uz) && !isupper((uchar) mons[res].mlet))
3570 res = animal_list[rn2(animal_list_count)];
3575 decide_to_shapeshift(mon, shiftflags)
3579 struct permonst *ptr = 0;
3581 unsigned was_female = mon->female;
3582 boolean msg = FALSE, dochng = FALSE;
3584 if ((shiftflags & SHIFT_MSG)
3585 || ((shiftflags & SHIFT_SEENMSG) && sensemon(mon)))
3588 if (!is_vampshifter(mon)) {
3589 /* regular shapeshifter */
3593 /* The vampire has to be in good health (mhp) to maintain
3596 * If we're shifted and getting low on hp, maybe shift back, or
3597 * if we're a fog cloud at full hp, maybe pick a different shape.
3598 * If we're not already shifted and in good health, maybe shift.
3600 if (mon->data->mlet != S_VAMPIRE) {
3601 if ((mon->mhp <= (mon->mhpmax + 5) / 6) && rn2(4)
3602 && mon->cham >= LOW_PM) {
3603 ptr = &mons[mon->cham];
3605 } else if (mon->data == &mons[PM_FOG_CLOUD]
3606 && mon->mhp == mon->mhpmax && !rn2(4)
3608 || distu(mon->mx, mon->my) > BOLT_LIM * BOLT_LIM)) {
3609 /* if a fog cloud, maybe change to wolf or vampire bat;
3610 those are more likely to take damage--at least when
3611 tame--and then switch back to vampire; they'll also
3612 switch to fog cloud if they encounter a closed door */
3613 mndx = pickvampshape(mon);
3614 if (mndx >= LOW_PM) {
3616 dochng = (ptr != mon->data);
3620 if (mon->mhp >= 9 * mon->mhpmax / 10 && !rn2(6)
3622 || distu(mon->mx, mon->my) > BOLT_LIM * BOLT_LIM))
3623 dochng = TRUE; /* 'ptr' stays Null */
3627 if (newcham(mon, ptr, FALSE, msg) && is_vampshifter(mon)) {
3628 /* for vampshift, override the 10% chance for sex change */
3630 if (!is_male(ptr) && !is_female(ptr) && !is_neuter(ptr))
3631 mon->female = was_female;
3640 int mndx = mon->cham, wolfchance = 10;
3641 /* avoid picking monsters with lowercase display symbols ('d' for wolf
3642 and 'v' for fog cloud) on rogue level*/
3643 boolean uppercase_only = Is_rogue_level(&u.uz);
3646 case PM_VLAD_THE_IMPALER:
3647 /* ensure Vlad can keep carrying the Candelabrum */
3648 if (mon_has_special(mon))
3649 break; /* leave mndx as is */
3652 case PM_VAMPIRE_LORD: /* vampire lord or Vlad can become wolf */
3653 if (!rn2(wolfchance) && !uppercase_only) {
3658 case PM_VAMPIRE: /* any vampire can become fog or bat */
3659 mndx = (!rn2(4) && !uppercase_only) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT;
3665 /* nonshapechangers who warrant special polymorph handling */
3670 return (mon->isshk || mon->ispriest || mon->isgd
3671 || mon->m_id == quest_status.leader_m_id);
3674 /* restrict certain special monsters (shopkeepers, aligned priests,
3675 vault guards) to forms that allow them to behave sensibly (catching
3676 gold, speaking?) so that they don't need too much extra code */
3678 validspecmon(mon, mndx)
3683 return TRUE; /* caller wants random */
3685 if (!accept_newcham_form(mon, mndx))
3686 return FALSE; /* geno'd or !polyok */
3688 if (isspecmon(mon)) {
3689 struct permonst *ptr = &mons[mndx];
3691 /* reject notake because object manipulation is expected
3692 and nohead because speech capability is expected */
3693 if (notake(ptr) || !has_head(ptr))
3695 /* [should we check ptr->msound here too?] */
3697 return TRUE; /* potential new form is ok */
3700 /* prevent wizard mode user from specifying invalid vampshifter shape */
3702 validvamp(mon, mndx_p, monclass)
3704 int *mndx_p, monclass;
3706 /* simplify caller's usage */
3707 if (!is_vampshifter(mon))
3708 return validspecmon(mon, *mndx_p);
3710 if (mon->cham == PM_VLAD_THE_IMPALER && mon_has_special(mon)) {
3711 /* Vlad with Candelabrum; override choice, then accept it */
3712 *mndx_p = PM_VLAD_THE_IMPALER;
3715 if (*mndx_p >= LOW_PM && is_shapeshifter(&mons[*mndx_p])) {
3716 /* player picked some type of shapeshifter; use mon's self
3717 (vampire or chameleon) */
3718 *mndx_p = mon->cham;
3721 /* basic vampires can't become wolves; any can become fog or bat
3722 (we don't enforce upper-case only for rogue level here) */
3723 if (*mndx_p == PM_WOLF)
3724 return (boolean) (mon->cham != PM_VAMPIRE);
3725 if (*mndx_p == PM_FOG_CLOUD || *mndx_p == PM_VAMPIRE_BAT)
3728 /* if we get here, specific type was no good; try by class */
3731 *mndx_p = mon->cham;
3734 *mndx_p = PM_VAMPIRE_BAT;
3737 *mndx_p = PM_FOG_CLOUD;
3740 if (mon->cham != PM_VAMPIRE) {
3749 return (boolean) (*mndx_p != NON_PM);
3753 select_newcham_form(mon)
3756 int mndx = NON_PM, tryct;
3758 switch (mon->cham) {
3761 mndx = pick_nasty();
3763 case PM_DOPPELGANGER:
3765 mndx = pick_nasty();
3766 } else if (rn2(3)) { /* role monsters */
3767 mndx = rn1(PM_WIZARD - PM_ARCHEOLOGIST + 1, PM_ARCHEOLOGIST);
3768 } else if (!rn2(3)) { /* quest guardians */
3769 mndx = rn1(PM_APPRENTICE - PM_STUDENT + 1, PM_STUDENT);
3770 /* avoid own role's guardian */
3771 if (mndx == urole.guardnum)
3773 } else { /* general humanoids */
3776 mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
3777 if (humanoid(&mons[mndx]) && polyok(&mons[mndx]))
3779 } while (--tryct > 0);
3786 mndx = pick_animal();
3788 case PM_VLAD_THE_IMPALER:
3789 case PM_VAMPIRE_LORD:
3791 mndx = pickvampshape(mon);
3793 case NON_PM: /* ordinary */
3795 struct obj *m_armr = which_armor(mon, W_ARM);
3797 if (m_armr && Is_dragon_scales(m_armr))
3798 mndx = (int) (Dragon_scales_to_pm(m_armr) - mons);
3799 else if (m_armr && Is_dragon_mail(m_armr))
3800 mndx = (int) (Dragon_mail_to_pm(m_armr) - mons);
3805 /* for debugging: allow control of polymorphed monster */
3806 if (wizard && iflags.mon_polycontrol) {
3807 char pprompt[BUFSZ], parttwo[QBUFSZ], buf[BUFSZ];
3810 /* construct prompt in pieces */
3811 Sprintf(pprompt, "Change %s", noit_mon_nam(mon));
3812 Sprintf(parttwo, " @ %s into what?",
3813 coord_desc((int) mon->mx, (int) mon->my, buf,
3814 (iflags.getpos_coords != GPCOORDS_NONE)
3815 ? iflags.getpos_coords : GPCOORDS_MAP));
3816 /* combine the two parts, not exceeding QBUFSZ-1 in overall length;
3817 if combined length is too long it has to be due to monster's
3818 name so we'll chop enough of that off to fit the second part */
3819 if ((len = (int) strlen(pprompt) + (int) strlen(parttwo)) >= QBUFSZ)
3820 /* strlen(parttwo) is less than QBUFSZ/2 so strlen(pprompt) is
3821 more than QBUFSZ/2 and excess amount being truncated can't
3822 exceed pprompt's length and back up to before &pprompt[0]) */
3823 *(eos(pprompt) - (len - (QBUFSZ - 1))) = '\0';
3824 Strcat(pprompt, parttwo);
3826 buf[0] = '\0'; /* clear buffer for EDIT_GETLIN */
3830 if (tryct == TRYLIMIT - 1) { /* first retry */
3831 /* change "into what?" to "into what kind of monster?" */
3832 if (strlen(pprompt) + sizeof " kind of monster" - 1 < QBUFSZ)
3833 Strcpy(eos(pprompt) - 1, " kind of monster?");
3837 getlin(pprompt, buf);
3839 /* for ESC, take form selected above (might be NON_PM) */
3842 /* for "*", use NON_PM to pick an arbitrary shape below */
3843 if (!strcmp(buf, "*") || !strcmpi(buf, "random")) {
3847 mndx = name_to_mon(buf);
3848 if (mndx == NON_PM) {
3849 /* didn't get a type, so check whether it's a class
3850 (single letter or text match with def_monsyms[]) */
3851 monclass = name_to_monclass(buf, &mndx);
3852 if (monclass && mndx == NON_PM)
3853 mndx = mkclass_poly(monclass);
3855 if (mndx >= LOW_PM) {
3856 /* got a specific type of monster; use it if we can */
3857 if (validvamp(mon, &mndx, monclass))
3859 /* can't; revert to random in case we exhaust tryct */
3863 pline("It can't become that.");
3864 } while (--tryct > 0);
3867 pline1(thats_enough_tries);
3868 if (is_vampshifter(mon) && !validvamp(mon, &mndx, monclass))
3869 mndx = pickvampshape(mon); /* don't resort to arbitrary */
3872 /* if no form was specified above, pick one at random now */
3873 if (mndx == NON_PM) {
3876 mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
3877 } while (--tryct > 0 && !validspecmon(mon, mndx)
3878 /* try harder to select uppercase monster on rogue level */
3879 && (tryct > 40 && Is_rogue_level(&u.uz)
3880 && !isupper((uchar) mons[mndx].mlet)));
3885 /* this used to be inline within newcham() but monpolycontrol needs it too */
3886 STATIC_OVL struct permonst *
3887 accept_newcham_form(mon, mndx)
3891 struct permonst *mdat;
3896 if ((mvitals[mndx].mvflags & G_GENOD) != 0)
3898 if (is_placeholder(mdat))
3900 /* select_newcham_form() might deliberately pick a player
3901 character type (random selection never does) which
3902 polyok() rejects, so we need a special case here */
3903 if (is_mplayer(mdat))
3905 /* shapeshifters are rejected by polyok() but allow a shapeshifter
3906 to take on its 'natural' form */
3907 if (is_shapeshifter(mdat)
3908 && mon->cham >= LOW_PM && mdat == &mons[mon->cham])
3910 /* polyok() rules out M2_PNAME, M2_WERE, and all humans except Kops */
3911 return polyok(mdat) ? mdat : 0;
3915 mgender_from_permonst(mtmp, mdat)
3917 struct permonst *mdat;
3919 if (is_male(mdat)) {
3921 mtmp->female = FALSE;
3922 } else if (is_female(mdat)) {
3924 mtmp->female = TRUE;
3925 } else if (!is_neuter(mdat)) {
3927 mtmp->female = !mtmp->female;
3931 /* make a chameleon take on another shape, or a polymorph target
3932 (possibly self-inflicted) become a different monster;
3933 returns 1 if it actually changes form */
3935 newcham(mtmp, mdat, polyspot, msg)
3937 struct permonst *mdat;
3938 boolean polyspot; /* change is the result of wand or spell of polymorph */
3939 boolean msg; /* "The oldmon turns into a newmon!" */
3943 struct permonst *olddata = mtmp->data;
3944 char *p, oldname[BUFSZ], l_oldname[BUFSZ], newname[BUFSZ];
3946 /* Riders are immune to polymorph and green slime
3947 (but apparent Rider might actually be a doppelganger) */
3948 if (mtmp->cham == NON_PM) { /* not a shapechanger */
3949 if (is_rider(olddata))
3951 /* make Nazgul and erinyes immune too, to reduce chance of
3952 anomalous extinction feedback during final disclsoure */
3953 if (mbirth_limit(monsndx(olddata)) < MAXMONNO)
3955 /* cancelled shapechangers become uncancelled prior
3956 to being given a new shape */
3957 if (mtmp->mcan && !Protection_from_shape_changers) {
3958 mtmp->cham = pm_to_cham(monsndx(mtmp->data));
3959 if (mtmp->cham != NON_PM)
3965 /* like Monnam() but never mention saddle */
3966 Strcpy(oldname, x_monnam(mtmp, ARTICLE_THE, (char *) 0,
3967 SUPPRESS_SADDLE, FALSE));
3968 oldname[0] = highc(oldname[0]);
3970 /* we need this one whether msg is true or not */
3971 Strcpy(l_oldname, x_monnam(mtmp, ARTICLE_THE, (char *) 0,
3972 has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE));
3974 /* mdat = 0 -> caller wants a random monster shape */
3976 /* select_newcham_form() loops when resorting to random but
3977 it doesn't always pick that so we still retry here too */
3980 mndx = select_newcham_form(mtmp);
3981 mdat = accept_newcham_form(mtmp, mndx);
3982 /* for the first several tries we require upper-case on
3983 the rogue level (after that, we take whatever we get) */
3984 if (tryct > 15 && Is_rogue_level(&u.uz)
3985 && mdat && !isupper((uchar) mdat->mlet))
3989 } while (--tryct > 0);
3992 } else if (mvitals[monsndx(mdat)].mvflags & G_GENOD)
3993 return 0; /* passed in mdat is genocided */
3995 if (mdat == olddata)
3996 return 0; /* still the same monster */
3998 mgender_from_permonst(mtmp, mdat);
3999 /* Endgame mplayers start out as "Foo the Bar", but some of the
4000 * titles are inappropriate when polymorphed, particularly into
4001 * the opposite sex. Player characters don't use ranks when
4002 * polymorphed, so dropping rank for mplayers seems reasonable.
4004 if (In_endgame(&u.uz) && is_mplayer(olddata)
4005 && has_mname(mtmp) && (p = strstr(MNAME(mtmp), " the ")) != 0)
4008 if (mtmp->wormno) { /* throw tail away */
4010 place_monster(mtmp, mtmp->mx, mtmp->my);
4012 if (M_AP_TYPE(mtmp) && mdat->mlet != S_MIMIC)
4013 seemimic(mtmp); /* revert to normal monster */
4015 /* (this code used to try to adjust the monster's health based on
4016 a normal one of its type but there are too many special cases
4017 which need to handled in order to do that correctly, so just
4018 give the new form the same proportion of HP as its old one had) */
4021 /* set level and hit points */
4022 newmonhp(mtmp, monsndx(mdat));
4023 /* new hp: same fraction of max as before */
4025 mtmp->mhp = (int) (((long) hpn * (long) mtmp->mhp) / (long) hpd);
4027 /* sanity check (potential overflow) */
4028 if (mtmp->mhp < 0 || mtmp->mhp > mtmp->mhpmax)
4029 mtmp->mhp = mtmp->mhpmax;
4030 /* unlikely but not impossible; a 1HD creature with 1HP that changes
4031 into a 0HD creature will require this statement */
4035 /* take on the new form... */
4036 set_mon_data(mtmp, mdat);
4038 if (mtmp->mleashed && !leashable(mtmp))
4039 m_unleash(mtmp, TRUE);
4041 if (emits_light(olddata) != emits_light(mtmp->data)) {
4042 /* used to give light, now doesn't, or vice versa,
4043 or light's range has changed */
4044 if (emits_light(olddata))
4045 del_light_source(LS_MONSTER, monst_to_any(mtmp));
4046 if (emits_light(mtmp->data))
4047 new_light_source(mtmp->mx, mtmp->my, emits_light(mtmp->data),
4048 LS_MONSTER, monst_to_any(mtmp));
4050 if (!mtmp->perminvis || pm_invisible(olddata))
4051 mtmp->perminvis = pm_invisible(mdat);
4052 mtmp->minvis = mtmp->invis_blkd ? 0 : mtmp->perminvis;
4053 if (mtmp->mundetected)
4054 (void) hideunder(mtmp);
4055 if (u.ustuck == mtmp) {
4057 if (!attacktype(mdat, AT_ENGL)) {
4058 /* Does mdat care? */
4059 if (!noncorporeal(mdat) && !amorphous(mdat)
4060 && !is_whirly(mdat) && (mdat != &mons[PM_YELLOW_LIGHT])) {
4061 char msgtrail[BUFSZ];
4063 if (is_vampshifter(mtmp)) {
4065 Sprintf(msgtrail, " which was a shapeshifted %s",
4066 noname_monnam(mtmp, ARTICLE_NONE));
4068 Sprintf(msgtrail, "(
\8eÀ
\8dÛ
\82É
\82Í
\8c`
\82ð
\95Ï
\82¦
\82½%s)",
4069 noname_monnam(mtmp, ARTICLE_NONE));
4071 } else if (is_animal(mdat)) {
4073 Strcpy(msgtrail, "'s stomach");
4075 Strcpy(msgtrail, "
\82Ì
\88Ý");
4080 /* Do this even if msg is FALSE */
4083 (amorphous(olddata) || is_whirly(olddata))
4084 ? "emerge from" : "break out of",
4085 l_oldname, msgtrail);
4087 You("%s%s%s
\81I", l_oldname, msgtrail,
4088 (amorphous(olddata) || is_whirly(olddata))
4089 ? "
\82©
\82ç
\94ò
\82Ñ
\8fo
\82µ
\82½" : "
\82ð
\94j
\82è
\8fo
\82½"
4092 msg = FALSE; /* message has been given */
4093 mtmp->mhp = 1; /* almost dead */
4095 expels(mtmp, olddata, FALSE);
4097 /* update swallow glyphs for new monster */
4100 } else if (!sticks(mdat) && !sticks(youmonst.data))
4105 if (mdat == &mons[PM_LONG_WORM] && (mtmp->wormno = get_wormno()) != 0) {
4107 /* DICE 3.0 doesn't like assigning and comparing mtmp->wormno in the
4110 if (mdat == &mons[PM_LONG_WORM]
4111 && (mtmp->wormno = get_wormno(), mtmp->wormno != 0)) {
4113 /* we can now create worms with tails - 11/91 */
4114 initworm(mtmp, rn2(5));
4115 place_worm_tail_randomly(mtmp, mtmp->mx, mtmp->my);
4118 newsym(mtmp->mx, mtmp->my);
4121 Strcpy(newname, noname_monnam(mtmp, ARTICLE_A));
4122 /* oldname was capitalized above; newname will be lower case */
4124 if (!strcmpi(newname, "it")) { /* can't see or sense it now */
4126 if (!strcmpi(newname, "
\89½
\8eÒ
\82©")) { /* can't see or sense it now */
4129 if (!!strcmpi(oldname, "it")) /* could see or sense it before */
4131 if (!!strcmpi(oldname, "
\89½
\8eÒ
\82©")) /* could see or sense it before */
4134 pline("%s disappears!", oldname);
4136 pline("%s
\82Í
\8fÁ
\82¦
\82½
\81I", oldname);
4137 (void) usmellmon(mdat);
4138 } else { /* can see or sense it now */
4140 if (!strcmpi(oldname, "it")) /* couldn't see or sense it before */
4142 if (!strcmpi(oldname, "
\89½
\8eÒ
\82©")) /* couldn't see or sense it before */
4145 pline("%s appears!", upstart(newname));
4147 pline("%s
\82ª
\8c»
\82ê
\82½
\81I", upstart(newname));
4150 pline("%s turns into %s!", oldname, newname);
4152 pline("%s
\82Í%s
\82É
\82È
\82Á
\82½
\81I", oldname, newname);
4156 /* when polymorph trap/wand/potion produces a vampire, turn in into
4157 a full-fledged vampshifter unless shape-changing is blocked */
4158 if (mtmp->cham == NON_PM && mdat->mlet == S_VAMPIRE
4159 && !Protection_from_shape_changers)
4160 mtmp->cham = pm_to_cham(monsndx(mdat));
4162 possibly_unwield(mtmp, polyspot); /* might lose use of weapon */
4163 mon_break_armor(mtmp, polyspot);
4164 if (!(mtmp->misc_worn_check & W_ARMG))
4166 mselftouch(mtmp, "No longer petrify-resistant, ",
4167 !context.mon_moving);
4169 mselftouch(mtmp, "
\90Î
\89»
\82Ö
\82Ì
\92ï
\8dR
\97Í
\82ª
\82È
\82
\82È
\82Á
\82Ä
\81C",
4170 !context.mon_moving);
4172 m_dowear(mtmp, FALSE);
4174 /* This ought to re-test can_carry() on each item in the inventory
4175 * rather than just checking ex-giants & boulders, but that'd be
4176 * pretty expensive to perform. If implemented, then perhaps
4177 * minvent should be sorted in order to drop heaviest items first.
4179 /* former giants can't continue carrying boulders */
4180 if (mtmp->minvent && !throws_rocks(mdat)) {
4181 register struct obj *otmp, *otmp2;
4183 for (otmp = mtmp->minvent; otmp; otmp = otmp2) {
4185 if (otmp->otyp == BOULDER) {
4186 /* this keeps otmp from being polymorphed in the
4187 same zap that the monster that held it is polymorphed */
4190 obj_extract_self(otmp);
4191 /* probably ought to give some "drop" message here */
4192 if (flooreffects(otmp, mtmp->mx, mtmp->my, ""))
4194 place_object(otmp, mtmp->mx, mtmp->my);
4202 /* sometimes an egg will be special */
4203 #define BREEDER_EGG (!rn2(77))
4206 * Determine if the given monster number can be hatched from an egg.
4207 * Return the monster number to use as the egg's corpsenm. Return
4208 * NON_PM if the given monster can't be hatched.
4211 can_be_hatched(mnum)
4214 /* ranger quest nemesis has the oviparous bit set, making it
4215 be possible to wish for eggs of that unique monster; turn
4216 such into ordinary eggs rather than forbidding them outright */
4217 if (mnum == PM_SCORPIUS)
4220 mnum = little_to_big(mnum);
4222 * Queen bees lay killer bee eggs (usually), but killer bees don't
4223 * grow into queen bees. Ditto for [winged-]gargoyles.
4225 if (mnum == PM_KILLER_BEE || mnum == PM_GARGOYLE
4226 || (lays_eggs(&mons[mnum])
4228 || (mnum != PM_QUEEN_BEE && mnum != PM_WINGED_GARGOYLE))))
4233 /* type of egg laid by #sit; usually matches parent */
4235 egg_type_from_parent(mnum, force_ordinary)
4236 int mnum; /* parent monster; caller must handle lays_eggs() check */
4237 boolean force_ordinary;
4239 if (force_ordinary || !BREEDER_EGG) {
4240 if (mnum == PM_QUEEN_BEE)
4241 mnum = PM_KILLER_BEE;
4242 else if (mnum == PM_WINGED_GARGOYLE)
4248 /* decide whether an egg of the indicated monster type is viable;
4249 also used to determine whether an egg or tin can be created... */
4251 dead_species(m_idx, egg)
4257 /* generic eggs are unhatchable and have corpsenm of NON_PM */
4261 * For monsters with both baby and adult forms, genociding either
4262 * form kills all eggs of that monster. Monsters with more than
4263 * two forms (small->large->giant mimics) are more or less ignored;
4264 * fortunately, none of them have eggs. Species extinction due to
4265 * overpopulation does not kill eggs.
4267 alt_idx = egg ? big_to_little(m_idx) : m_idx;
4268 return (boolean) ((mvitals[m_idx].mvflags & G_GENOD) != 0
4269 || (mvitals[alt_idx].mvflags & G_GENOD) != 0);
4272 /* kill off any eggs of genocided monsters */
4275 struct obj *obj_list;
4279 for (otmp = obj_list; otmp; otmp = otmp->nobj)
4280 if (otmp->otyp == EGG) {
4281 if (dead_species(otmp->corpsenm, TRUE)) {
4283 * It seems we could also just catch this when
4284 * it attempted to hatch, so we wouldn't have to
4285 * search all of the objlists.. or stop all
4286 * hatch timers based on a corpsenm.
4290 #if 0 /* not used */
4291 } else if (otmp->otyp == TIN) {
4292 if (dead_species(otmp->corpsenm, FALSE))
4293 otmp->corpsenm = NON_PM; /* empty tin */
4294 } else if (otmp->otyp == CORPSE) {
4295 if (dead_species(otmp->corpsenm, FALSE))
4296 ; /* not yet implemented... */
4298 } else if (Has_contents(otmp)) {
4299 kill_eggs(otmp->cobj);
4303 /* kill all members of genocided species */
4305 kill_genocided_monsters()
4307 struct monst *mtmp, *mtmp2;
4312 * Called during genocide, and again upon level change. The latter
4313 * catches up with any migrating monsters as they finally arrive at
4314 * their intended destinations, so possessions get deposited there.
4316 * Chameleon handling:
4317 * 1) if chameleons have been genocided, destroy them
4318 * regardless of current form;
4319 * 2) otherwise, force every chameleon which is imitating
4320 * any genocided species to take on a new form.
4322 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
4324 if (DEADMONSTER(mtmp))
4326 mndx = monsndx(mtmp->data);
4327 kill_cham = (mtmp->cham >= LOW_PM
4328 && (mvitals[mtmp->cham].mvflags & G_GENOD));
4329 if ((mvitals[mndx].mvflags & G_GENOD) || kill_cham) {
4330 if (mtmp->cham >= LOW_PM && !kill_cham)
4331 (void) newcham(mtmp, (struct permonst *) 0, FALSE, FALSE);
4336 kill_eggs(mtmp->minvent);
4341 kill_eggs(migrating_objs);
4342 kill_eggs(level.buriedobjlist);
4346 golemeffects(mon, damtype, dam)
4347 register struct monst *mon;
4350 int heal = 0, slow = 0;
4352 if (mon->data == &mons[PM_FLESH_GOLEM]) {
4353 if (damtype == AD_ELEC)
4354 heal = (dam + 5) / 6;
4355 else if (damtype == AD_FIRE || damtype == AD_COLD)
4357 } else if (mon->data == &mons[PM_IRON_GOLEM]) {
4358 if (damtype == AD_ELEC)
4360 else if (damtype == AD_FIRE)
4366 if (mon->mspeed != MSLOW)
4367 mon_adjust_speed(mon, -1, (struct obj *) 0);
4370 if (mon->mhp < mon->mhpmax) {
4372 if (mon->mhp > mon->mhpmax)
4373 mon->mhp = mon->mhpmax;
4374 if (cansee(mon->mx, mon->my))
4376 pline("%s seems healthier.", Monnam(mon));
4378 pline("%s
\82Í
\8c³
\8bC
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82é
\81D", Monnam(mon));
4384 angry_guards(silent)
4388 int ct = 0, nct = 0, sct = 0, slct = 0;
4390 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
4391 if (DEADMONSTER(mtmp))
4393 if (is_watch(mtmp->data) && mtmp->mpeaceful) {
4395 if (cansee(mtmp->mx, mtmp->my) && mtmp->mcanmove) {
4396 if (distu(mtmp->mx, mtmp->my) == 2)
4401 if (mtmp->msleeping || mtmp->mfrozen) {
4403 mtmp->msleeping = mtmp->mfrozen = 0;
4405 mtmp->mpeaceful = 0;
4409 if (!silent) { /* do we want pline msgs? */
4412 pline_The("guard%s wake%s up!", slct > 1 ? "s" : "",
4413 slct == 1 ? "s" : "");
4415 pline("
\94Ô
\95º
\82Í
\96Ú
\82ð
\8ao
\82Ü
\82µ
\82½
\81I");
4420 pline_The("guard%s get%s angry!", nct == 1 ? "" : "s",
4421 nct == 1 ? "s" : "");
4423 pline("
\94Ô
\95º
\82Í
\93{
\82Á
\82½
\81I");
4427 You_see("%sangry guard%s approaching!",
4428 sct == 1 ? "an " : "", sct > 1 ? "s" : "");
4430 You("
\93{
\82Á
\82½
\94Ô
\95º
\82ª
\8bß
\8añ
\82Á
\82Ä
\82
\82é
\82Ì
\82ð
\8c©
\82½
\81I");
4434 You_hear("the shrill sound of a guard's whistle.");
4436 You_hear("
\94Ô
\95º
\82Ì
\93J
\82ª
\82¯
\82½
\82½
\82Ü
\82µ
\82
\96Â
\82é
\82Ì
\82ð
\95·
\82¢
\82½
\81D");
4448 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
4449 if (DEADMONSTER(mtmp))
4451 if (is_watch(mtmp->data))
4452 mtmp->mpeaceful = 1;
4457 mimic_hit_msg(mtmp, otyp)
4461 short ap = mtmp->mappearance;
4463 switch (M_AP_TYPE(mtmp)) {
4465 case M_AP_FURNITURE:
4469 if (otyp == SPE_HEALING || otyp == SPE_EXTRA_HEALING) {
4471 pline("%s seems a more vivid %s than before.",
4472 The(simple_typename(ap)),
4473 c_obj_colors[objects[ap].oc_color]);
4475 pline("%s
\82Í
\88È
\91O
\82æ
\82è
\82æ
\82è
\91N
\82â
\82©
\82È%s
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82¾
\81D",
4476 The(simple_typename(ap)),
4477 c_obj_colors[objects[ap].oc_color]);
4486 struct permonst *mdat;
4489 boolean nonspecific = FALSE;
4490 boolean msg_given = FALSE;
4493 if (!olfaction(youmonst.data))
4495 mndx = monsndx(mdat);
4500 You("notice a bovine smell.");
4502 You("
\8b\8d\82Ì
\82æ
\82¤
\82È
\82É
\82¨
\82¢
\82É
\8bC
\95t
\82¢
\82½
\81D");
4508 case PM_NEANDERTHAL:
4510 You("smell body odor.");
4512 pline("
\91Ì
\8fL
\82Ì
\82æ
\82¤
\82È
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
4521 case PM_HORNED_DEVIL:
4528 case PM_HUMAN_WEREJACKAL:
4529 case PM_HUMAN_WERERAT:
4530 case PM_HUMAN_WEREWOLF:
4536 You("detect an odor reminiscent of an animal's den.");
4538 pline("
\93®
\95¨
\82Ì
\82Ë
\82®
\82ç
\82ð
\8ev
\82¢
\8fo
\82·
\82æ
\82¤
\82È
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
4542 case PM_PURPLE_WORM:
4545 case PM_STEAM_VORTEX:
4547 You("smell steam.");
4549 pline("
\8fö
\8bC
\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
4552 case PM_GREEN_SLIME:
4554 pline("%s stinks.", Something);
4556 pline("
\88«
\8fL
\82ª
\82µ
\82½
\81D");
4559 case PM_VIOLET_FUNGUS:
4562 You("smell mushrooms.");
4564 pline("
\82«
\82Ì
\82±
\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
4567 /* These are here to avoid triggering the
4568 nonspecific treatment through the default case below*/
4569 case PM_WHITE_UNICORN:
4570 case PM_GRAY_UNICORN:
4571 case PM_BLACK_UNICORN:
4580 switch (mdat->mlet) {
4583 You("notice a dog smell.");
4585 You("
\8c¢
\82Ì
\82É
\82¨
\82¢
\82É
\8bC
\95t
\82¢
\82½
\81D");
4590 You("smell a dragon!");
4592 pline("
\83h
\83\89\83S
\83\93\82Ì
\82É
\82¨
\82¢
\82ª
\82·
\82é
\81I");
4597 pline("%s smells moldy.", Something);
4599 pline("
\89½
\82©
\91Û
\82Ì
\82æ
\82¤
\82È
\82É
\82¨
\82¢
\82ª
\82·
\82é
\81D");
4604 You("detect a%s odor reminiscent of a stable.",
4605 (mndx == PM_PONY) ? "n" : " strong");
4607 pline("
\94n
\8f¬
\89®
\82ð
\8ev
\82¢
\8fo
\82·
\82æ
\82¤
\82È%s
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D",
4608 (mndx == PM_PONY) ? "" : "
\8b
\82¢");
4614 You("smell rotting flesh.");
4616 pline("
\95\85\82Á
\82½
\93÷
\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
4623 pline("
\8b\9b\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
4627 if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC)))
4629 You("notice an attractive smell.");
4631 You("
\96£
\97Í
\93I
\82È
\82É
\82¨
\82¢
\82É
\8bC
\95t
\82¢
\82½
\81D");
4634 pline("A foul stench makes you feel a little nauseated.");
4636 pline("
\82Þ
\82©
\82Â
\82
\82æ
\82¤
\82È
\88«
\8fL
\82Å
\8f
\82µ
\8bC
\95ª
\82ª
\88«
\82
\82È
\82Á
\82½
\81D");
4643 return msg_given ? TRUE : FALSE;