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
15STATIC_DCL boolean FDECL(restrap,(struct monst *));
16STATIC_DCL long FDECL(mm_aggression, (struct monst *,struct monst *));
17#ifdef OVL2
18STATIC_DCL int NDECL(pick_animal);
19STATIC_DCL int FDECL(select_newcham_form, (struct monst *));
20STATIC_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
37long lastwarntime;
38int lastwarnlev;
39
40const char *warnings[] = {
41	"white", "pink", "red", "ruby", "purple", "black"
42};
43
44STATIC_DCL void NDECL(warn_effects);
45#endif /* OVL1 */
46#endif /* 0 */
47
48#ifndef OVLB
49STATIC_VAR short cham_to_pm[];
50#else
51STATIC_DCL struct obj *FDECL(make_corpse,(struct monst *));
52STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *));
53STATIC_DCL void FDECL(lifesaved_monster, (struct monst *));
54
55/* convert the monster index of an undead to its living counterpart */
56int
57undead_to_corpse(mndx)
58int 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 */
93int
94genus(mndx, mode)
95int 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 */
129int
130pm_to_cham(mndx)
131int 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 */
145STATIC_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 */
168STATIC_OVL struct obj *
169make_corpse(mtmp)
170register 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 */
330STATIC_OVL void
331warn_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) */
380int
381minliquid(mtmp)
382register 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
488int
489mcalcmove(mon)
490struct 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 */
518void
519mcalcdistress()
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
553int
554movemon()
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 */
660int
661meatmetal(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
749int
750meatobj(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
839void
840mpickgold(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
866boolean
867mpickstuff(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
912int
913curr_mon_load(mtmp)
914register 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
927int
928max_mon_load(mtmp)
929register 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 */
956boolean
957can_carry(mtmp,otmp)
958struct monst *mtmp;
959struct 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 */
999int
1000mfndpos(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
1046nexttry:	/* 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)  {
1162impossible("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. */
1215STATIC_OVL long
1216mm_aggression(magr, mdef)
1217struct 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
1231boolean
1232monnear(mon, x, y)
1233register struct monst *mon;
1234register 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 */
1243void
1244dmonsfree()
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 */
1269void
1270replmon(mtmp, mtmp2)
1271register 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 NETHACK_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 */
1316void
1317relmon(mon)
1318register 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 */
1335STATIC_OVL void
1336m_detach(mtmp, mptr)
1337struct monst *mtmp;
1338struct 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 */
1358struct obj *
1359mlifesaver(mon)
1360struct 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
1371STATIC_OVL void
1372lifesaved_monster(mtmp)
1373struct 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
1412void
1413mondead(mtmp)
1414register 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 */
1490boolean
1491corpse_chance(mon, magr, was_swallowed)
1492struct monst *mon;
1493struct monst *magr;			/* killer, if swallowed */
1494boolean 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 */
1561void
1562mondied(mdef)
1563register 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 */
1574void
1575mongone(mdef)
1576register 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 */
1597void
1598monstone(mdef)
1599register 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 */
1683void
1684monkilled(mdef, fltxt, how)
1685register struct monst *mdef;
1686const char *fltxt;
1687int 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
1711void
1712unstuck(mtmp)
1713register 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
1729void
1730killed(mtmp)
1731register struct monst *mtmp;
1732{
1733	xkilled(mtmp, 1);
1734}
1735
1736/* the player has killed the monster mtmp */
1737void
1738xkilled(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);
1854cleanup:
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 */
1908void
1909mon_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
1927void
1928mnexto(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 */
1953boolean
1954mnearto(mtmp,x,y,move_other)
1955register struct monst *mtmp;
1956xchar x, y;
1957boolean 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
1997static 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
2004void
2005poisontell(typ)
2006
2007	int	typ;
2008{
2009	pline("You%s.", poiseff[typ]);
2010}
2011
2012void
2013poisoned(string, typ, pname, fatal)
2014const char *string, *pname;
2015int  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 */
2069void
2070m_respond(mtmp)
2071register 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
2100void
2101setmangry(mtmp)
2102register 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
2140void
2141wakeup(mtmp)
2142register 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. */
2155void
2156wake_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. */
2170void
2171wake_nearto(x, y, distance)
2172register 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 */
2184void
2185seemimic(mtmp)
2186register 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 */
2207void
2208rescham()
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 */
2233void
2234restartcham()
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. */
2252void
2253restore_cham(mon)
2254struct 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.  */
2272STATIC_OVL boolean
2273restrap(mtmp)
2274register 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
2293short *animal_list = 0;		/* list of PM values for animal monsters */
2294int animal_list_count;
2295
2296void
2297mon_animal_list(construct)
2298boolean 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
2321STATIC_OVL int
2322pick_animal()
2323{
2324	if (!animal_list) mon_animal_list(TRUE);
2325
2326	return animal_list[rn2(animal_list_count)];
2327}
2328
2329STATIC_OVL int
2330select_newcham_form(mon)
2331struct 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 */
2381int
2382newcham(mtmp, mdat, polyspot, msg)
2383struct monst *mtmp;
2384struct permonst *mdat;
2385boolean polyspot;	/* change is the result of wand or spell of polymorph */
2386boolean 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 */
2580int
2581can_be_hatched(mnum)
2582int 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 */
2602int
2603egg_type_from_parent(mnum, force_ordinary)
2604int mnum;	/* parent monster; caller must handle lays_eggs() check */
2605boolean 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... */
2616boolean
2617dead_species(m_idx, egg)
2618int m_idx;
2619boolean 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 */
2636STATIC_OVL void
2637kill_eggs(obj_list)
2638struct 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 */
2667void
2668kill_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
2709void
2710golemeffects(mon, damtype, dam)
2711register struct monst *mon;
2712int 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
2739boolean
2740angry_guards(silent)
2741register 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
2781void
2782pacify_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
2794void
2795mimic_hit_msg(mtmp, otyp)
2796struct monst *mtmp;
2797short 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*/
2818