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