OSDN Git Service

add gitignore
[nethackexpress/trunk.git] / src / mon.c
1 /*      SCCS Id: @(#)mon.c      3.4     2003/12/04      */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /* If you're using precompiled headers, you don't want this either */
6 #ifdef MICROPORT_BUG
7 #define MKROOM_H
8 #endif
9
10 #include "hack.h"
11 #include "mfndpos.h"
12 #include "edog.h"
13 #include <ctype.h>
14
15 STATIC_DCL boolean FDECL(restrap,(struct monst *));
16 STATIC_DCL long FDECL(mm_aggression, (struct monst *,struct monst *));
17 #ifdef OVL2
18 STATIC_DCL int NDECL(pick_animal);
19 STATIC_DCL int FDECL(select_newcham_form, (struct monst *));
20 STATIC_DCL void FDECL(kill_eggs, (struct obj *));
21 #endif
22
23 #ifdef REINCARNATION
24 #define LEVEL_SPECIFIC_NOCORPSE(mdat) \
25          (Is_rogue_level(&u.uz) || \
26            (level.flags.graveyard && is_undead(mdat) && rn2(3)))
27 #else
28 #define LEVEL_SPECIFIC_NOCORPSE(mdat) \
29            (level.flags.graveyard && is_undead(mdat) && rn2(3))
30 #endif
31
32
33 #if 0
34 /* part of the original warning code which was replaced in 3.3.1 */
35 #ifdef OVL1
36 #define warnDelay 10
37 long lastwarntime;
38 int lastwarnlev;
39
40 const char *warnings[] = {
41         "white", "pink", "red", "ruby", "purple", "black"
42 };
43
44 STATIC_DCL void NDECL(warn_effects);
45 #endif /* OVL1 */
46 #endif /* 0 */
47
48 #ifndef OVLB
49 STATIC_VAR short cham_to_pm[];
50 #else
51 STATIC_DCL struct obj *FDECL(make_corpse,(struct monst *));
52 STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *));
53 STATIC_DCL void FDECL(lifesaved_monster, (struct monst *));
54
55 /* convert the monster index of an undead to its living counterpart */
56 int
57 undead_to_corpse(mndx)
58 int mndx;
59 {
60         switch (mndx) {
61         case PM_KOBOLD_ZOMBIE:
62         case PM_KOBOLD_MUMMY:   mndx = PM_KOBOLD;  break;
63         case PM_DWARF_ZOMBIE:
64         case PM_DWARF_MUMMY:    mndx = PM_DWARF;  break;
65         case PM_GNOME_ZOMBIE:
66         case PM_GNOME_MUMMY:    mndx = PM_GNOME;  break;
67         case PM_ORC_ZOMBIE:
68         case PM_ORC_MUMMY:      mndx = PM_ORC;  break;
69         case PM_ELF_ZOMBIE:
70         case PM_ELF_MUMMY:      mndx = PM_ELF;  break;
71         case PM_VAMPIRE:
72         case PM_VAMPIRE_LORD:
73 #if 0   /* DEFERRED */
74         case PM_VAMPIRE_MAGE:
75 #endif
76         case PM_HUMAN_ZOMBIE:
77         case PM_HUMAN_MUMMY:    mndx = PM_HUMAN;  break;
78         case PM_GIANT_ZOMBIE:
79         case PM_GIANT_MUMMY:    mndx = PM_GIANT;  break;
80         case PM_ETTIN_ZOMBIE:
81         case PM_ETTIN_MUMMY:    mndx = PM_ETTIN;  break;
82         default:  break;
83         }
84         return mndx;
85 }
86
87 /* Convert the monster index of some monsters (such as quest guardians)
88  * to their generic species type.
89  *
90  * Return associated character class monster, rather than species
91  * if mode is 1.
92  */
93 int
94 genus(mndx, mode)
95 int mndx, mode;
96 {
97         switch (mndx) {
98 /* Quest guardians */
99         case PM_STUDENT:     mndx = mode ? PM_ARCHEOLOGIST  : PM_HUMAN; break;
100         case PM_CHIEFTAIN:   mndx = mode ? PM_BARBARIAN : PM_HUMAN; break;
101         case PM_NEANDERTHAL: mndx = mode ? PM_CAVEMAN   : PM_HUMAN; break;
102         case PM_ATTENDANT:   mndx = mode ? PM_HEALER    : PM_HUMAN; break;
103         case PM_PAGE:        mndx = mode ? PM_KNIGHT    : PM_HUMAN; break;
104         case PM_ABBOT:       mndx = mode ? PM_MONK      : PM_HUMAN; break;
105         case PM_ACOLYTE:     mndx = mode ? PM_PRIEST    : PM_HUMAN; break;
106         case PM_HUNTER:      mndx = mode ? PM_RANGER    : PM_HUMAN; break;
107         case PM_THUG:        mndx = mode ? PM_ROGUE     : PM_HUMAN; break;
108         case PM_ROSHI:       mndx = mode ? PM_SAMURAI   : PM_HUMAN; break;
109 #ifdef TOURIST
110         case PM_GUIDE:       mndx = mode ? PM_TOURIST   : PM_HUMAN; break;
111 #endif
112         case PM_APPRENTICE:  mndx = mode ? PM_WIZARD    : PM_HUMAN; break;
113         case PM_WARRIOR:     mndx = mode ? PM_VALKYRIE  : PM_HUMAN; break;
114         default:
115                 if (mndx >= LOW_PM && mndx < NUMMONS) {
116                         struct permonst *ptr = &mons[mndx];
117                         if (is_human(ptr))      mndx = PM_HUMAN;
118                         else if (is_elf(ptr))   mndx = PM_ELF;
119                         else if (is_dwarf(ptr)) mndx = PM_DWARF;
120                         else if (is_gnome(ptr)) mndx = PM_GNOME;
121                         else if (is_orc(ptr))   mndx = PM_ORC;
122                 }
123                 break;
124         }
125         return mndx;
126 }
127
128 /* convert monster index to chameleon index */
129 int
130 pm_to_cham(mndx)
131 int mndx;
132 {
133         int mcham;
134
135         switch (mndx) {
136         case PM_CHAMELEON:      mcham = CHAM_CHAMELEON; break;
137         case PM_DOPPELGANGER:   mcham = CHAM_DOPPELGANGER; break;
138         case PM_SANDESTIN:      mcham = CHAM_SANDESTIN; break;
139         default: mcham = CHAM_ORDINARY; break;
140         }
141         return mcham;
142 }
143
144 /* convert chameleon index to monster index */
145 STATIC_VAR short cham_to_pm[] = {
146                 NON_PM,         /* placeholder for CHAM_ORDINARY */
147                 PM_CHAMELEON,
148                 PM_DOPPELGANGER,
149                 PM_SANDESTIN,
150 };
151
152 /* for deciding whether corpse or statue will carry along full monster data */
153 #define KEEPTRAITS(mon) ((mon)->isshk || (mon)->mtame ||                \
154                          ((mon)->data->geno & G_UNIQ) ||                \
155                          is_reviver((mon)->data) ||                     \
156                          /* normally leader the will be unique, */      \
157                          /* but he might have been polymorphed  */      \
158                          (mon)->m_id == quest_status.leader_m_id ||     \
159                          /* special cancellation handling for these */  \
160                          (dmgtype((mon)->data, AD_SEDU) ||              \
161                           dmgtype((mon)->data, AD_SSEX)))
162
163 /* Creates a monster corpse, a "special" corpse, or nothing if it doesn't
164  * leave corpses.  Monsters which leave "special" corpses should have
165  * G_NOCORPSE set in order to prevent wishing for one, finding tins of one,
166  * etc....
167  */
168 STATIC_OVL struct obj *
169 make_corpse(mtmp)
170 register struct monst *mtmp;
171 {
172         register struct permonst *mdat = mtmp->data;
173         int num;
174         struct obj *obj = (struct obj *)0;
175         int x = mtmp->mx, y = mtmp->my;
176         int mndx = monsndx(mdat);
177
178         switch(mndx) {
179             case PM_GRAY_DRAGON:
180             case PM_SILVER_DRAGON:
181 #if 0   /* DEFERRED */
182             case PM_SHIMMERING_DRAGON:
183 #endif
184             case PM_RED_DRAGON:
185             case PM_ORANGE_DRAGON:
186             case PM_WHITE_DRAGON:
187             case PM_BLACK_DRAGON:
188             case PM_BLUE_DRAGON:
189             case PM_GREEN_DRAGON:
190             case PM_YELLOW_DRAGON:
191                 /* Make dragon scales.  This assumes that the order of the */
192                 /* dragons is the same as the order of the scales.         */
193                 if (!rn2(mtmp->mrevived ? 20 : 3)) {
194                     num = GRAY_DRAGON_SCALES + monsndx(mdat) - PM_GRAY_DRAGON;
195                     obj = mksobj_at(num, x, y, FALSE, FALSE);
196                     obj->spe = 0;
197                     obj->cursed = obj->blessed = FALSE;
198                 }
199                 goto default_1;
200
201             case PM_WHITE_UNICORN:
202             case PM_GRAY_UNICORN:
203             case PM_BLACK_UNICORN:
204                 if (mtmp->mrevived && rn2(20)) {
205                         if (canseemon(mtmp))
206                            pline("%s recently regrown horn crumbles to dust.",
207                                 s_suffix(Monnam(mtmp)));
208                 } else
209                         (void) mksobj_at(UNICORN_HORN, x, y, TRUE, FALSE);
210                 goto default_1;
211             case PM_LONG_WORM:
212                 (void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE);
213                 goto default_1;
214             case PM_VAMPIRE:
215             case PM_VAMPIRE_LORD:
216                 /* include mtmp in the mkcorpstat() call */
217                 num = undead_to_corpse(mndx);
218                 obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, TRUE);
219                 obj->age -= 100;                /* this is an *OLD* corpse */
220                 break;
221             case PM_KOBOLD_MUMMY:
222             case PM_DWARF_MUMMY:
223             case PM_GNOME_MUMMY:
224             case PM_ORC_MUMMY:
225             case PM_ELF_MUMMY:
226             case PM_HUMAN_MUMMY:
227             case PM_GIANT_MUMMY:
228             case PM_ETTIN_MUMMY:
229             case PM_KOBOLD_ZOMBIE:
230             case PM_DWARF_ZOMBIE:
231             case PM_GNOME_ZOMBIE:
232             case PM_ORC_ZOMBIE:
233             case PM_ELF_ZOMBIE:
234             case PM_HUMAN_ZOMBIE:
235             case PM_GIANT_ZOMBIE:
236             case PM_ETTIN_ZOMBIE:
237                 num = undead_to_corpse(mndx);
238                 obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, TRUE);
239                 obj->age -= 100;                /* this is an *OLD* corpse */
240                 break;
241             case PM_IRON_GOLEM:
242                 num = d(2,6);
243                 while (num--)
244                         obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE);
245                 mtmp->mnamelth = 0;
246                 break;
247             case PM_GLASS_GOLEM:
248                 num = d(2,4);   /* very low chance of creating all glass gems */
249                 while (num--)
250                         obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE);
251                 mtmp->mnamelth = 0;
252                 break;
253             case PM_CLAY_GOLEM:
254                 obj = mksobj_at(ROCK, x, y, FALSE, FALSE);
255                 obj->quan = (long)(rn2(20) + 50);
256                 obj->owt = weight(obj);
257                 mtmp->mnamelth = 0;
258                 break;
259             case PM_STONE_GOLEM:
260                 obj = mkcorpstat(STATUE, (struct monst *)0,
261                         mdat, x, y, FALSE);
262                 break;
263             case PM_WOOD_GOLEM:
264                 num = d(2,4);
265                 while(num--) {
266                         obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE);
267                 }
268                 mtmp->mnamelth = 0;
269                 break;
270             case PM_LEATHER_GOLEM:
271                 num = d(2,4);
272                 while(num--)
273                         obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE);
274                 mtmp->mnamelth = 0;
275                 break;
276             case PM_GOLD_GOLEM:
277                 /* Good luck gives more coins */
278                 obj = mkgold((long)(200 - rnl(101)), x, y);
279                 mtmp->mnamelth = 0;
280                 break;
281             case PM_PAPER_GOLEM:
282                 num = rnd(4);
283                 while (num--)
284                         obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE);
285                 mtmp->mnamelth = 0;
286                 break;
287             default_1:
288             default:
289                 if (mvitals[mndx].mvflags & G_NOCORPSE)
290                     return (struct obj *)0;
291                 else    /* preserve the unique traits of some creatures */
292                     obj = mkcorpstat(CORPSE, KEEPTRAITS(mtmp) ? mtmp : 0,
293                                      mdat, x, y, TRUE);
294                 break;
295         }
296         /* All special cases should precede the G_NOCORPSE check */
297
298         /* if polymorph or undead turning has killed this monster,
299            prevent the same attack beam from hitting its corpse */
300         if (flags.bypasses) bypass_obj(obj);
301
302         if (mtmp->mnamelth)
303             obj = oname(obj, NAME(mtmp));
304
305         /* Avoid "It was hidden under a green mold corpse!" 
306          *  during Blind combat. An unseen monster referred to as "it"
307          *  could be killed and leave a corpse.  If a hider then hid
308          *  underneath it, you could be told the corpse type of a
309          *  monster that you never knew was there without this.
310          *  The code in hitmu() substitutes the word "something"
311          *  if the corpses obj->dknown is 0.
312          */
313         if (Blind && !sensemon(mtmp)) obj->dknown = 0;
314
315 #ifdef INVISIBLE_OBJECTS
316         /* Invisible monster ==> invisible corpse */
317         obj->oinvis = mtmp->minvis;
318 #endif
319
320         stackobj(obj);
321         newsym(x, y);
322         return obj;
323 }
324
325 #endif /* OVLB */
326 #ifdef OVL1
327
328 #if 0
329 /* part of the original warning code which was replaced in 3.3.1 */
330 STATIC_OVL void
331 warn_effects()
332 {
333     if (warnlevel == 100) {
334         if(!Blind && uwep &&
335             (warnlevel > lastwarnlev || moves > lastwarntime + warnDelay)) {
336             Your("%s %s!", aobjnam(uwep, "glow"),
337                 hcolor(NH_LIGHT_BLUE));
338             lastwarnlev = warnlevel;
339             lastwarntime = moves;
340         }
341         warnlevel = 0;
342         return;
343     }
344
345     if (warnlevel >= SIZE(warnings))
346         warnlevel = SIZE(warnings)-1;
347     if (!Blind &&
348             (warnlevel > lastwarnlev || moves > lastwarntime + warnDelay)) {
349         const char *which, *what, *how;
350         long rings = (EWarning & (LEFT_RING|RIGHT_RING));
351
352         if (rings) {
353             what = Hallucination ? "mood ring" : "ring";
354             how = "glows";      /* singular verb */
355             if (rings == LEFT_RING) {
356                 which = "left ";
357             } else if (rings == RIGHT_RING) {
358                 which = "right ";
359             } else {            /* both */
360                 which = "";
361                 what = (const char *) makeplural(what);
362                 how = "glow";   /* plural verb */
363             }
364             Your("%s%s %s %s!", which, what, how, hcolor(warnings[warnlevel]));
365         } else {
366             if (Hallucination)
367                 Your("spider-sense is tingling...");
368             else
369                 You_feel("apprehensive as you sense a %s flash.",
370                     warnings[warnlevel]);
371         }
372
373         lastwarntime = moves;
374         lastwarnlev = warnlevel;
375     }
376 }
377 #endif /* 0 */
378
379 /* check mtmp and water/lava for compatibility, 0 (survived), 1 (died) */
380 int
381 minliquid(mtmp)
382 register struct monst *mtmp;
383 {
384     boolean inpool, inlava, infountain;
385
386     inpool = is_pool(mtmp->mx,mtmp->my) &&
387              !is_flyer(mtmp->data) && !is_floater(mtmp->data);
388     inlava = is_lava(mtmp->mx,mtmp->my) &&
389              !is_flyer(mtmp->data) && !is_floater(mtmp->data);
390     infountain = IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ);
391
392 #ifdef STEED
393         /* Flying and levitation keeps our steed out of the liquid */
394         /* (but not water-walking or swimming) */
395         if (mtmp == u.usteed && (Flying || Levitation))
396                 return (0);
397 #endif
398
399     /* Gremlin multiplying won't go on forever since the hit points
400      * keep going down, and when it gets to 1 hit point the clone
401      * function will fail.
402      */
403     if (mtmp->data == &mons[PM_GREMLIN] && (inpool || infountain) && rn2(3)) {
404         if (split_mon(mtmp, (struct monst *)0))
405             dryup(mtmp->mx, mtmp->my, FALSE);
406         if (inpool) water_damage(mtmp->minvent, FALSE, FALSE);
407         return (0);
408     } else if (mtmp->data == &mons[PM_IRON_GOLEM] && inpool && !rn2(5)) {
409         int dam = d(2,6);
410         if (cansee(mtmp->mx,mtmp->my))
411             pline("%s rusts.", Monnam(mtmp));
412         mtmp->mhp -= dam;
413         if (mtmp->mhpmax > dam) mtmp->mhpmax -= dam;
414         if (mtmp->mhp < 1) {
415             mondead(mtmp);
416             if (mtmp->mhp < 1) return (1);
417         }
418         water_damage(mtmp->minvent, FALSE, FALSE);
419         return (0);
420     }
421
422     if (inlava) {
423         /*
424          * Lava effects much as water effects. Lava likers are able to
425          * protect their stuff. Fire resistant monsters can only protect
426          * themselves  --ALI
427          */
428         if (!is_clinger(mtmp->data) && !likes_lava(mtmp->data)) {
429             if (!resists_fire(mtmp)) {
430                 if (cansee(mtmp->mx,mtmp->my))
431                     pline("%s %s.", Monnam(mtmp),
432                           mtmp->data == &mons[PM_WATER_ELEMENTAL] ?
433                           "boils away" : "burns to a crisp");
434                 mondead(mtmp);
435             }
436             else {
437                 if (--mtmp->mhp < 1) {
438                     if (cansee(mtmp->mx,mtmp->my))
439                         pline("%s surrenders to the fire.", Monnam(mtmp));
440                     mondead(mtmp);
441                 }
442                 else if (cansee(mtmp->mx,mtmp->my))
443                     pline("%s burns slightly.", Monnam(mtmp));
444             }
445             if (mtmp->mhp > 0) {
446                 (void) fire_damage(mtmp->minvent, FALSE, FALSE,
447                                                 mtmp->mx, mtmp->my);
448                 (void) rloc(mtmp, FALSE);
449                 return 0;
450             }
451             return (1);
452         }
453     } else if (inpool) {
454         /* Most monsters drown in pools.  flooreffects() will take care of
455          * water damage to dead monsters' inventory, but survivors need to
456          * be handled here.  Swimmers are able to protect their stuff...
457          */
458         if (!is_clinger(mtmp->data)
459             && !is_swimmer(mtmp->data) && !amphibious(mtmp->data)) {
460             if (cansee(mtmp->mx,mtmp->my)) {
461                     pline("%s drowns.", Monnam(mtmp));
462             }
463             if (u.ustuck && u.uswallow && u.ustuck == mtmp) {
464             /* This can happen after a purple worm plucks you off a
465                 flying steed while you are over water. */
466                 pline("%s sinks as water rushes in and flushes you out.",
467                         Monnam(mtmp));
468             }
469             mondead(mtmp);
470             if (mtmp->mhp > 0) {
471                 (void) rloc(mtmp, FALSE);
472                 water_damage(mtmp->minvent, FALSE, FALSE);
473                 return 0;
474             }
475             return (1);
476         }
477     } else {
478         /* but eels have a difficult time outside */
479         if (mtmp->data->mlet == S_EEL && !Is_waterlevel(&u.uz)) {
480             if(mtmp->mhp > 1) mtmp->mhp--;
481             monflee(mtmp, 2, FALSE, FALSE);
482         }
483     }
484     return (0);
485 }
486
487
488 int
489 mcalcmove(mon)
490 struct monst *mon;
491 {
492     int mmove = mon->data->mmove;
493
494     /* Note: MSLOW's `+ 1' prevents slowed speed 1 getting reduced to 0;
495      *       MFAST's `+ 2' prevents hasted speed 1 from becoming a no-op;
496      *       both adjustments have negligible effect on higher speeds.
497      */
498     if (mon->mspeed == MSLOW)
499         mmove = (2 * mmove + 1) / 3;
500     else if (mon->mspeed == MFAST)
501         mmove = (4 * mmove + 2) / 3;
502
503 #ifdef STEED
504     if (mon == u.usteed) {
505         if (u.ugallop && flags.mv) {
506             /* average movement is 1.50 times normal */
507             mmove = ((rn2(2) ? 4 : 5) * mmove) / 3;
508         }
509     }
510 #endif
511
512     return mmove;
513 }
514
515 /* actions that happen once per ``turn'', regardless of each
516    individual monster's metabolism; some of these might need to
517    be reclassified to occur more in proportion with movement rate */
518 void
519 mcalcdistress()
520 {
521     struct monst *mtmp;
522
523     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
524         if (DEADMONSTER(mtmp)) continue;
525
526         /* must check non-moving monsters once/turn in case
527          * they managed to end up in liquid */
528         if (mtmp->data->mmove == 0) {
529             if (vision_full_recalc) vision_recalc(0);
530             if (minliquid(mtmp)) continue;
531         }
532
533         /* regenerate hit points */
534         mon_regen(mtmp, FALSE);
535
536         /* possibly polymorph shapechangers and lycanthropes */
537         if (mtmp->cham && !rn2(6))
538             (void) newcham(mtmp, (struct permonst *)0, FALSE, FALSE);
539         were_change(mtmp);
540
541         /* gradually time out temporary problems */
542         if (mtmp->mblinded && !--mtmp->mblinded)
543             mtmp->mcansee = 1;
544         if (mtmp->mfrozen && !--mtmp->mfrozen)
545             mtmp->mcanmove = 1;
546         if (mtmp->mfleetim && !--mtmp->mfleetim)
547             mtmp->mflee = 0;
548
549         /* FIXME: mtmp->mlstmv ought to be updated here */
550     }
551 }
552
553 int
554 movemon()
555 {
556     register struct monst *mtmp, *nmtmp;
557     register boolean somebody_can_move = FALSE;
558 #if 0
559     /* part of the original warning code which was replaced in 3.3.1 */
560     warnlevel = 0;
561 #endif
562
563     /*
564     Some of you may remember the former assertion here that
565     because of deaths and other actions, a simple one-pass
566     algorithm wasn't possible for movemon.  Deaths are no longer
567     removed to the separate list fdmon; they are simply left in
568     the chain with hit points <= 0, to be cleaned up at the end
569     of the pass.
570
571     The only other actions which cause monsters to be removed from
572     the chain are level migrations and losedogs().  I believe losedogs()
573     is a cleanup routine not associated with monster movements, and
574     monsters can only affect level migrations on themselves, not others
575     (hence the fetching of nmon before moving the monster).  Currently,
576     monsters can jump into traps, read cursed scrolls of teleportation,
577     and drink cursed potions of raise level to change levels.  These are
578     all reflexive at this point.  Should one monster be able to level
579     teleport another, this scheme would have problems.
580     */
581
582     for(mtmp = fmon; mtmp; mtmp = nmtmp) {
583         nmtmp = mtmp->nmon;
584
585         /* Find a monster that we have not treated yet.  */
586         if(DEADMONSTER(mtmp))
587             continue;
588         if(mtmp->movement < NORMAL_SPEED)
589             continue;
590
591         mtmp->movement -= NORMAL_SPEED;
592         if (mtmp->movement >= NORMAL_SPEED)
593             somebody_can_move = TRUE;
594
595         if (vision_full_recalc) vision_recalc(0);       /* vision! */
596
597         if (minliquid(mtmp)) continue;
598
599         if (is_hider(mtmp->data)) {
600             /* unwatched mimics and piercers may hide again  [MRS] */
601             if(restrap(mtmp))   continue;
602             if(mtmp->m_ap_type == M_AP_FURNITURE ||
603                                 mtmp->m_ap_type == M_AP_OBJECT)
604                     continue;
605             if(mtmp->mundetected) continue;
606         }
607
608         /* continue if the monster died fighting */
609         if (Conflict && !mtmp->iswiz && mtmp->mcansee) {
610             /* Note:
611              *  Conflict does not take effect in the first round.
612              *  Therefore, A monster when stepping into the area will
613              *  get to swing at you.
614              *
615              *  The call to fightm() must be _last_.  The monster might
616              *  have died if it returns 1.
617              */
618             if (couldsee(mtmp->mx,mtmp->my) &&
619                 (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) &&
620                                                         fightm(mtmp))
621                 continue;       /* mon might have died */
622         }
623         if(dochugw(mtmp))               /* otherwise just move the monster */
624             continue;
625     }
626 #if 0
627     /* part of the original warning code which was replaced in 3.3.1 */
628     if(warnlevel > 0)
629         warn_effects();
630 #endif
631
632     if (any_light_source())
633         vision_full_recalc = 1; /* in case a mon moved with a light source */
634     dmonsfree();        /* remove all dead monsters */
635
636     /* a monster may have levteleported player -dlc */
637     if (u.utotype) {
638         deferred_goto();
639         /* changed levels, so these monsters are dormant */
640         somebody_can_move = FALSE;
641     }
642
643     return somebody_can_move;
644 }
645
646 #endif /* OVL1 */
647 #ifdef OVLB
648
649 #define mstoning(obj)   (ofood(obj) && \
650                                         (touch_petrifies(&mons[(obj)->corpsenm]) || \
651                                         (obj)->corpsenm == PM_MEDUSA))
652
653 /*
654  * Maybe eat a metallic object (not just gold).
655  * Return value: 0 => nothing happened, 1 => monster ate something,
656  * 2 => monster died (it must have grown into a genocided form, but
657  * that can't happen at present because nothing which eats objects
658  * has young and old forms).
659  */
660 int
661 meatmetal(mtmp)
662         register struct monst *mtmp;
663 {
664         register struct obj *otmp;
665         struct permonst *ptr;
666         int poly, grow, heal, mstone;
667
668         /* If a pet, eating is handled separately, in dog.c */
669         if (mtmp->mtame) return 0;
670
671         /* Eats topmost metal object if it is there */
672         for (otmp = level.objects[mtmp->mx][mtmp->my];
673                                                 otmp; otmp = otmp->nexthere) {
674             if (mtmp->data == &mons[PM_RUST_MONSTER] && !is_rustprone(otmp))
675                 continue;
676             if (is_metallic(otmp) && !obj_resists(otmp, 5, 95) &&
677                 touch_artifact(otmp,mtmp)) {
678                 if (mtmp->data == &mons[PM_RUST_MONSTER] && otmp->oerodeproof) {
679                     if (canseemon(mtmp) && flags.verbose) {
680                         pline("%s eats %s!",
681                                 Monnam(mtmp),
682                                 distant_name(otmp,doname));
683                     }
684                     /* The object's rustproofing is gone now */
685                     otmp->oerodeproof = 0;
686                     mtmp->mstun = 1;
687                     if (canseemon(mtmp) && flags.verbose) {
688                         pline("%s spits %s out in disgust!",
689                               Monnam(mtmp), distant_name(otmp,doname));
690                     }
691                 /* KMH -- Don't eat indigestible/choking objects */
692                 } else if (otmp->otyp != AMULET_OF_STRANGULATION &&
693                                 otmp->otyp != RIN_SLOW_DIGESTION) {
694                     if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
695                         pline("%s eats %s!", Monnam(mtmp),
696                                 distant_name(otmp,doname));
697                     else if (flags.soundok && flags.verbose)
698                         You_hear("a crunching sound.");
699                     mtmp->meating = otmp->owt/2 + 1;
700                     /* Heal up to the object's weight in hp */
701                     if (mtmp->mhp < mtmp->mhpmax) {
702                         mtmp->mhp += objects[otmp->otyp].oc_weight;
703                         if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
704                     }
705                     if(otmp == uball) {
706                         unpunish();
707                         delobj(otmp);
708                     } else if (otmp == uchain) {
709                         unpunish();     /* frees uchain */
710                     } else {
711                         poly = polyfodder(otmp);
712                         grow = mlevelgain(otmp);
713                         heal = mhealup(otmp);
714                         mstone = mstoning(otmp);
715                         delobj(otmp);
716                         ptr = mtmp->data;
717                         if (poly) {
718                             if (newcham(mtmp, (struct permonst *)0,
719                                         FALSE, FALSE))
720                                 ptr = mtmp->data;
721                         } else if (grow) {
722                             ptr = grow_up(mtmp, (struct monst *)0);
723                         } else if (mstone) {
724                             if (poly_when_stoned(ptr)) {
725                                 mon_to_stone(mtmp);
726                                 ptr = mtmp->data;
727                             } else if (!resists_ston(mtmp)) {
728                                 if (canseemon(mtmp))
729                                     pline("%s turns to stone!", Monnam(mtmp));
730                                 monstone(mtmp);
731                                 ptr = (struct permonst *)0;
732                             }
733                         } else if (heal) {
734                             mtmp->mhp = mtmp->mhpmax;
735                         }
736                         if (!ptr) return 2;              /* it died */
737                     }
738                     /* Left behind a pile? */
739                     if (rnd(25) < 3)
740                         (void)mksobj_at(ROCK, mtmp->mx, mtmp->my, TRUE, FALSE);
741                     newsym(mtmp->mx, mtmp->my);
742                     return 1;
743                 }
744             }
745         }
746         return 0;
747 }
748
749 int
750 meatobj(mtmp)           /* for gelatinous cubes */
751         register struct monst *mtmp;
752 {
753         register struct obj *otmp, *otmp2;
754         struct permonst *ptr;
755         int poly, grow, heal, count = 0, ecount = 0;
756         char buf[BUFSZ];
757
758         buf[0] = '\0';
759         /* If a pet, eating is handled separately, in dog.c */
760         if (mtmp->mtame) return 0;
761
762         /* Eats organic objects, including cloth and wood, if there */
763         /* Engulfs others, except huge rocks and metal attached to player */
764         for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
765             otmp2 = otmp->nexthere;
766             if (is_organic(otmp) && !obj_resists(otmp, 5, 95) &&
767                     touch_artifact(otmp,mtmp)) {
768                 if (otmp->otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) &&
769                         !resists_ston(mtmp))
770                     continue;
771                 if (otmp->otyp == AMULET_OF_STRANGULATION ||
772                                 otmp->otyp == RIN_SLOW_DIGESTION)
773                     continue;
774                 ++count;
775                 if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
776                     pline("%s eats %s!", Monnam(mtmp),
777                             distant_name(otmp, doname));
778                 else if (flags.soundok && flags.verbose)
779                     You_hear("a slurping sound.");
780                 /* Heal up to the object's weight in hp */
781                 if (mtmp->mhp < mtmp->mhpmax) {
782                     mtmp->mhp += objects[otmp->otyp].oc_weight;
783                     if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
784                 }
785                 if (Has_contents(otmp)) {
786                     register struct obj *otmp3;
787                     /* contents of eaten containers become engulfed; this
788                        is arbitrary, but otherwise g.cubes are too powerful */
789                     while ((otmp3 = otmp->cobj) != 0) {
790                         obj_extract_self(otmp3);
791                         if (otmp->otyp == ICE_BOX && otmp3->otyp == CORPSE) {
792                             otmp3->age = monstermoves - otmp3->age;
793                             start_corpse_timeout(otmp3);
794                         }
795                         (void) mpickobj(mtmp, otmp3);
796                     }
797                 }
798                 poly = polyfodder(otmp);
799                 grow = mlevelgain(otmp);
800                 heal = mhealup(otmp);
801                 delobj(otmp);           /* munch */
802                 ptr = mtmp->data;
803                 if (poly) {
804                     if (newcham(mtmp, (struct permonst *)0, FALSE, FALSE))
805                         ptr = mtmp->data;
806                 } else if (grow) {
807                     ptr = grow_up(mtmp, (struct monst *)0);
808                 } else if (heal) {
809                     mtmp->mhp = mtmp->mhpmax;
810                 }
811                 /* in case it polymorphed or died */
812                 if (ptr != &mons[PM_GELATINOUS_CUBE])
813                     return !ptr ? 2 : 1;
814             } else if (otmp->oclass != ROCK_CLASS &&
815                                     otmp != uball && otmp != uchain) {
816                 ++ecount;
817                 if (ecount == 1) {
818                         Sprintf(buf, "%s engulfs %s.", Monnam(mtmp),
819                             distant_name(otmp,doname));
820                 } else if (ecount == 2)
821                         Sprintf(buf, "%s engulfs several objects.", Monnam(mtmp));
822                 obj_extract_self(otmp);
823                 (void) mpickobj(mtmp, otmp);    /* slurp */
824             }
825             /* Engulf & devour is instant, so don't set meating */
826             if (mtmp->minvis) newsym(mtmp->mx, mtmp->my);
827         }
828         if (ecount > 0) {
829             if (cansee(mtmp->mx, mtmp->my) && flags.verbose && buf[0])
830                 pline("%s", buf);
831             else if (flags.soundok && flags.verbose)
832                 You_hear("%s slurping sound%s.",
833                         ecount == 1 ? "a" : "several",
834                         ecount == 1 ? "" : "s");
835         }
836         return ((count > 0) || (ecount > 0)) ? 1 : 0;
837 }
838
839 void
840 mpickgold(mtmp)
841         register struct monst *mtmp;
842 {
843     register struct obj *gold;
844     int mat_idx;
845
846     if ((gold = g_at(mtmp->mx, mtmp->my)) != 0) {
847         mat_idx = objects[gold->otyp].oc_material;
848 #ifndef GOLDOBJ
849         mtmp->mgold += gold->quan;
850         delobj(gold);
851 #else
852         obj_extract_self(gold);
853         add_to_minv(mtmp, gold);
854 #endif
855         if (cansee(mtmp->mx, mtmp->my) ) {
856             if (flags.verbose && !mtmp->isgd)
857                 pline("%s picks up some %s.", Monnam(mtmp),
858                         mat_idx == GOLD ? "gold" : "money");
859             newsym(mtmp->mx, mtmp->my);
860         }
861     }
862 }
863 #endif /* OVLB */
864 #ifdef OVL2
865
866 boolean
867 mpickstuff(mtmp, str)
868         register struct monst *mtmp;
869         register const char *str;
870 {
871         register struct obj *otmp, *otmp2;
872
873 /*      prevent shopkeepers from leaving the door of their shop */
874         if(mtmp->isshk && inhishop(mtmp)) return FALSE;
875
876         for(otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
877             otmp2 = otmp->nexthere;
878 /*      Nymphs take everything.  Most monsters don't pick up corpses. */
879             if (!str ? searches_for_item(mtmp,otmp) :
880                   !!(index(str, otmp->oclass))) {
881                 if (otmp->otyp == CORPSE && mtmp->data->mlet != S_NYMPH &&
882                         /* let a handful of corpse types thru to can_carry() */
883                         !touch_petrifies(&mons[otmp->corpsenm]) &&
884                         otmp->corpsenm != PM_LIZARD &&
885                         !acidic(&mons[otmp->corpsenm])) continue;
886                 if (!touch_artifact(otmp,mtmp)) continue;
887                 if (!can_carry(mtmp,otmp)) continue;
888                 if (is_pool(mtmp->mx,mtmp->my)) continue;
889 #ifdef INVISIBLE_OBJECTS
890                 if (otmp->oinvis && !perceives(mtmp->data)) continue;
891 #endif
892                 if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
893                         pline("%s picks up %s.", Monnam(mtmp),
894                               (distu(mtmp->mx, mtmp->my) <= 5) ?
895                                 doname(otmp) : distant_name(otmp, doname));
896                 obj_extract_self(otmp);
897                 /* unblock point after extract, before pickup */
898                 if (otmp->otyp == BOULDER)
899                     unblock_point(otmp->ox,otmp->oy);   /* vision */
900                 (void) mpickobj(mtmp, otmp);    /* may merge and free otmp */
901                 m_dowear(mtmp, FALSE);
902                 newsym(mtmp->mx, mtmp->my);
903                 return TRUE;                    /* pick only one object */
904             }
905         }
906         return FALSE;
907 }
908
909 #endif /* OVL2 */
910 #ifdef OVL0
911
912 int
913 curr_mon_load(mtmp)
914 register struct monst *mtmp;
915 {
916         register int curload = 0;
917         register struct obj *obj;
918
919         for(obj = mtmp->minvent; obj; obj = obj->nobj) {
920                 if(obj->otyp != BOULDER || !throws_rocks(mtmp->data))
921                         curload += obj->owt;
922         }
923
924         return curload;
925 }
926
927 int
928 max_mon_load(mtmp)
929 register struct monst *mtmp;
930 {
931         register long maxload;
932
933         /* Base monster carrying capacity is equal to human maximum
934          * carrying capacity, or half human maximum if not strong.
935          * (for a polymorphed player, the value used would be the
936          * non-polymorphed carrying capacity instead of max/half max).
937          * This is then modified by the ratio between the monster weights
938          * and human weights.  Corpseless monsters are given a capacity
939          * proportional to their size instead of weight.
940          */
941         if (!mtmp->data->cwt)
942                 maxload = (MAX_CARR_CAP * (long)mtmp->data->msize) / MZ_HUMAN;
943         else if (!strongmonst(mtmp->data)
944                 || (strongmonst(mtmp->data) && (mtmp->data->cwt > WT_HUMAN)))
945                 maxload = (MAX_CARR_CAP * (long)mtmp->data->cwt) / WT_HUMAN;
946         else    maxload = MAX_CARR_CAP; /*strong monsters w/cwt <= WT_HUMAN*/
947
948         if (!strongmonst(mtmp->data)) maxload /= 2;
949
950         if (maxload < 1) maxload = 1;
951
952         return (int) maxload;
953 }
954
955 /* for restricting monsters' object-pickup */
956 boolean
957 can_carry(mtmp,otmp)
958 struct monst *mtmp;
959 struct obj *otmp;
960 {
961         int otyp = otmp->otyp, newload = otmp->owt;
962         struct permonst *mdat = mtmp->data;
963
964         if (notake(mdat)) return FALSE;         /* can't carry anything */
965
966         if (otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) &&
967                 !(mtmp->misc_worn_check & W_ARMG) && !resists_ston(mtmp))
968             return FALSE;
969         if (otyp == CORPSE && is_rider(&mons[otmp->corpsenm]))
970             return FALSE;
971         if (objects[otyp].oc_material == SILVER && hates_silver(mdat) &&
972                 (otyp != BELL_OF_OPENING || !is_covetous(mdat)))
973             return FALSE;
974
975 #ifdef STEED
976         /* Steeds don't pick up stuff (to avoid shop abuse) */
977         if (mtmp == u.usteed) return (FALSE);
978 #endif
979         if (mtmp->isshk) return(TRUE); /* no limit */
980         if (mtmp->mpeaceful && !mtmp->mtame) return(FALSE);
981         /* otherwise players might find themselves obligated to violate
982          * their alignment if the monster takes something they need
983          */
984
985         /* special--boulder throwers carry unlimited amounts of boulders */
986         if (throws_rocks(mdat) && otyp == BOULDER)
987                 return(TRUE);
988
989         /* nymphs deal in stolen merchandise, but not boulders or statues */
990         if (mdat->mlet == S_NYMPH)
991                 return (boolean)(otmp->oclass != ROCK_CLASS);
992
993         if (curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return FALSE;
994
995         return(TRUE);
996 }
997
998 /* return number of acceptable neighbour positions */
999 int
1000 mfndpos(mon, poss, info, flag)
1001         register struct monst *mon;
1002         coord *poss;    /* coord poss[9] */
1003         long *info;     /* long info[9] */
1004         long flag;
1005 {
1006         struct permonst *mdat = mon->data;
1007         register xchar x,y,nx,ny;
1008         register int cnt = 0;
1009         register uchar ntyp;
1010         uchar nowtyp;
1011         boolean wantpool,poolok,lavaok,nodiag;
1012         boolean rockok = FALSE, treeok = FALSE, thrudoor;
1013         int maxx, maxy;
1014
1015         x = mon->mx;
1016         y = mon->my;
1017         nowtyp = levl[x][y].typ;
1018
1019         nodiag = (mdat == &mons[PM_GRID_BUG]);
1020         wantpool = mdat->mlet == S_EEL;
1021         poolok = is_flyer(mdat) || is_clinger(mdat) ||
1022                  (is_swimmer(mdat) && !wantpool);
1023         lavaok = is_flyer(mdat) || is_clinger(mdat) || likes_lava(mdat);
1024         thrudoor = ((flag & (ALLOW_WALL|BUSTDOOR)) != 0L);
1025         if (flag & ALLOW_DIG) {
1026             struct obj *mw_tmp;
1027
1028             /* need to be specific about what can currently be dug */
1029             if (!needspick(mdat)) {
1030                 rockok = treeok = TRUE;
1031             } else if ((mw_tmp = MON_WEP(mon)) && mw_tmp->cursed &&
1032                        mon->weapon_check == NO_WEAPON_WANTED) {
1033                 rockok = is_pick(mw_tmp);
1034                 treeok = is_axe(mw_tmp);
1035             } else {
1036                 rockok = (m_carrying(mon, PICK_AXE) ||
1037                           (m_carrying(mon, DWARVISH_MATTOCK) &&
1038                            !which_armor(mon, W_ARMS)));
1039                 treeok = (m_carrying(mon, AXE) ||
1040                           (m_carrying(mon, BATTLE_AXE) &&
1041                            !which_armor(mon, W_ARMS)));
1042             }
1043             thrudoor |= rockok || treeok;
1044         }
1045
1046 nexttry:        /* eels prefer the water, but if there is no water nearby,
1047                    they will crawl over land */
1048         if(mon->mconf) {
1049                 flag |= ALLOW_ALL;
1050                 flag &= ~NOTONL;
1051         }
1052         if(!mon->mcansee)
1053                 flag |= ALLOW_SSM;
1054         maxx = min(x+1,COLNO-1);
1055         maxy = min(y+1,ROWNO-1);
1056         for(nx = max(1,x-1); nx <= maxx; nx++)
1057           for(ny = max(0,y-1); ny <= maxy; ny++) {
1058             if(nx == x && ny == y) continue;
1059             if(IS_ROCK(ntyp = levl[nx][ny].typ) &&
1060                !((flag & ALLOW_WALL) && may_passwall(nx,ny)) &&
1061                !((IS_TREE(ntyp) ? treeok : rockok) && may_dig(nx,ny))) continue;
1062             /* KMH -- Added iron bars */
1063             if (ntyp == IRONBARS && !(flag & ALLOW_BARS)) continue;
1064             if(IS_DOOR(ntyp) && !amorphous(mdat) &&
1065                ((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) ||
1066                 (levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR))) &&
1067                !thrudoor) continue;
1068             if(nx != x && ny != y && (nodiag ||
1069 #ifdef REINCARNATION
1070                ((IS_DOOR(nowtyp) &&
1071                  ((levl[x][y].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))) ||
1072                 (IS_DOOR(ntyp) &&
1073                  ((levl[nx][ny].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))))
1074 #else
1075                ((IS_DOOR(nowtyp) && (levl[x][y].doormask & ~D_BROKEN)) ||
1076                 (IS_DOOR(ntyp) && (levl[nx][ny].doormask & ~D_BROKEN)))
1077 #endif
1078                ))
1079                 continue;
1080             if((is_pool(nx,ny) == wantpool || poolok) &&
1081                (lavaok || !is_lava(nx,ny))) {
1082                 int dispx, dispy;
1083                 boolean monseeu = (mon->mcansee && (!Invis || perceives(mdat)));
1084                 boolean checkobj = OBJ_AT(nx,ny);
1085
1086                 /* Displacement also displaces the Elbereth/scare monster,
1087                  * as long as you are visible.
1088                  */
1089                 if(Displaced && monseeu && (mon->mux==nx) && (mon->muy==ny)) {
1090                     dispx = u.ux;
1091                     dispy = u.uy;
1092                 } else {
1093                     dispx = nx;
1094                     dispy = ny;
1095                 }
1096
1097                 info[cnt] = 0;
1098                 if ((checkobj || Displaced) && onscary(dispx, dispy, mon)) {
1099                     if(!(flag & ALLOW_SSM)) continue;
1100                     info[cnt] |= ALLOW_SSM;
1101                 }
1102                 if((nx == u.ux && ny == u.uy) ||
1103                    (nx == mon->mux && ny == mon->muy)) {
1104                         if (nx == u.ux && ny == u.uy) {
1105                                 /* If it's right next to you, it found you,
1106                                  * displaced or no.  We must set mux and muy
1107                                  * right now, so when we return we can tell
1108                                  * that the ALLOW_U means to attack _you_ and
1109                                  * not the image.
1110                                  */
1111                                 mon->mux = u.ux;
1112                                 mon->muy = u.uy;
1113                         }
1114                         if(!(flag & ALLOW_U)) continue;
1115                         info[cnt] |= ALLOW_U;
1116                 } else {
1117                         if(MON_AT(nx, ny)) {
1118                                 struct monst *mtmp2 = m_at(nx, ny);
1119                                 long mmflag = flag | mm_aggression(mon, mtmp2);
1120
1121                                 if (!(mmflag & ALLOW_M)) continue;
1122                                 info[cnt] |= ALLOW_M;
1123                                 if (mtmp2->mtame) {
1124                                         if (!(mmflag & ALLOW_TM)) continue;
1125                                         info[cnt] |= ALLOW_TM;
1126                                 }
1127                         }
1128                         /* Note: ALLOW_SANCT only prevents movement, not */
1129                         /* attack, into a temple. */
1130                         if(level.flags.has_temple &&
1131                            *in_rooms(nx, ny, TEMPLE) &&
1132                            !*in_rooms(x, y, TEMPLE) &&
1133                            in_your_sanctuary((struct monst *)0, nx, ny)) {
1134                                 if(!(flag & ALLOW_SANCT)) continue;
1135                                 info[cnt] |= ALLOW_SANCT;
1136                         }
1137                 }
1138                 if(checkobj && sobj_at(CLOVE_OF_GARLIC, nx, ny)) {
1139                         if(flag & NOGARLIC) continue;
1140                         info[cnt] |= NOGARLIC;
1141                 }
1142                 if(checkobj && sobj_at(BOULDER, nx, ny)) {
1143                         if(!(flag & ALLOW_ROCK)) continue;
1144                         info[cnt] |= ALLOW_ROCK;
1145                 }
1146                 if (monseeu && onlineu(nx,ny)) {
1147                         if(flag & NOTONL) continue;
1148                         info[cnt] |= NOTONL;
1149                 }
1150                 if (nx != x && ny != y && bad_rock(mdat, x, ny)
1151                             && bad_rock(mdat, nx, y)
1152                             && (bigmonst(mdat) || (curr_mon_load(mon) > 600)))
1153                         continue;
1154                 /* The monster avoids a particular type of trap if it's familiar
1155                  * with the trap type.  Pets get ALLOW_TRAPS and checking is
1156                  * done in dogmove.c.  In either case, "harmless" traps are
1157                  * neither avoided nor marked in info[].
1158                  */
1159                 { register struct trap *ttmp = t_at(nx, ny);
1160                     if(ttmp) {
1161                         if(ttmp->ttyp >= TRAPNUM || ttmp->ttyp == 0)  {
1162 impossible("A monster looked at a very strange trap of type %d.", ttmp->ttyp);
1163                             continue;
1164                         }
1165                         if ((ttmp->ttyp != RUST_TRAP
1166                                         || mdat == &mons[PM_IRON_GOLEM])
1167                                 && ttmp->ttyp != STATUE_TRAP
1168                                 && ((ttmp->ttyp != PIT
1169                                     && ttmp->ttyp != SPIKED_PIT
1170                                     && ttmp->ttyp != TRAPDOOR
1171                                     && ttmp->ttyp != HOLE)
1172                                       || (!is_flyer(mdat)
1173                                     && !is_floater(mdat)
1174                                     && !is_clinger(mdat))
1175                                       || In_sokoban(&u.uz))
1176                                 && (ttmp->ttyp != SLP_GAS_TRAP ||
1177                                     !resists_sleep(mon))
1178                                 && (ttmp->ttyp != BEAR_TRAP ||
1179                                     (mdat->msize > MZ_SMALL &&
1180                                      !amorphous(mdat) && !is_flyer(mdat)))
1181                                 && (ttmp->ttyp != FIRE_TRAP ||
1182                                     !resists_fire(mon))
1183                                 && (ttmp->ttyp != SQKY_BOARD || !is_flyer(mdat))
1184                                 && (ttmp->ttyp != WEB || (!amorphous(mdat) &&
1185                                     !webmaker(mdat)))
1186                         ) {
1187                             if (!(flag & ALLOW_TRAPS)) {
1188                                 if (mon->mtrapseen & (1L << (ttmp->ttyp - 1)))
1189                                     continue;
1190                             }
1191                             info[cnt] |= ALLOW_TRAPS;
1192                         }
1193                     }
1194                 }
1195                 poss[cnt].x = nx;
1196                 poss[cnt].y = ny;
1197                 cnt++;
1198             }
1199         }
1200         if(!cnt && wantpool && !is_pool(x,y)) {
1201                 wantpool = FALSE;
1202                 goto nexttry;
1203         }
1204         return(cnt);
1205 }
1206
1207 #endif /* OVL0 */
1208 #ifdef OVL1
1209
1210 /* Monster against monster special attacks; for the specified monster
1211    combinations, this allows one monster to attack another adjacent one
1212    in the absence of Conflict.  There is no provision for targetting
1213    other monsters; just hand to hand fighting when they happen to be
1214    next to each other. */
1215 STATIC_OVL long
1216 mm_aggression(magr, mdef)
1217 struct monst *magr,     /* monster that is currently deciding where to move */
1218              *mdef;     /* another monster which is next to it */
1219 {
1220         /* supposedly purple worms are attracted to shrieking because they
1221            like to eat shriekers, so attack the latter when feasible */
1222         if (magr->data == &mons[PM_PURPLE_WORM] &&
1223                 mdef->data == &mons[PM_SHRIEKER])
1224             return ALLOW_M|ALLOW_TM;
1225         /* Various other combinations such as dog vs cat, cat vs rat, and
1226            elf vs orc have been suggested.  For the time being we don't
1227            support those. */
1228         return 0L;
1229 }
1230
1231 boolean
1232 monnear(mon, x, y)
1233 register struct monst *mon;
1234 register int x,y;
1235 /* Is the square close enough for the monster to move or attack into? */
1236 {
1237         register int distance = dist2(mon->mx, mon->my, x, y);
1238         if (distance==2 && mon->data==&mons[PM_GRID_BUG]) return 0;
1239         return((boolean)(distance < 3));
1240 }
1241
1242 /* really free dead monsters */
1243 void
1244 dmonsfree()
1245 {
1246     struct monst **mtmp;
1247     int count = 0;
1248
1249     for (mtmp = &fmon; *mtmp;) {
1250         if ((*mtmp)->mhp <= 0) {
1251             struct monst *freetmp = *mtmp;
1252             *mtmp = (*mtmp)->nmon;
1253             dealloc_monst(freetmp);
1254             count++;
1255         } else
1256             mtmp = &(*mtmp)->nmon;
1257     }
1258
1259     if (count != iflags.purge_monsters)
1260         impossible("dmonsfree: %d removed doesn't match %d pending",
1261                    count, iflags.purge_monsters);
1262     iflags.purge_monsters = 0;
1263 }
1264
1265 #endif /* OVL1 */
1266 #ifdef OVLB
1267
1268 /* called when monster is moved to larger structure */
1269 void
1270 replmon(mtmp, mtmp2)
1271 register struct monst *mtmp, *mtmp2;
1272 {
1273     struct obj *otmp;
1274
1275     /* transfer the monster's inventory */
1276     for (otmp = mtmp2->minvent; otmp; otmp = otmp->nobj) {
1277 #ifdef DEBUG
1278         if (otmp->where != OBJ_MINVENT || otmp->ocarry != mtmp)
1279             panic("replmon: minvent inconsistency");
1280 #endif
1281         otmp->ocarry = mtmp2;
1282     }
1283     mtmp->minvent = 0;
1284
1285     /* remove the old monster from the map and from `fmon' list */
1286     relmon(mtmp);
1287
1288     /* finish adding its replacement */
1289 #ifdef STEED
1290     if (mtmp == u.usteed) ; else        /* don't place steed onto the map */
1291 #endif
1292     place_monster(mtmp2, mtmp2->mx, mtmp2->my);
1293     if (mtmp2->wormno)      /* update level.monsters[wseg->wx][wseg->wy] */
1294         place_wsegs(mtmp2); /* locations to mtmp2 not mtmp. */
1295     if (emits_light(mtmp2->data)) {
1296         /* since this is so rare, we don't have any `mon_move_light_source' */
1297         new_light_source(mtmp2->mx, mtmp2->my,
1298                          emits_light(mtmp2->data),
1299                          LS_MONSTER, (genericptr_t)mtmp2);
1300         /* here we rely on the fact that `mtmp' hasn't actually been deleted */
1301         del_light_source(LS_MONSTER, (genericptr_t)mtmp);
1302     }
1303     mtmp2->nmon = fmon;
1304     fmon = mtmp2;
1305     if (u.ustuck == mtmp) u.ustuck = mtmp2;
1306 #ifdef STEED
1307     if (u.usteed == mtmp) u.usteed = mtmp2;
1308 #endif
1309     if (mtmp2->isshk) replshk(mtmp,mtmp2);
1310
1311     /* discard the old monster */
1312     dealloc_monst(mtmp);
1313 }
1314
1315 /* release mon from display and monster list */
1316 void
1317 relmon(mon)
1318 register struct monst *mon;
1319 {
1320         register struct monst *mtmp;
1321
1322         if (fmon == (struct monst *)0)  panic ("relmon: no fmon available.");
1323
1324         remove_monster(mon->mx, mon->my);
1325
1326         if(mon == fmon) fmon = fmon->nmon;
1327         else {
1328                 for(mtmp = fmon; mtmp && mtmp->nmon != mon; mtmp = mtmp->nmon) ;
1329                 if(mtmp)    mtmp->nmon = mon->nmon;
1330                 else        panic("relmon: mon not in list.");
1331         }
1332 }
1333
1334 /* remove effects of mtmp from other data structures */
1335 STATIC_OVL void
1336 m_detach(mtmp, mptr)
1337 struct monst *mtmp;
1338 struct permonst *mptr;  /* reflects mtmp->data _prior_ to mtmp's death */
1339 {
1340         if (mtmp->mleashed) m_unleash(mtmp, FALSE);
1341             /* to prevent an infinite relobj-flooreffects-hmon-killed loop */
1342         mtmp->mtrapped = 0;
1343         mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */
1344         relobj(mtmp, 0, FALSE);
1345         remove_monster(mtmp->mx, mtmp->my);
1346         if (emits_light(mptr))
1347             del_light_source(LS_MONSTER, (genericptr_t)mtmp);
1348         newsym(mtmp->mx,mtmp->my);
1349         unstuck(mtmp);
1350         fill_pit(mtmp->mx, mtmp->my);
1351
1352         if(mtmp->isshk) shkgone(mtmp);
1353         if(mtmp->wormno) wormgone(mtmp);
1354         iflags.purge_monsters++;
1355 }
1356
1357 /* find the worn amulet of life saving which will save a monster */
1358 struct obj *
1359 mlifesaver(mon)
1360 struct monst *mon;
1361 {
1362         if (!nonliving(mon->data)) {
1363             struct obj *otmp = which_armor(mon, W_AMUL);
1364
1365             if (otmp && otmp->otyp == AMULET_OF_LIFE_SAVING)
1366                 return otmp;
1367         }
1368         return (struct obj *)0;
1369 }
1370
1371 STATIC_OVL void
1372 lifesaved_monster(mtmp)
1373 struct monst *mtmp;
1374 {
1375         struct obj *lifesave = mlifesaver(mtmp);
1376
1377         if (lifesave) {
1378                 /* not canseemon; amulets are on the head, so you don't want */
1379                 /* to show this for a long worm with only a tail visible. */
1380                 /* Nor do you check invisibility, because glowing and disinte- */
1381                 /* grating amulets are always visible. */
1382                 if (cansee(mtmp->mx, mtmp->my)) {
1383                         pline("But wait...");
1384                         pline("%s medallion begins to glow!",
1385                                 s_suffix(Monnam(mtmp)));
1386                         makeknown(AMULET_OF_LIFE_SAVING);
1387                         if (attacktype(mtmp->data, AT_EXPL)
1388                             || attacktype(mtmp->data, AT_BOOM))
1389                                 pline("%s reconstitutes!", Monnam(mtmp));
1390                         else
1391                                 pline("%s looks much better!", Monnam(mtmp));
1392                         pline_The("medallion crumbles to dust!");
1393                 }
1394                 m_useup(mtmp, lifesave);
1395                 mtmp->mcanmove = 1;
1396                 mtmp->mfrozen = 0;
1397                 if (mtmp->mtame && !mtmp->isminion) {
1398                         wary_dog(mtmp, FALSE);
1399                 }
1400                 if (mtmp->mhpmax <= 0) mtmp->mhpmax = 10;
1401                 mtmp->mhp = mtmp->mhpmax;
1402                 if (mvitals[monsndx(mtmp->data)].mvflags & G_GENOD) {
1403                         if (cansee(mtmp->mx, mtmp->my))
1404                             pline("Unfortunately %s is still genocided...",
1405                                 mon_nam(mtmp));
1406                 } else
1407                         return;
1408         }
1409         mtmp->mhp = 0;
1410 }
1411
1412 void
1413 mondead(mtmp)
1414 register struct monst *mtmp;
1415 {
1416         struct permonst *mptr;
1417         int tmp;
1418
1419         if(mtmp->isgd) {
1420                 /* if we're going to abort the death, it *must* be before
1421                  * the m_detach or there will be relmon problems later */
1422                 if(!grddead(mtmp)) return;
1423         }
1424         lifesaved_monster(mtmp);
1425         if (mtmp->mhp > 0) return;
1426
1427 #ifdef STEED
1428         /* Player is thrown from his steed when it dies */
1429         if (mtmp == u.usteed)
1430                 dismount_steed(DISMOUNT_GENERIC);
1431 #endif
1432
1433         mptr = mtmp->data;              /* save this for m_detach() */
1434         /* restore chameleon, lycanthropes to true form at death */
1435         if (mtmp->cham)
1436             set_mon_data(mtmp, &mons[cham_to_pm[mtmp->cham]], -1);
1437         else if (mtmp->data == &mons[PM_WEREJACKAL])
1438             set_mon_data(mtmp, &mons[PM_HUMAN_WEREJACKAL], -1);
1439         else if (mtmp->data == &mons[PM_WEREWOLF])
1440             set_mon_data(mtmp, &mons[PM_HUMAN_WEREWOLF], -1);
1441         else if (mtmp->data == &mons[PM_WERERAT])
1442             set_mon_data(mtmp, &mons[PM_HUMAN_WERERAT], -1);
1443
1444         /* if MAXMONNO monsters of a given type have died, and it
1445          * can be done, extinguish that monster.
1446          *
1447          * mvitals[].died does double duty as total number of dead monsters
1448          * and as experience factor for the player killing more monsters.
1449          * this means that a dragon dying by other means reduces the
1450          * experience the player gets for killing a dragon directly; this
1451          * is probably not too bad, since the player likely finagled the
1452          * first dead dragon via ring of conflict or pets, and extinguishing
1453          * based on only player kills probably opens more avenues of abuse
1454          * for rings of conflict and such.
1455          */
1456         tmp = monsndx(mtmp->data);
1457         if (mvitals[tmp].died < 255) mvitals[tmp].died++;
1458
1459         /* if it's a (possibly polymorphed) quest leader, mark him as dead */
1460         if (mtmp->m_id == quest_status.leader_m_id)
1461             quest_status.leader_is_dead = TRUE;
1462 #ifdef MAIL
1463         /* if the mail daemon dies, no more mail delivery.  -3. */
1464         if (tmp == PM_MAIL_DAEMON) mvitals[tmp].mvflags |= G_GENOD;
1465 #endif
1466
1467 #ifdef KOPS
1468         if (mtmp->data->mlet == S_KOP) {
1469             /* Dead Kops may come back. */
1470             switch(rnd(5)) {
1471                 case 1:      /* returns near the stairs */
1472                         (void) makemon(mtmp->data,xdnstair,ydnstair,NO_MM_FLAGS);
1473                         break;
1474                 case 2:      /* randomly */
1475                         (void) makemon(mtmp->data,0,0,NO_MM_FLAGS);
1476                         break;
1477                 default:
1478                         break;
1479             }
1480         }
1481 #endif
1482         if(mtmp->iswiz) wizdead();
1483         if(mtmp->data->msound == MS_NEMESIS) nemdead();
1484         if(glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
1485             unmap_object(mtmp->mx, mtmp->my);
1486         m_detach(mtmp, mptr);
1487 }
1488
1489 /* TRUE if corpse might be dropped, magr may die if mon was swallowed */
1490 boolean
1491 corpse_chance(mon, magr, was_swallowed)
1492 struct monst *mon;
1493 struct monst *magr;                     /* killer, if swallowed */
1494 boolean was_swallowed;                  /* digestion */
1495 {
1496         struct permonst *mdat = mon->data;
1497         int i, tmp;
1498
1499         if (mdat == &mons[PM_VLAD_THE_IMPALER] || mdat->mlet == S_LICH) {
1500             if (cansee(mon->mx, mon->my) && !was_swallowed)
1501                 pline("%s body crumbles into dust.", s_suffix(Monnam(mon)));
1502             return FALSE;
1503         }
1504
1505         /* Gas spores always explode upon death */
1506         for(i = 0; i < NATTK; i++) {
1507             if (mdat->mattk[i].aatyp == AT_BOOM) {
1508                 if (mdat->mattk[i].damn)
1509                     tmp = d((int)mdat->mattk[i].damn,
1510                                 (int)mdat->mattk[i].damd);
1511                 else if(mdat->mattk[i].damd)
1512                     tmp = d((int)mdat->mlevel+1, (int)mdat->mattk[i].damd);
1513                 else tmp = 0;
1514                 if (was_swallowed && magr) {
1515                     if (magr == &youmonst) {
1516                         There("is an explosion in your %s!",
1517                               body_part(STOMACH));
1518                         Sprintf(killer_buf, "%s explosion",
1519                                 s_suffix(mdat->mname));
1520                         if (Half_physical_damage) tmp = (tmp+1) / 2;
1521                         losehp(tmp, killer_buf, KILLED_BY_AN);
1522                     } else {
1523                         if (flags.soundok) You_hear("an explosion.");
1524                         magr->mhp -= tmp;
1525                         if (magr->mhp < 1) mondied(magr);
1526                         if (magr->mhp < 1) { /* maybe lifesaved */
1527                             if (canspotmon(magr))
1528                                 pline("%s rips open!", Monnam(magr));
1529                         } else if (canseemon(magr))
1530                             pline("%s seems to have indigestion.",
1531                                   Monnam(magr));
1532                     }
1533
1534                     return FALSE;
1535                 }
1536
1537                 Sprintf(killer_buf, "%s explosion", s_suffix(mdat->mname));
1538                 killer = killer_buf;
1539                 killer_format = KILLED_BY_AN;
1540                 explode(mon->mx, mon->my, -1, tmp, MON_EXPLODE, EXPL_NOXIOUS); 
1541                 return (FALSE);
1542             }
1543         }
1544
1545         /* must duplicate this below check in xkilled() since it results in
1546          * creating no objects as well as no corpse
1547          */
1548         if (LEVEL_SPECIFIC_NOCORPSE(mdat))
1549                 return FALSE;
1550
1551         if (bigmonst(mdat) || mdat == &mons[PM_LIZARD]
1552                    || is_golem(mdat)
1553                    || is_mplayer(mdat)
1554                    || is_rider(mdat))
1555                 return TRUE;
1556         return (boolean) (!rn2((int)
1557                 (2 + ((int)(mdat->geno & G_FREQ)<2) + verysmall(mdat))));
1558 }
1559
1560 /* drop (perhaps) a cadaver and remove monster */
1561 void
1562 mondied(mdef)
1563 register struct monst *mdef;
1564 {
1565         mondead(mdef);
1566         if (mdef->mhp > 0) return;      /* lifesaved */
1567
1568         if (corpse_chance(mdef, (struct monst *)0, FALSE) &&
1569             (accessible(mdef->mx, mdef->my) || is_pool(mdef->mx, mdef->my)))
1570                 (void) make_corpse(mdef);
1571 }
1572
1573 /* monster disappears, not dies */
1574 void
1575 mongone(mdef)
1576 register struct monst *mdef;
1577 {
1578         mdef->mhp = 0;  /* can skip some inventory bookkeeping */
1579 #ifdef STEED
1580         /* Player is thrown from his steed when it disappears */
1581         if (mdef == u.usteed)
1582                 dismount_steed(DISMOUNT_GENERIC);
1583 #endif
1584
1585         /* drop special items like the Amulet so that a dismissed Kop or nurse
1586            can't remove them from the game */
1587         mdrop_special_objs(mdef);
1588         /* release rest of monster's inventory--it is removed from game */
1589         discard_minvent(mdef);
1590 #ifndef GOLDOBJ
1591         mdef->mgold = 0L;
1592 #endif
1593         m_detach(mdef, mdef->data);
1594 }
1595
1596 /* drop a statue or rock and remove monster */
1597 void
1598 monstone(mdef)
1599 register struct monst *mdef;
1600 {
1601         struct obj *otmp, *obj, *oldminvent;
1602         xchar x = mdef->mx, y = mdef->my;
1603         boolean wasinside = FALSE;
1604
1605         /* we have to make the statue before calling mondead, to be able to
1606          * put inventory in it, and we have to check for lifesaving before
1607          * making the statue....
1608          */
1609         lifesaved_monster(mdef);
1610         if (mdef->mhp > 0) return;
1611
1612         mdef->mtrapped = 0;     /* (see m_detach) */
1613
1614         if ((int)mdef->data->msize > MZ_TINY ||
1615                     !rn2(2 + ((int) (mdef->data->geno & G_FREQ) > 2))) {
1616                 oldminvent = 0;
1617                 /* some objects may end up outside the statue */
1618                 while ((obj = mdef->minvent) != 0) {
1619                     obj_extract_self(obj);
1620                     if (obj->owornmask)
1621                         update_mon_intrinsics(mdef, obj, FALSE, TRUE);
1622                     obj_no_longer_held(obj);
1623                     if (obj->owornmask & W_WEP)
1624                         setmnotwielded(mdef,obj);
1625                     obj->owornmask = 0L;
1626                     if (obj->otyp == BOULDER ||
1627 #if 0                           /* monsters don't carry statues */
1628      (obj->otyp == STATUE && mons[obj->corpsenm].msize >= mdef->data->msize) ||
1629 #endif
1630                                 obj_resists(obj, 0, 0)) {
1631                         if (flooreffects(obj, x, y, "fall")) continue;
1632                         place_object(obj, x, y);
1633                     } else {
1634                         if (obj->lamplit) end_burn(obj, TRUE);
1635                         obj->nobj = oldminvent;
1636                         oldminvent = obj;
1637                     }
1638                 }
1639                 /* defer statue creation until after inventory removal
1640                    so that saved monster traits won't retain any stale
1641                    item-conferred attributes */
1642                 otmp = mkcorpstat(STATUE, KEEPTRAITS(mdef) ? mdef : 0,
1643                                   mdef->data, x, y, FALSE);
1644                 if (mdef->mnamelth) otmp = oname(otmp, NAME(mdef));
1645                 while ((obj = oldminvent) != 0) {
1646                     oldminvent = obj->nobj;
1647                     (void) add_to_container(otmp, obj);
1648                 }
1649 #ifndef GOLDOBJ
1650                 if (mdef->mgold) {
1651                         struct obj *au;
1652                         au = mksobj(GOLD_PIECE, FALSE, FALSE);
1653                         au->quan = mdef->mgold;
1654                         au->owt = weight(au);
1655                         (void) add_to_container(otmp, au);
1656                         mdef->mgold = 0;
1657                 }
1658 #endif
1659                 /* Archeologists should not break unique statues */
1660                 if (mdef->data->geno & G_UNIQ)
1661                         otmp->spe = 1;
1662                 otmp->owt = weight(otmp);
1663         } else
1664                 otmp = mksobj_at(ROCK, x, y, TRUE, FALSE);
1665
1666         stackobj(otmp);
1667         /* mondead() already does this, but we must do it before the newsym */
1668         if(glyph_is_invisible(levl[x][y].glyph))
1669             unmap_object(x, y);
1670         if (cansee(x, y)) newsym(x,y);
1671         /* We don't currently trap the hero in the statue in this case but we could */
1672         if (u.uswallow && u.ustuck == mdef) wasinside = TRUE;
1673         mondead(mdef);
1674         if (wasinside) {
1675                 if (is_animal(mdef->data))
1676                         You("%s through an opening in the new %s.",
1677                                 locomotion(youmonst.data, "jump"),
1678                                 xname(otmp));
1679         }
1680 }
1681
1682 /* another monster has killed the monster mdef */
1683 void
1684 monkilled(mdef, fltxt, how)
1685 register struct monst *mdef;
1686 const char *fltxt;
1687 int how;
1688 {
1689         boolean be_sad = FALSE;         /* true if unseen pet is killed */
1690
1691         if ((mdef->wormno ? worm_known(mdef) : cansee(mdef->mx, mdef->my))
1692                 && fltxt)
1693             pline("%s is %s%s%s!", Monnam(mdef),
1694                         nonliving(mdef->data) ? "destroyed" : "killed",
1695                     *fltxt ? " by the " : "",
1696                     fltxt
1697                  );
1698         else
1699             be_sad = (mdef->mtame != 0);
1700
1701         /* no corpses if digested or disintegrated */
1702         if(how == AD_DGST || how == -AD_RBRE)
1703             mondead(mdef);
1704         else
1705             mondied(mdef);
1706
1707         if (be_sad && mdef->mhp <= 0)
1708             You("have a sad feeling for a moment, then it passes.");
1709 }
1710
1711 void
1712 unstuck(mtmp)
1713 register struct monst *mtmp;
1714 {
1715         if(u.ustuck == mtmp) {
1716                 if(u.uswallow){
1717                         u.ux = mtmp->mx;
1718                         u.uy = mtmp->my;
1719                         u.uswallow = 0;
1720                         u.uswldtim = 0;
1721                         if (Punished) placebc();
1722                         vision_full_recalc = 1;
1723                         docrt();
1724                 }
1725                 u.ustuck = 0;
1726         }
1727 }
1728
1729 void
1730 killed(mtmp)
1731 register struct monst *mtmp;
1732 {
1733         xkilled(mtmp, 1);
1734 }
1735
1736 /* the player has killed the monster mtmp */
1737 void
1738 xkilled(mtmp, dest)
1739         register struct monst *mtmp;
1740 /*
1741  * Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse
1742  * either; dest=3, message but no corpse
1743  */
1744         int     dest;
1745 {
1746         register int tmp, x = mtmp->mx, y = mtmp->my;
1747         register struct permonst *mdat;
1748         int mndx;
1749         register struct obj *otmp;
1750         register struct trap *t;
1751         boolean redisp = FALSE;
1752         boolean wasinside = u.uswallow && (u.ustuck == mtmp);
1753
1754
1755         /* KMH, conduct */
1756         u.uconduct.killer++;
1757
1758         if (dest & 1) {
1759             const char *verb = nonliving(mtmp->data) ? "destroy" : "kill";
1760
1761             if (!wasinside && !canspotmon(mtmp))
1762                 You("%s it!", verb);
1763             else {
1764                 You("%s %s!", verb,
1765                     !mtmp->mtame ? mon_nam(mtmp) :
1766                         x_monnam(mtmp,
1767                                  mtmp->mnamelth ? ARTICLE_NONE : ARTICLE_THE,
1768                                  "poor",
1769                                  mtmp->mnamelth ? SUPPRESS_SADDLE : 0,
1770                                  FALSE));
1771             }
1772         }
1773
1774         if (mtmp->mtrapped && (t = t_at(x, y)) != 0 &&
1775                 (t->ttyp == PIT || t->ttyp == SPIKED_PIT) &&
1776                 sobj_at(BOULDER, x, y))
1777             dest |= 2;     /*
1778                             * Prevent corpses/treasure being created "on top"
1779                             * of the boulder that is about to fall in. This is
1780                             * out of order, but cannot be helped unless this
1781                             * whole routine is rearranged.
1782                             */
1783
1784         /* your pet knows who just killed it...watch out */
1785         if (mtmp->mtame && !mtmp->isminion) EDOG(mtmp)->killed_by_u = 1;
1786
1787         /* dispose of monster and make cadaver */
1788         if(stoned) monstone(mtmp);
1789         else mondead(mtmp);
1790
1791         if (mtmp->mhp > 0) { /* monster lifesaved */
1792                 /* Cannot put the non-visible lifesaving message in
1793                  * lifesaved_monster() since the message appears only when you
1794                  * kill it (as opposed to visible lifesaving which always
1795                  * appears).
1796                  */
1797                 stoned = FALSE;
1798                 if (!cansee(x,y)) pline("Maybe not...");
1799                 return;
1800         }
1801
1802         mdat = mtmp->data; /* note: mondead can change mtmp->data */
1803         mndx = monsndx(mdat);
1804
1805         if (stoned) {
1806                 stoned = FALSE;
1807                 goto cleanup;
1808         }
1809
1810         if((dest & 2) || LEVEL_SPECIFIC_NOCORPSE(mdat))
1811                 goto cleanup;
1812
1813 #ifdef MAIL
1814         if(mdat == &mons[PM_MAIL_DAEMON]) {
1815                 stackobj(mksobj_at(SCR_MAIL, x, y, FALSE, FALSE));
1816                 redisp = TRUE;
1817         }
1818 #endif
1819         if((!accessible(x, y) && !is_pool(x, y)) ||
1820            (x == u.ux && y == u.uy)) {
1821             /* might be mimic in wall or corpse in lava or on player's spot */
1822             redisp = TRUE;
1823             if(wasinside) spoteffects(TRUE);
1824         } else if(x != u.ux || y != u.uy) {
1825                 /* might be here after swallowed */
1826                 if (!rn2(6) && !(mvitals[mndx].mvflags & G_NOCORPSE)
1827 #ifdef KOPS
1828                                         && mdat->mlet != S_KOP
1829 #endif
1830                                                         ) {
1831                         int typ;
1832
1833                         otmp = mkobj_at(RANDOM_CLASS, x, y, TRUE);
1834                         /* Don't create large objects from small monsters */
1835                         typ = otmp->otyp;
1836                         if (mdat->msize < MZ_HUMAN && typ != FOOD_RATION
1837                             && typ != LEASH
1838                             && typ != FIGURINE
1839                             && (otmp->owt > 3 ||
1840                                 objects[typ].oc_big /*oc_bimanual/oc_bulky*/ ||
1841                                 is_spear(otmp) || is_pole(otmp) ||
1842                                 typ == MORNING_STAR)) {
1843                             delobj(otmp);
1844                         } else redisp = TRUE;
1845                 }
1846                 /* Whether or not it always makes a corpse is, in theory,
1847                  * different from whether or not the corpse is "special";
1848                  * if we want both, we have to specify it explicitly.
1849                  */
1850                 if (corpse_chance(mtmp, (struct monst *)0, FALSE))
1851                         (void) make_corpse(mtmp);
1852         }
1853         if(redisp) newsym(x,y);
1854 cleanup:
1855         /* punish bad behaviour */
1856         if(is_human(mdat) && (!always_hostile(mdat) && mtmp->malign <= 0) &&
1857            (mndx < PM_ARCHEOLOGIST || mndx > PM_WIZARD) &&
1858            u.ualign.type != A_CHAOTIC) {
1859                 HTelepat &= ~INTRINSIC;
1860                 change_luck(-2);
1861                 You("murderer!");
1862                 if (Blind && !Blind_telepat)
1863                     see_monsters(); /* Can't sense monsters any more. */
1864         }
1865         if((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame) change_luck(-1);
1866         if (is_unicorn(mdat) &&
1867                                 sgn(u.ualign.type) == sgn(mdat->maligntyp)) {
1868                 change_luck(-5);
1869                 You_feel("guilty...");
1870         }
1871
1872         /* give experience points */
1873         tmp = experience(mtmp, (int)mvitals[mndx].died + 1);
1874         more_experienced(tmp, 0);
1875         newexplevel();          /* will decide if you go up */
1876
1877         /* adjust alignment points */
1878         if (mtmp->m_id == quest_status.leader_m_id) {           /* REAL BAD! */
1879             adjalign(-(u.ualign.record+(int)ALIGNLIM/2));
1880             pline("That was %sa bad idea...",
1881                         u.uevent.qcompleted ? "probably " : "");
1882         } else if (mdat->msound == MS_NEMESIS)  /* Real good! */
1883             adjalign((int)(ALIGNLIM/4));
1884         else if (mdat->msound == MS_GUARDIAN) { /* Bad */
1885             adjalign(-(int)(ALIGNLIM/8));
1886             if (!Hallucination) pline("That was probably a bad idea...");
1887             else pline("Whoopsie-daisy!");
1888         }else if (mtmp->ispriest) {
1889                 adjalign((p_coaligned(mtmp)) ? -2 : 2);
1890                 /* cancel divine protection for killing your priest */
1891                 if (p_coaligned(mtmp)) u.ublessed = 0;
1892                 if (mdat->maligntyp == A_NONE)
1893                         adjalign((int)(ALIGNLIM / 4));          /* BIG bonus */
1894         } else if (mtmp->mtame) {
1895                 adjalign(-15);  /* bad!! */
1896                 /* your god is mighty displeased... */
1897                 if (!Hallucination) You_hear("the rumble of distant thunder...");
1898                 else You_hear("the studio audience applaud!");
1899         } else if (mtmp->mpeaceful)
1900                 adjalign(-5);
1901
1902         /* malign was already adjusted for u.ualign.type and randomization */
1903         adjalign(mtmp->malign);
1904 }
1905
1906 /* changes the monster into a stone monster of the same type */
1907 /* this should only be called when poly_when_stoned() is true */
1908 void
1909 mon_to_stone(mtmp)
1910     register struct monst *mtmp;
1911 {
1912     if(mtmp->data->mlet == S_GOLEM) {
1913         /* it's a golem, and not a stone golem */
1914         if(canseemon(mtmp))
1915             pline("%s solidifies...", Monnam(mtmp));
1916         if (newcham(mtmp, &mons[PM_STONE_GOLEM], FALSE, FALSE)) {
1917             if(canseemon(mtmp))
1918                 pline("Now it's %s.", an(mtmp->data->mname));
1919         } else {
1920             if(canseemon(mtmp))
1921                 pline("... and returns to normal.");
1922         }
1923     } else
1924         impossible("Can't polystone %s!", a_monnam(mtmp));
1925 }
1926
1927 void
1928 mnexto(mtmp)    /* Make monster mtmp next to you (if possible) */
1929         struct monst *mtmp;
1930 {
1931         coord mm;
1932
1933 #ifdef STEED
1934         if (mtmp == u.usteed) {
1935                 /* Keep your steed in sync with you instead */
1936                 mtmp->mx = u.ux;
1937                 mtmp->my = u.uy;
1938                 return;
1939         }
1940 #endif
1941
1942         if(!enexto(&mm, u.ux, u.uy, mtmp->data)) return;
1943         rloc_to(mtmp, mm.x, mm.y);
1944         return;
1945 }
1946
1947 /* mnearto()
1948  * Put monster near (or at) location if possible.
1949  * Returns:
1950  *      1 - if a monster was moved from x, y to put mtmp at x, y.
1951  *      0 - in most cases.
1952  */
1953 boolean
1954 mnearto(mtmp,x,y,move_other)
1955 register struct monst *mtmp;
1956 xchar x, y;
1957 boolean move_other;     /* make sure mtmp gets to x, y! so move m_at(x, y) */
1958 {
1959         struct monst *othermon = (struct monst *)0;
1960         xchar newx, newy;
1961         coord mm;
1962
1963         if ((mtmp->mx == x) && (mtmp->my == y)) return(FALSE);
1964
1965         if (move_other && (othermon = m_at(x, y))) {
1966                 if (othermon->wormno)
1967                         remove_worm(othermon);
1968                 else
1969                         remove_monster(x, y);
1970         }
1971
1972         newx = x;
1973         newy = y;
1974
1975         if (!goodpos(newx, newy, mtmp, 0)) {
1976                 /* actually we have real problems if enexto ever fails.
1977                  * migrating_mons that need to be placed will cause
1978                  * no end of trouble.
1979                  */
1980                 if (!enexto(&mm, newx, newy, mtmp->data)) return(FALSE);
1981                 newx = mm.x; newy = mm.y;
1982         }
1983
1984         rloc_to(mtmp, newx, newy);
1985
1986         if (move_other && othermon) {
1987             othermon->mx = othermon->my = 0;
1988             (void) mnearto(othermon, x, y, FALSE);
1989             if ((othermon->mx != x) || (othermon->my != y))
1990                 return(TRUE);
1991         }
1992
1993         return(FALSE);
1994 }
1995
1996
1997 static const char *poiseff[] = {
1998
1999         " feel weaker", "r brain is on fire",
2000         "r judgement is impaired", "r muscles won't obey you",
2001         " feel very sick", " break out in hives"
2002 };
2003
2004 void
2005 poisontell(typ)
2006
2007         int     typ;
2008 {
2009         pline("You%s.", poiseff[typ]);
2010 }
2011
2012 void
2013 poisoned(string, typ, pname, fatal)
2014 const char *string, *pname;
2015 int  typ, fatal;
2016 {
2017         int i, plural, kprefix = KILLED_BY_AN;
2018         boolean thrown_weapon = (fatal < 0);
2019
2020         if (thrown_weapon) fatal = -fatal;
2021         if(strcmp(string, "blast") && !thrown_weapon) {
2022             /* 'blast' has already given a 'poison gas' message */
2023             /* so have "poison arrow", "poison dart", etc... */
2024             plural = (string[strlen(string) - 1] == 's')? 1 : 0;
2025             /* avoid "The" Orcus's sting was poisoned... */
2026             pline("%s%s %s poisoned!", isupper(*string) ? "" : "The ",
2027                         string, plural ? "were" : "was");
2028         }
2029
2030         if(Poison_resistance) {
2031                 if(!strcmp(string, "blast")) shieldeff(u.ux, u.uy);
2032                 pline_The("poison doesn't seem to affect you.");
2033                 return;
2034         }
2035         /* suppress killer prefix if it already has one */
2036         if ((i = name_to_mon(pname)) >= LOW_PM && mons[i].geno & G_UNIQ) {
2037             kprefix = KILLED_BY;
2038             if (!type_is_pname(&mons[i])) pname = the(pname);
2039         } else if (!strncmpi(pname, "the ", 4) ||
2040             !strncmpi(pname, "an ", 3) ||
2041             !strncmpi(pname, "a ", 2)) {
2042             /*[ does this need a plural check too? ]*/
2043             kprefix = KILLED_BY;
2044         }
2045         i = rn2(fatal + 20*thrown_weapon);
2046         if(i == 0 && typ != A_CHA) {
2047                 u.uhp = -1;
2048                 pline_The("poison was deadly...");
2049         } else if(i <= 5) {
2050                 /* Check that a stat change was made */
2051                 if (adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), 1))
2052                     pline("You%s!", poiseff[typ]);
2053         } else {
2054                 i = thrown_weapon ? rnd(6) : rn1(10,6);
2055                 if(Half_physical_damage) i = (i+1) / 2;
2056                 losehp(i, pname, kprefix);
2057         }
2058         if(u.uhp < 1) {
2059                 killer_format = kprefix;
2060                 killer = pname;
2061                 /* "Poisoned by a poisoned ___" is redundant */
2062                 done(strstri(pname, "poison") ? DIED : POISONING);
2063         }
2064         (void) encumber_msg();
2065 }
2066
2067 /* monster responds to player action; not the same as a passive attack */
2068 /* assumes reason for response has been tested, and response _must_ be made */
2069 void
2070 m_respond(mtmp)
2071 register struct monst *mtmp;
2072 {
2073     if(mtmp->data->msound == MS_SHRIEK) {
2074         if(flags.soundok) {
2075             pline("%s shrieks.", Monnam(mtmp));
2076             stop_occupation();
2077         }
2078         if (!rn2(10)) {
2079             if (!rn2(13))
2080                 (void) makemon(&mons[PM_PURPLE_WORM], 0, 0, NO_MM_FLAGS);
2081             else
2082                 (void) makemon((struct permonst *)0, 0, 0, NO_MM_FLAGS);
2083
2084         }
2085         aggravate();
2086     }
2087     if(mtmp->data == &mons[PM_MEDUSA]) {
2088         register int i;
2089         for(i = 0; i < NATTK; i++)
2090              if(mtmp->data->mattk[i].aatyp == AT_GAZE) {
2091                  (void) gazemu(mtmp, &mtmp->data->mattk[i]);
2092                  break;
2093              }
2094     }
2095 }
2096
2097 #endif /* OVLB */
2098 #ifdef OVL2
2099
2100 void
2101 setmangry(mtmp)
2102 register struct monst *mtmp;
2103 {
2104         mtmp->mstrategy &= ~STRAT_WAITMASK;
2105         if(!mtmp->mpeaceful) return;
2106         if(mtmp->mtame) return;
2107         mtmp->mpeaceful = 0;
2108         if(mtmp->ispriest) {
2109                 if(p_coaligned(mtmp)) adjalign(-5); /* very bad */
2110                 else adjalign(2);
2111         } else
2112                 adjalign(-1);           /* attacking peaceful monsters is bad */
2113         if (couldsee(mtmp->mx, mtmp->my)) {
2114                 if (humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd)
2115                     pline("%s gets angry!", Monnam(mtmp));
2116                 else if (flags.verbose && flags.soundok) growl(mtmp);
2117         }
2118
2119         /* attacking your own quest leader will anger his or her guardians */
2120         if (!flags.mon_moving &&        /* should always be the case here */
2121                 mtmp->data == &mons[quest_info(MS_LEADER)]) {
2122             struct monst *mon;
2123             struct permonst *q_guardian = &mons[quest_info(MS_GUARDIAN)];
2124             int got_mad = 0;
2125
2126             /* guardians will sense this attack even if they can't see it */
2127             for (mon = fmon; mon; mon = mon->nmon)
2128                 if (!DEADMONSTER(mon) && mon->data == q_guardian && mon->mpeaceful) {
2129                     mon->mpeaceful = 0;
2130                     if (canseemon(mon)) ++got_mad;
2131                 }
2132             if (got_mad && !Hallucination)
2133                 pline_The("%s appear%s to be angry too...",
2134                       got_mad == 1 ? q_guardian->mname :
2135                                     makeplural(q_guardian->mname),
2136                       got_mad == 1 ? "s" : "");
2137         }
2138 }
2139
2140 void
2141 wakeup(mtmp)
2142 register struct monst *mtmp;
2143 {
2144         mtmp->msleeping = 0;
2145         mtmp->meating = 0;      /* assume there's no salvagable food left */
2146         setmangry(mtmp);
2147         if(mtmp->m_ap_type) seemimic(mtmp);
2148         else if (flags.forcefight && !flags.mon_moving && mtmp->mundetected) {
2149             mtmp->mundetected = 0;
2150             newsym(mtmp->mx, mtmp->my);
2151         }
2152 }
2153
2154 /* Wake up nearby monsters. */
2155 void
2156 wake_nearby()
2157 {
2158         register struct monst *mtmp;
2159
2160         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2161             if (!DEADMONSTER(mtmp) && distu(mtmp->mx,mtmp->my) < u.ulevel*20) {
2162                 mtmp->msleeping = 0;
2163                 if (mtmp->mtame && !mtmp->isminion)
2164                     EDOG(mtmp)->whistletime = moves;
2165             }
2166         }
2167 }
2168
2169 /* Wake up monsters near some particular location. */
2170 void
2171 wake_nearto(x, y, distance)
2172 register int x, y, distance;
2173 {
2174         register struct monst *mtmp;
2175
2176         for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2177             if (!DEADMONSTER(mtmp) && mtmp->msleeping && (distance == 0 ||
2178                                  dist2(mtmp->mx, mtmp->my, x, y) < distance))
2179                 mtmp->msleeping = 0;
2180         }
2181 }
2182
2183 /* NOTE: we must check for mimicry before calling this routine */
2184 void
2185 seemimic(mtmp)
2186 register struct monst *mtmp;
2187 {
2188         unsigned old_app = mtmp->mappearance;
2189         uchar old_ap_type = mtmp->m_ap_type;
2190
2191         mtmp->m_ap_type = M_AP_NOTHING;
2192         mtmp->mappearance = 0;
2193
2194         /*
2195          *  Discovered mimics don't block light.
2196          */
2197         if (((old_ap_type == M_AP_FURNITURE &&
2198               (old_app == S_hcdoor || old_app == S_vcdoor)) ||
2199              (old_ap_type == M_AP_OBJECT && old_app == BOULDER)) &&
2200             !does_block(mtmp->mx, mtmp->my, &levl[mtmp->mx][mtmp->my]))
2201             unblock_point(mtmp->mx, mtmp->my);
2202
2203         newsym(mtmp->mx,mtmp->my);
2204 }
2205
2206 /* force all chameleons to become normal */
2207 void
2208 rescham()
2209 {
2210         register struct monst *mtmp;
2211         int mcham;
2212
2213         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2214                 if (DEADMONSTER(mtmp)) continue;
2215                 mcham = (int) mtmp->cham;
2216                 if (mcham) {
2217                         mtmp->cham = CHAM_ORDINARY;
2218                         (void) newcham(mtmp, &mons[cham_to_pm[mcham]],
2219                                        FALSE, FALSE);
2220                 }
2221                 if(is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN)
2222                         new_were(mtmp);
2223                 if(mtmp->m_ap_type && cansee(mtmp->mx, mtmp->my)) {
2224                         seemimic(mtmp);
2225                         /* we pretend that the mimic doesn't */
2226                         /* know that it has been unmasked.   */
2227                         mtmp->msleeping = 1;
2228                 }
2229         }
2230 }
2231
2232 /* Let the chameleons change again -dgk */
2233 void
2234 restartcham()
2235 {
2236         register struct monst *mtmp;
2237
2238         for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2239                 if (DEADMONSTER(mtmp)) continue;
2240                 mtmp->cham = pm_to_cham(monsndx(mtmp->data));
2241                 if (mtmp->data->mlet == S_MIMIC && mtmp->msleeping &&
2242                                 cansee(mtmp->mx, mtmp->my)) {
2243                         set_mimic_sym(mtmp);
2244                         newsym(mtmp->mx,mtmp->my);
2245                 }
2246         }
2247 }
2248
2249 /* called when restoring a monster from a saved level; protection
2250    against shape-changing might be different now than it was at the
2251    time the level was saved. */
2252 void
2253 restore_cham(mon)
2254 struct monst *mon;
2255 {
2256         int mcham;
2257
2258         if (Protection_from_shape_changers) {
2259             mcham = (int) mon->cham;
2260             if (mcham) {
2261                 mon->cham = CHAM_ORDINARY;
2262                 (void) newcham(mon, &mons[cham_to_pm[mcham]], FALSE, FALSE);
2263             } else if (is_were(mon->data) && !is_human(mon->data)) {
2264                 new_were(mon);
2265             }
2266         } else if (mon->cham == CHAM_ORDINARY) {
2267             mon->cham = pm_to_cham(monsndx(mon->data));
2268         }
2269 }
2270
2271 /* unwatched hiders may hide again; if so, a 1 is returned.  */
2272 STATIC_OVL boolean
2273 restrap(mtmp)
2274 register struct monst *mtmp;
2275 {
2276         if(mtmp->cham || mtmp->mcan || mtmp->m_ap_type ||
2277            cansee(mtmp->mx, mtmp->my) || rn2(3) || (mtmp == u.ustuck) ||
2278            (sensemon(mtmp) && distu(mtmp->mx, mtmp->my) <= 2))
2279                 return(FALSE);
2280
2281         if(mtmp->data->mlet == S_MIMIC) {
2282                 set_mimic_sym(mtmp);
2283                 return(TRUE);
2284         } else
2285             if(levl[mtmp->mx][mtmp->my].typ == ROOM)  {
2286                 mtmp->mundetected = 1;
2287                 return(TRUE);
2288             }
2289
2290         return(FALSE);
2291 }
2292
2293 short *animal_list = 0;         /* list of PM values for animal monsters */
2294 int animal_list_count;
2295
2296 void
2297 mon_animal_list(construct)
2298 boolean construct;
2299 {
2300         if (construct) {
2301             short animal_temp[SPECIAL_PM];
2302             int i, n;
2303
2304          /* if (animal_list) impossible("animal_list already exists"); */
2305
2306             for (n = 0, i = LOW_PM; i < SPECIAL_PM; i++)
2307                 if (is_animal(&mons[i])) animal_temp[n++] = i;
2308          /* if (n == 0) animal_temp[n++] = NON_PM; */
2309
2310             animal_list = (short *)alloc(n * sizeof *animal_list);
2311             (void) memcpy((genericptr_t)animal_list,
2312                           (genericptr_t)animal_temp,
2313                           n * sizeof *animal_list);
2314             animal_list_count = n;
2315         } else {        /* release */
2316             if (animal_list) free((genericptr_t)animal_list), animal_list = 0;
2317             animal_list_count = 0;
2318         }
2319 }
2320
2321 STATIC_OVL int
2322 pick_animal()
2323 {
2324         if (!animal_list) mon_animal_list(TRUE);
2325
2326         return animal_list[rn2(animal_list_count)];
2327 }
2328
2329 STATIC_OVL int
2330 select_newcham_form(mon)
2331 struct monst *mon;
2332 {
2333         int mndx = NON_PM;
2334
2335         switch (mon->cham) {
2336             case CHAM_SANDESTIN:
2337                 if (rn2(7)) mndx = pick_nasty();
2338                 break;
2339             case CHAM_DOPPELGANGER:
2340                 if (!rn2(7)) mndx = pick_nasty();
2341                 else if (rn2(3)) mndx = rn1(PM_WIZARD - PM_ARCHEOLOGIST + 1,
2342                                             PM_ARCHEOLOGIST);
2343                 break;
2344             case CHAM_CHAMELEON:
2345                 if (!rn2(3)) mndx = pick_animal();
2346                 break;
2347             case CHAM_ORDINARY:
2348               {
2349                 struct obj *m_armr = which_armor(mon, W_ARM);
2350
2351                 if (m_armr && Is_dragon_scales(m_armr))
2352                     mndx = Dragon_scales_to_pm(m_armr) - mons;
2353                 else if (m_armr && Is_dragon_mail(m_armr))
2354                     mndx = Dragon_mail_to_pm(m_armr) - mons;
2355               }
2356                 break;
2357         }
2358 #ifdef WIZARD
2359         /* For debugging only: allow control of polymorphed monster; not saved */
2360         if (wizard && iflags.mon_polycontrol) {
2361                 char pprompt[BUFSZ], buf[BUFSZ];
2362                 int tries = 0;
2363                 do {
2364                         Sprintf(pprompt,
2365                                 "Change %s into what kind of monster? [type the name]",
2366                                 mon_nam(mon));
2367                         getlin(pprompt,buf);
2368                         mndx = name_to_mon(buf);
2369                         if (mndx < LOW_PM)
2370                                 You("cannot polymorph %s into that.", mon_nam(mon));
2371                         else break;
2372                 } while(++tries < 5);
2373                 if (tries==5) pline(thats_enough_tries);
2374         }
2375 #endif /*WIZARD*/
2376         if (mndx == NON_PM) mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
2377         return mndx;
2378 }
2379
2380 /* make a chameleon look like a new monster; returns 1 if it actually changed */
2381 int
2382 newcham(mtmp, mdat, polyspot, msg)
2383 struct monst *mtmp;
2384 struct permonst *mdat;
2385 boolean polyspot;       /* change is the result of wand or spell of polymorph */
2386 boolean msg;            /* "The oldmon turns into a newmon!" */
2387 {
2388         int mhp, hpn, hpd;
2389         int mndx, tryct;
2390         struct permonst *olddata = mtmp->data;
2391         char oldname[BUFSZ];
2392
2393         if (msg) {
2394             /* like Monnam() but never mention saddle */
2395             Strcpy(oldname, x_monnam(mtmp, ARTICLE_THE, (char *)0,
2396                                      SUPPRESS_SADDLE, FALSE));
2397             oldname[0] = highc(oldname[0]);
2398         }
2399
2400         /* mdat = 0 -> caller wants a random monster shape */
2401         tryct = 0;
2402         if (mdat == 0) {
2403             while (++tryct <= 100) {
2404                 mndx = select_newcham_form(mtmp);
2405                 mdat = &mons[mndx];
2406                 if ((mvitals[mndx].mvflags & G_GENOD) != 0 ||
2407                         is_placeholder(mdat)) continue;
2408                 /* polyok rules out all M2_PNAME and M2_WERE's;
2409                    select_newcham_form might deliberately pick a player
2410                    character type, so we can't arbitrarily rule out all
2411                    human forms any more */
2412                 if (is_mplayer(mdat) || (!is_human(mdat) && polyok(mdat)))
2413                     break;
2414             }
2415             if (tryct > 100) return 0;  /* Should never happen */
2416         } else if (mvitals[monsndx(mdat)].mvflags & G_GENOD)
2417             return(0);  /* passed in mdat is genocided */
2418
2419         if(is_male(mdat)) {
2420                 if(mtmp->female) mtmp->female = FALSE;
2421         } else if (is_female(mdat)) {
2422                 if(!mtmp->female) mtmp->female = TRUE;
2423         } else if (!is_neuter(mdat)) {
2424                 if(!rn2(10)) mtmp->female = !mtmp->female;
2425         }
2426
2427         if (In_endgame(&u.uz) && is_mplayer(olddata)) {
2428                 /* mplayers start out as "Foo the Bar", but some of the
2429                  * titles are inappropriate when polymorphed, particularly
2430                  * into the opposite sex.  players don't use ranks when
2431                  * polymorphed, so dropping the rank for mplayers seems
2432                  * reasonable.
2433                  */
2434                 char *p = index(NAME(mtmp), ' ');
2435                 if (p) {
2436                         *p = '\0';
2437                         mtmp->mnamelth = p - NAME(mtmp) + 1;
2438                 }
2439         }
2440
2441         if(mdat == mtmp->data) return(0);       /* still the same monster */
2442
2443         if(mtmp->wormno) {                      /* throw tail away */
2444                 wormgone(mtmp);
2445                 place_monster(mtmp, mtmp->mx, mtmp->my);
2446         }
2447
2448         hpn = mtmp->mhp;
2449         hpd = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel;
2450         if(!hpd) hpd = 4;
2451
2452         mtmp->m_lev = adj_lev(mdat);            /* new monster level */
2453
2454         mhp = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel;
2455         if(!mhp) mhp = 4;
2456
2457         /* new hp: same fraction of max as before */
2458 #ifndef LINT
2459         mtmp->mhp = (int)(((long)hpn*(long)mhp)/(long)hpd);
2460 #endif
2461         if(mtmp->mhp < 0) mtmp->mhp = hpn;      /* overflow */
2462 /* Unlikely but not impossible; a 1HD creature with 1HP that changes into a
2463    0HD creature will require this statement */
2464         if (!mtmp->mhp) mtmp->mhp = 1;
2465
2466 /* and the same for maximum hit points */
2467         hpn = mtmp->mhpmax;
2468 #ifndef LINT
2469         mtmp->mhpmax = (int)(((long)hpn*(long)mhp)/(long)hpd);
2470 #endif
2471         if(mtmp->mhpmax < 0) mtmp->mhpmax = hpn;        /* overflow */
2472         if (!mtmp->mhpmax) mtmp->mhpmax = 1;
2473
2474         /* take on the new form... */
2475         set_mon_data(mtmp, mdat, 0);
2476
2477         if (emits_light(olddata) != emits_light(mtmp->data)) {
2478             /* used to give light, now doesn't, or vice versa,
2479                or light's range has changed */
2480             if (emits_light(olddata))
2481                 del_light_source(LS_MONSTER, (genericptr_t)mtmp);
2482             if (emits_light(mtmp->data))
2483                 new_light_source(mtmp->mx, mtmp->my, emits_light(mtmp->data),
2484                                  LS_MONSTER, (genericptr_t)mtmp);
2485         }
2486         if (!mtmp->perminvis || pm_invisible(olddata))
2487             mtmp->perminvis = pm_invisible(mdat);
2488         mtmp->minvis = mtmp->invis_blkd ? 0 : mtmp->perminvis;
2489         if (!(hides_under(mdat) && OBJ_AT(mtmp->mx, mtmp->my)) &&
2490                         !(mdat->mlet == S_EEL && is_pool(mtmp->mx, mtmp->my)))
2491                 mtmp->mundetected = 0;
2492         if (u.ustuck == mtmp) {
2493                 if(u.uswallow) {
2494                         if(!attacktype(mdat,AT_ENGL)) {
2495                                 /* Does mdat care? */
2496                                 if (!noncorporeal(mdat) && !amorphous(mdat) &&
2497                                     !is_whirly(mdat) &&
2498                                     (mdat != &mons[PM_YELLOW_LIGHT])) {
2499                                         You("break out of %s%s!", mon_nam(mtmp),
2500                                             (is_animal(mdat)?
2501                                             "'s stomach" : ""));
2502                                         mtmp->mhp = 1;  /* almost dead */
2503                                 }
2504                                 expels(mtmp, olddata, FALSE);
2505                         } else {
2506                                 /* update swallow glyphs for new monster */
2507                                 swallowed(0);
2508                         }
2509                 } else if (!sticks(mdat) && !sticks(youmonst.data))
2510                         unstuck(mtmp);
2511         }
2512
2513 #ifndef DCC30_BUG
2514         if (mdat == &mons[PM_LONG_WORM] && (mtmp->wormno = get_wormno()) != 0) {
2515 #else
2516         /* DICE 3.0 doesn't like assigning and comparing mtmp->wormno in the
2517          * same expression.
2518          */
2519         if (mdat == &mons[PM_LONG_WORM] &&
2520                 (mtmp->wormno = get_wormno(), mtmp->wormno != 0)) {
2521 #endif
2522             /* we can now create worms with tails - 11/91 */
2523             initworm(mtmp, rn2(5));
2524             if (count_wsegs(mtmp))
2525                 place_worm_tail_randomly(mtmp, mtmp->mx, mtmp->my);
2526         }
2527
2528         newsym(mtmp->mx,mtmp->my);
2529
2530         if (msg) {
2531             uchar save_mnamelth = mtmp->mnamelth;
2532             mtmp->mnamelth = 0;
2533             pline("%s turns into %s!", oldname,
2534                   mdat == &mons[PM_GREEN_SLIME] ? "slime" :
2535                   x_monnam(mtmp, ARTICLE_A, (char*)0, SUPPRESS_SADDLE, FALSE));
2536             mtmp->mnamelth = save_mnamelth;
2537         }
2538
2539         possibly_unwield(mtmp, polyspot);       /* might lose use of weapon */
2540         mon_break_armor(mtmp, polyspot);
2541         if (!(mtmp->misc_worn_check & W_ARMG))
2542             mselftouch(mtmp, "No longer petrify-resistant, ",
2543                         !flags.mon_moving);
2544         m_dowear(mtmp, FALSE);
2545
2546         /* This ought to re-test can_carry() on each item in the inventory
2547          * rather than just checking ex-giants & boulders, but that'd be
2548          * pretty expensive to perform.  If implemented, then perhaps
2549          * minvent should be sorted in order to drop heaviest items first.
2550          */
2551         /* former giants can't continue carrying boulders */
2552         if (mtmp->minvent && !throws_rocks(mdat)) {
2553             register struct obj *otmp, *otmp2;
2554
2555             for (otmp = mtmp->minvent; otmp; otmp = otmp2) {
2556                 otmp2 = otmp->nobj;
2557                 if (otmp->otyp == BOULDER) {
2558                     /* this keeps otmp from being polymorphed in the
2559                        same zap that the monster that held it is polymorphed */
2560                     if (polyspot) bypass_obj(otmp);
2561                     obj_extract_self(otmp);
2562                     /* probably ought to give some "drop" message here */
2563                     if (flooreffects(otmp, mtmp->mx, mtmp->my, "")) continue;
2564                     place_object(otmp, mtmp->mx, mtmp->my);
2565                 }
2566             }
2567         }
2568
2569         return(1);
2570 }
2571
2572 /* sometimes an egg will be special */
2573 #define BREEDER_EGG (!rn2(77))
2574
2575 /*
2576  * Determine if the given monster number can be hatched from an egg.
2577  * Return the monster number to use as the egg's corpsenm.  Return
2578  * NON_PM if the given monster can't be hatched.
2579  */
2580 int
2581 can_be_hatched(mnum)
2582 int mnum;
2583 {
2584     /* ranger quest nemesis has the oviparous bit set, making it
2585        be possible to wish for eggs of that unique monster; turn
2586        such into ordinary eggs rather than forbidding them outright */
2587     if (mnum == PM_SCORPIUS) mnum = PM_SCORPION;
2588
2589     mnum = little_to_big(mnum);
2590     /*
2591      * Queen bees lay killer bee eggs (usually), but killer bees don't
2592      * grow into queen bees.  Ditto for [winged-]gargoyles.
2593      */
2594     if (mnum == PM_KILLER_BEE || mnum == PM_GARGOYLE ||
2595             (lays_eggs(&mons[mnum]) && (BREEDER_EGG ||
2596                 (mnum != PM_QUEEN_BEE && mnum != PM_WINGED_GARGOYLE))))
2597         return mnum;
2598     return NON_PM;
2599 }
2600
2601 /* type of egg laid by #sit; usually matches parent */
2602 int
2603 egg_type_from_parent(mnum, force_ordinary)
2604 int mnum;       /* parent monster; caller must handle lays_eggs() check */
2605 boolean force_ordinary;
2606 {
2607     if (force_ordinary || !BREEDER_EGG) {
2608         if (mnum == PM_QUEEN_BEE) mnum = PM_KILLER_BEE;
2609         else if (mnum == PM_WINGED_GARGOYLE) mnum = PM_GARGOYLE;
2610     }
2611     return mnum;
2612 }
2613
2614 /* decide whether an egg of the indicated monster type is viable; */
2615 /* also used to determine whether an egg or tin can be created... */
2616 boolean
2617 dead_species(m_idx, egg)
2618 int m_idx;
2619 boolean egg;
2620 {
2621         /*
2622          * For monsters with both baby and adult forms, genociding either
2623          * form kills all eggs of that monster.  Monsters with more than
2624          * two forms (small->large->giant mimics) are more or less ignored;
2625          * fortunately, none of them have eggs.  Species extinction due to
2626          * overpopulation does not kill eggs.
2627          */
2628         return (boolean)
2629                 (m_idx >= LOW_PM &&
2630                  ((mvitals[m_idx].mvflags & G_GENOD) != 0 ||
2631                   (egg &&
2632                    (mvitals[big_to_little(m_idx)].mvflags & G_GENOD) != 0)));
2633 }
2634
2635 /* kill off any eggs of genocided monsters */
2636 STATIC_OVL void
2637 kill_eggs(obj_list)
2638 struct obj *obj_list;
2639 {
2640         struct obj *otmp;
2641
2642         for (otmp = obj_list; otmp; otmp = otmp->nobj)
2643             if (otmp->otyp == EGG) {
2644                 if (dead_species(otmp->corpsenm, TRUE)) {
2645                     /*
2646                      * It seems we could also just catch this when
2647                      * it attempted to hatch, so we wouldn't have to
2648                      * search all of the objlists.. or stop all
2649                      * hatch timers based on a corpsenm.
2650                      */
2651                     kill_egg(otmp);
2652                 }
2653 #if 0   /* not used */
2654             } else if (otmp->otyp == TIN) {
2655                 if (dead_species(otmp->corpsenm, FALSE))
2656                     otmp->corpsenm = NON_PM;    /* empty tin */
2657             } else if (otmp->otyp == CORPSE) {
2658                 if (dead_species(otmp->corpsenm, FALSE))
2659                     ;           /* not yet implemented... */
2660 #endif
2661             } else if (Has_contents(otmp)) {
2662                 kill_eggs(otmp->cobj);
2663             }
2664 }
2665
2666 /* kill all members of genocided species */
2667 void
2668 kill_genocided_monsters()
2669 {
2670         struct monst *mtmp, *mtmp2;
2671         boolean kill_cham[CHAM_MAX_INDX+1];
2672         int mndx;
2673
2674         kill_cham[CHAM_ORDINARY] = FALSE;       /* (this is mndx==0) */
2675         for (mndx = 1; mndx <= CHAM_MAX_INDX; mndx++)
2676           kill_cham[mndx] = (mvitals[cham_to_pm[mndx]].mvflags & G_GENOD) != 0;
2677         /*
2678          * Called during genocide, and again upon level change.  The latter
2679          * catches up with any migrating monsters as they finally arrive at
2680          * their intended destinations, so possessions get deposited there.
2681          *
2682          * Chameleon handling:
2683          *      1) if chameleons have been genocided, destroy them
2684          *         regardless of current form;
2685          *      2) otherwise, force every chameleon which is imitating
2686          *         any genocided species to take on a new form.
2687          */
2688         for (mtmp = fmon; mtmp; mtmp = mtmp2) {
2689             mtmp2 = mtmp->nmon;
2690             if (DEADMONSTER(mtmp)) continue;
2691             mndx = monsndx(mtmp->data);
2692             if ((mvitals[mndx].mvflags & G_GENOD) || kill_cham[mtmp->cham]) {
2693                 if (mtmp->cham && !kill_cham[mtmp->cham])
2694                     (void) newcham(mtmp, (struct permonst *)0, FALSE, FALSE);
2695                 else
2696                     mondead(mtmp);
2697             }
2698             if (mtmp->minvent) kill_eggs(mtmp->minvent);
2699         }
2700
2701         kill_eggs(invent);
2702         kill_eggs(fobj);
2703         kill_eggs(level.buriedobjlist);
2704 }
2705
2706 #endif /* OVL2 */
2707 #ifdef OVLB
2708
2709 void
2710 golemeffects(mon, damtype, dam)
2711 register struct monst *mon;
2712 int damtype, dam;
2713 {
2714     int heal = 0, slow = 0;
2715
2716     if (mon->data == &mons[PM_FLESH_GOLEM]) {
2717         if (damtype == AD_ELEC) heal = dam / 6;
2718         else if (damtype == AD_FIRE || damtype == AD_COLD) slow = 1;
2719     } else if (mon->data == &mons[PM_IRON_GOLEM]) {
2720         if (damtype == AD_ELEC) slow = 1;
2721         else if (damtype == AD_FIRE) heal = dam;
2722     } else {
2723         return;
2724     }
2725     if (slow) {
2726         if (mon->mspeed != MSLOW)
2727             mon_adjust_speed(mon, -1, (struct obj *)0);
2728     }
2729     if (heal) {
2730         if (mon->mhp < mon->mhpmax) {
2731             mon->mhp += dam;
2732             if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax;
2733             if (cansee(mon->mx, mon->my))
2734                 pline("%s seems healthier.", Monnam(mon));
2735         }
2736     }
2737 }
2738
2739 boolean
2740 angry_guards(silent)
2741 register boolean silent;
2742 {
2743         register struct monst *mtmp;
2744         register int ct = 0, nct = 0, sct = 0, slct = 0;
2745
2746         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2747                 if (DEADMONSTER(mtmp)) continue;
2748                 if((mtmp->data == &mons[PM_WATCHMAN] ||
2749                                mtmp->data == &mons[PM_WATCH_CAPTAIN])
2750                                         && mtmp->mpeaceful) {
2751                         ct++;
2752                         if(cansee(mtmp->mx, mtmp->my) && mtmp->mcanmove) {
2753                                 if (distu(mtmp->mx, mtmp->my) == 2) nct++;
2754                                 else sct++;
2755                         }
2756                         if (mtmp->msleeping || mtmp->mfrozen) {
2757                                 slct++;
2758                                 mtmp->msleeping = mtmp->mfrozen = 0;
2759                         }
2760                         mtmp->mpeaceful = 0;
2761                 }
2762         }
2763         if(ct) {
2764             if(!silent) { /* do we want pline msgs? */
2765                 if(slct) pline_The("guard%s wake%s up!",
2766                                  slct > 1 ? "s" : "", slct == 1 ? "s" : "");
2767                 if(nct || sct) {
2768                         if(nct) pline_The("guard%s get%s angry!",
2769                                 nct == 1 ? "" : "s", nct == 1 ? "s" : "");
2770                         else if(!Blind)
2771                                 You("see %sangry guard%s approaching!",
2772                                   sct == 1 ? "an " : "", sct > 1 ? "s" : "");
2773                 } else if(flags.soundok)
2774                         You_hear("the shrill sound of a guard's whistle.");
2775             }
2776             return(TRUE);
2777         }
2778         return(FALSE);
2779 }
2780
2781 void
2782 pacify_guards()
2783 {
2784         register struct monst *mtmp;
2785
2786         for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2787             if (DEADMONSTER(mtmp)) continue;
2788             if (mtmp->data == &mons[PM_WATCHMAN] ||
2789                 mtmp->data == &mons[PM_WATCH_CAPTAIN])
2790             mtmp->mpeaceful = 1;
2791         }
2792 }
2793
2794 void
2795 mimic_hit_msg(mtmp, otyp)
2796 struct monst *mtmp;
2797 short otyp;
2798 {
2799         short ap = mtmp->mappearance;
2800
2801         switch(mtmp->m_ap_type) {
2802             case M_AP_NOTHING:                  
2803             case M_AP_FURNITURE:
2804             case M_AP_MONSTER:
2805                 break;
2806             case M_AP_OBJECT:
2807                 if (otyp == SPE_HEALING || otyp == SPE_EXTRA_HEALING) {
2808                     pline("%s seems a more vivid %s than before.",
2809                                 The(simple_typename(ap)),
2810                                 c_obj_colors[objects[ap].oc_color]);
2811                 }
2812                 break;
2813         }
2814 }
2815 #endif /* OVLB */
2816
2817 /*mon.c*/