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