mplayer.c formatting
[aNetHack.git] / src / mon.c
blobb0eec652ef7f2d99601c7bab70b59be86f44bdb6
1 /* NetHack 3.6 mon.c $NHDT-Date: 1454528962 2016/02/03 19:49:22 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.210 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* If you're using precompiled headers, you don't want this either */
6 #ifdef MICROPORT_BUG
7 #define MKROOM_H
8 #endif
10 #include "hack.h"
11 #include "mfndpos.h"
12 #include <ctype.h>
14 STATIC_VAR boolean vamp_rise_msg;
16 STATIC_DCL void FDECL(sanity_check_single_mon, (struct monst *, BOOLEAN_P,
17 const char *));
18 STATIC_DCL boolean FDECL(restrap, (struct monst *));
19 STATIC_DCL long FDECL(mm_aggression, (struct monst *, struct monst *));
20 STATIC_DCL long FDECL(mm_displacement, (struct monst *, struct monst *));
21 STATIC_DCL int NDECL(pick_animal);
22 STATIC_DCL void FDECL(kill_eggs, (struct obj *));
23 STATIC_DCL int FDECL(pickvampshape, (struct monst *));
24 STATIC_DCL boolean FDECL(isspecmon, (struct monst *));
25 STATIC_DCL boolean FDECL(validspecmon, (struct monst *, int));
26 STATIC_DCL boolean FDECL(validvamp, (struct monst *, int *, int));
27 STATIC_DCL struct permonst *FDECL(accept_newcham_form, (int));
28 STATIC_DCL struct obj *FDECL(make_corpse, (struct monst *, unsigned));
29 STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *));
30 STATIC_DCL void FDECL(lifesaved_monster, (struct monst *));
32 #define LEVEL_SPECIFIC_NOCORPSE(mdat) \
33 (Is_rogue_level(&u.uz) \
34 || (level.flags.graveyard && is_undead(mdat) && rn2(3)))
36 #if 0
37 /* part of the original warning code which was replaced in 3.3.1 */
38 const char *warnings[] = {
39 "white", "pink", "red", "ruby", "purple", "black"
41 #endif /* 0 */
44 void
45 sanity_check_single_mon(mtmp, chk_geno, msg)
46 struct monst *mtmp;
47 boolean chk_geno;
48 const char *msg;
50 if (DEADMONSTER(mtmp))
51 return;
52 if (mtmp->data < &mons[LOW_PM] || mtmp->data >= &mons[NUMMONS]) {
53 impossible("illegal mon data %s; mnum=%d (%s)",
54 fmt_ptr((genericptr_t) mtmp->data), mtmp->mnum, msg);
55 } else {
56 int mndx = monsndx(mtmp->data);
58 if (mtmp->mnum != mndx) {
59 impossible("monster mnum=%d, monsndx=%d (%s)",
60 mtmp->mnum, mndx, msg);
61 mtmp->mnum = mndx;
63 if (chk_geno && (mvitals[mndx].mvflags & G_GENOD) != 0)
64 impossible("genocided %s in play (%s)", mons[mndx].mname, msg);
66 if (mtmp->isshk && !has_eshk(mtmp))
67 impossible("shk without eshk (%s)", msg);
68 if (mtmp->ispriest && !has_epri(mtmp))
69 impossible("priest without epri (%s)", msg);
70 if (mtmp->isgd && !has_egd(mtmp))
71 impossible("guard without egd (%s)", msg);
72 if (mtmp->isminion && !has_emin(mtmp))
73 impossible("minion without emin (%s)", msg);
74 /* guardian angel on astral level is tame but has emin rather than edog */
75 if (mtmp->mtame && !has_edog(mtmp) && !mtmp->isminion)
76 impossible("pet without edog (%s)", msg);
79 void
80 mon_sanity_check()
82 int x, y;
83 struct monst *mtmp, *m;
85 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
86 sanity_check_single_mon(mtmp, TRUE, "fmon");
87 x = mtmp->mx, y = mtmp->my;
88 if (!isok(x, y) || (x == 0 && !mtmp->isgd))
89 impossible("mon (%s) claims to be at <%d,%d>?",
90 fmt_ptr((genericptr_t) mtmp), x, y);
91 else if (level.monsters[x][y] != mtmp)
92 impossible("mon (%s) at <%d,%d> is not there!",
93 fmt_ptr((genericptr_t) mtmp), x, y);
96 for (x = 0; x < COLNO; x++)
97 for (y = 0; y < ROWNO; y++)
98 if ((mtmp = level.monsters[x][y]) != 0) {
99 for (m = fmon; m; m = m->nmon)
100 if (m == mtmp)
101 break;
102 if (!m)
103 impossible("map mon (%s) at <%d,%d> not in fmon list!",
104 fmt_ptr((genericptr_t) mtmp), x, y);
105 else if ((mtmp->mx != x || mtmp->my != y)
106 && mtmp->data != &mons[PM_LONG_WORM])
107 impossible("map mon (%s) at <%d,%d> is found at <%d,%d>?",
108 fmt_ptr((genericptr_t) mtmp),
109 mtmp->mx, mtmp->my, x, y);
112 for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon) {
113 sanity_check_single_mon(mtmp, FALSE, "migr");
118 /* convert the monster index of an undead to its living counterpart */
120 undead_to_corpse(mndx)
121 int mndx;
123 switch (mndx) {
124 case PM_KOBOLD_ZOMBIE:
125 case PM_KOBOLD_MUMMY:
126 mndx = PM_KOBOLD;
127 break;
128 case PM_DWARF_ZOMBIE:
129 case PM_DWARF_MUMMY:
130 mndx = PM_DWARF;
131 break;
132 case PM_GNOME_ZOMBIE:
133 case PM_GNOME_MUMMY:
134 mndx = PM_GNOME;
135 break;
136 case PM_ORC_ZOMBIE:
137 case PM_ORC_MUMMY:
138 mndx = PM_ORC;
139 break;
140 case PM_ELF_ZOMBIE:
141 case PM_ELF_MUMMY:
142 mndx = PM_ELF;
143 break;
144 case PM_VAMPIRE:
145 case PM_VAMPIRE_LORD:
146 #if 0 /* DEFERRED */
147 case PM_VAMPIRE_MAGE:
148 #endif
149 case PM_HUMAN_ZOMBIE:
150 case PM_HUMAN_MUMMY:
151 mndx = PM_HUMAN;
152 break;
153 case PM_GIANT_ZOMBIE:
154 case PM_GIANT_MUMMY:
155 mndx = PM_GIANT;
156 break;
157 case PM_ETTIN_ZOMBIE:
158 case PM_ETTIN_MUMMY:
159 mndx = PM_ETTIN;
160 break;
161 default:
162 break;
164 return mndx;
167 /* Convert the monster index of some monsters (such as quest guardians)
168 * to their generic species type.
170 * Return associated character class monster, rather than species
171 * if mode is 1.
174 genus(mndx, mode)
175 int mndx, mode;
177 switch (mndx) {
178 /* Quest guardians */
179 case PM_STUDENT:
180 mndx = mode ? PM_ARCHEOLOGIST : PM_HUMAN;
181 break;
182 case PM_CHIEFTAIN:
183 mndx = mode ? PM_BARBARIAN : PM_HUMAN;
184 break;
185 case PM_NEANDERTHAL:
186 mndx = mode ? PM_CAVEMAN : PM_HUMAN;
187 break;
188 case PM_ATTENDANT:
189 mndx = mode ? PM_HEALER : PM_HUMAN;
190 break;
191 case PM_PAGE:
192 mndx = mode ? PM_KNIGHT : PM_HUMAN;
193 break;
194 case PM_ABBOT:
195 mndx = mode ? PM_MONK : PM_HUMAN;
196 break;
197 case PM_ACOLYTE:
198 mndx = mode ? PM_PRIEST : PM_HUMAN;
199 break;
200 case PM_HUNTER:
201 mndx = mode ? PM_RANGER : PM_HUMAN;
202 break;
203 case PM_THUG:
204 mndx = mode ? PM_ROGUE : PM_HUMAN;
205 break;
206 case PM_ROSHI:
207 mndx = mode ? PM_SAMURAI : PM_HUMAN;
208 break;
209 case PM_GUIDE:
210 mndx = mode ? PM_TOURIST : PM_HUMAN;
211 break;
212 case PM_APPRENTICE:
213 mndx = mode ? PM_WIZARD : PM_HUMAN;
214 break;
215 case PM_WARRIOR:
216 mndx = mode ? PM_VALKYRIE : PM_HUMAN;
217 break;
218 default:
219 if (mndx >= LOW_PM && mndx < NUMMONS) {
220 struct permonst *ptr = &mons[mndx];
222 if (is_human(ptr))
223 mndx = PM_HUMAN;
224 else if (is_elf(ptr))
225 mndx = PM_ELF;
226 else if (is_dwarf(ptr))
227 mndx = PM_DWARF;
228 else if (is_gnome(ptr))
229 mndx = PM_GNOME;
230 else if (is_orc(ptr))
231 mndx = PM_ORC;
233 break;
235 return mndx;
238 /* return monster index if chameleon, or NON_PM if not */
240 pm_to_cham(mndx)
241 int mndx;
243 int mcham = NON_PM;
246 * As of 3.6.0 we just check M2_SHAPESHIFTER instead of having a
247 * big switch statement with hardcoded shapeshifter types here.
249 if (mndx >= LOW_PM && is_shapeshifter(&mons[mndx]))
250 mcham = mndx;
251 return mcham;
254 /* for deciding whether corpse will carry along full monster data */
255 #define KEEPTRAITS(mon) \
256 ((mon)->isshk || (mon)->mtame || unique_corpstat((mon)->data) \
257 || is_reviver((mon)->data) \
258 /* normally quest leader will be unique, */ \
259 /* but he or she might have been polymorphed */ \
260 || (mon)->m_id == quest_status.leader_m_id \
261 /* special cancellation handling for these */ \
262 || (dmgtype((mon)->data, AD_SEDU) || dmgtype((mon)->data, AD_SSEX)))
264 /* Creates a monster corpse, a "special" corpse, or nothing if it doesn't
265 * leave corpses. Monsters which leave "special" corpses should have
266 * G_NOCORPSE set in order to prevent wishing for one, finding tins of one,
267 * etc....
269 STATIC_OVL struct obj *
270 make_corpse(mtmp, corpseflags)
271 register struct monst *mtmp;
272 unsigned corpseflags;
274 register struct permonst *mdat = mtmp->data;
275 int num;
276 struct obj *obj = (struct obj *) 0;
277 struct obj *otmp = (struct obj *) 0;
278 int x = mtmp->mx, y = mtmp->my;
279 int mndx = monsndx(mdat);
280 unsigned corpstatflags = corpseflags;
281 boolean burythem = ((corpstatflags & CORPSTAT_BURIED) != 0);
283 switch (mndx) {
284 case PM_GRAY_DRAGON:
285 case PM_SILVER_DRAGON:
286 #if 0 /* DEFERRED */
287 case PM_SHIMMERING_DRAGON:
288 #endif
289 case PM_RED_DRAGON:
290 case PM_ORANGE_DRAGON:
291 case PM_WHITE_DRAGON:
292 case PM_BLACK_DRAGON:
293 case PM_BLUE_DRAGON:
294 case PM_GREEN_DRAGON:
295 case PM_YELLOW_DRAGON:
296 /* Make dragon scales. This assumes that the order of the
297 dragons is the same as the order of the scales. */
298 if (!rn2(mtmp->mrevived ? 20 : 3)) {
299 num = GRAY_DRAGON_SCALES + monsndx(mdat) - PM_GRAY_DRAGON;
300 obj = mksobj_at(num, x, y, FALSE, FALSE);
301 obj->spe = 0;
302 obj->cursed = obj->blessed = FALSE;
304 goto default_1;
305 case PM_WHITE_UNICORN:
306 case PM_GRAY_UNICORN:
307 case PM_BLACK_UNICORN:
308 if (mtmp->mrevived && rn2(2)) {
309 if (canseemon(mtmp))
310 pline("%s recently regrown horn crumbles to dust.",
311 s_suffix(Monnam(mtmp)));
312 } else {
313 obj = mksobj_at(UNICORN_HORN, x, y, TRUE, FALSE);
314 if (obj && mtmp->mrevived)
315 obj->degraded_horn = 1;
317 goto default_1;
318 case PM_LONG_WORM:
319 (void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE);
320 goto default_1;
321 case PM_VAMPIRE:
322 case PM_VAMPIRE_LORD:
323 /* include mtmp in the mkcorpstat() call */
324 num = undead_to_corpse(mndx);
325 corpstatflags |= CORPSTAT_INIT;
326 obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags);
327 obj->age -= 100; /* this is an *OLD* corpse */
328 break;
329 case PM_KOBOLD_MUMMY:
330 case PM_DWARF_MUMMY:
331 case PM_GNOME_MUMMY:
332 case PM_ORC_MUMMY:
333 case PM_ELF_MUMMY:
334 case PM_HUMAN_MUMMY:
335 case PM_GIANT_MUMMY:
336 case PM_ETTIN_MUMMY:
337 case PM_KOBOLD_ZOMBIE:
338 case PM_DWARF_ZOMBIE:
339 case PM_GNOME_ZOMBIE:
340 case PM_ORC_ZOMBIE:
341 case PM_ELF_ZOMBIE:
342 case PM_HUMAN_ZOMBIE:
343 case PM_GIANT_ZOMBIE:
344 case PM_ETTIN_ZOMBIE:
345 num = undead_to_corpse(mndx);
346 corpstatflags |= CORPSTAT_INIT;
347 obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags);
348 obj->age -= 100; /* this is an *OLD* corpse */
349 break;
350 case PM_IRON_GOLEM:
351 num = d(2, 6);
352 while (num--)
353 obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE);
354 free_mname(mtmp); /* don't christen obj */
355 break;
356 case PM_GLASS_GOLEM:
357 num = d(2, 4); /* very low chance of creating all glass gems */
358 while (num--)
359 obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE);
360 free_mname(mtmp);
361 break;
362 case PM_CLAY_GOLEM:
363 obj = mksobj_at(ROCK, x, y, FALSE, FALSE);
364 obj->quan = (long) (rn2(20) + 50);
365 obj->owt = weight(obj);
366 free_mname(mtmp);
367 break;
368 case PM_STONE_GOLEM:
369 corpstatflags &= ~CORPSTAT_INIT;
370 obj =
371 mkcorpstat(STATUE, (struct monst *) 0, mdat, x, y, corpstatflags);
372 break;
373 case PM_WOOD_GOLEM:
374 num = d(2, 4);
375 while (num--) {
376 obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE);
378 free_mname(mtmp);
379 break;
380 case PM_LEATHER_GOLEM:
381 num = d(2, 4);
382 while (num--)
383 obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE);
384 free_mname(mtmp);
385 break;
386 case PM_GOLD_GOLEM:
387 /* Good luck gives more coins */
388 obj = mkgold((long) (200 - rnl(101)), x, y);
389 free_mname(mtmp);
390 break;
391 case PM_PAPER_GOLEM:
392 num = rnd(4);
393 while (num--)
394 obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE);
395 free_mname(mtmp);
396 break;
397 /* expired puddings will congeal into a large blob;
398 like dragons, relies on the order remaining consistent */
399 case PM_GRAY_OOZE:
400 case PM_BROWN_PUDDING:
401 case PM_GREEN_SLIME:
402 case PM_BLACK_PUDDING:
403 /* we have to do this here because most other places
404 expect there to be an object coming back; not this one */
405 obj = mksobj_at(GLOB_OF_BLACK_PUDDING - (PM_BLACK_PUDDING - mndx),
406 x, y, TRUE, FALSE);
408 while (obj && (otmp = obj_nexto(obj)) != (struct obj *) 0) {
409 pudding_merge_message(obj, otmp);
410 obj = obj_meld(&obj, &otmp);
412 free_mname(mtmp);
413 return obj;
414 break;
415 default_1:
416 default:
417 if (mvitals[mndx].mvflags & G_NOCORPSE) {
418 return (struct obj *) 0;
419 } else {
420 corpstatflags |= CORPSTAT_INIT;
421 /* preserve the unique traits of some creatures */
422 obj = mkcorpstat(CORPSE, KEEPTRAITS(mtmp) ? mtmp : 0,
423 mdat, x, y, corpstatflags);
424 if (burythem) {
425 boolean dealloc;
427 (void) bury_an_obj(obj, &dealloc);
428 newsym(x, y);
429 return dealloc ? (struct obj *) 0 : obj;
432 break;
434 /* All special cases should precede the G_NOCORPSE check */
436 if (!obj) return NULL;
438 /* if polymorph or undead turning has killed this monster,
439 prevent the same attack beam from hitting its corpse */
440 if (context.bypasses)
441 bypass_obj(obj);
443 if (has_mname(mtmp))
444 obj = oname(obj, MNAME(mtmp));
446 /* Avoid "It was hidden under a green mold corpse!"
447 * during Blind combat. An unseen monster referred to as "it"
448 * could be killed and leave a corpse. If a hider then hid
449 * underneath it, you could be told the corpse type of a
450 * monster that you never knew was there without this.
451 * The code in hitmu() substitutes the word "something"
452 * if the corpses obj->dknown is 0.
454 if (Blind && !sensemon(mtmp))
455 obj->dknown = 0;
457 stackobj(obj);
458 newsym(x, y);
459 return obj;
462 /* check mtmp and water/lava for compatibility, 0 (survived), 1 (died) */
464 minliquid(mtmp)
465 register struct monst *mtmp;
467 boolean inpool, inlava, infountain;
469 /* [what about ceiling clingers?] */
470 inpool = (is_pool(mtmp->mx, mtmp->my)
471 && !(is_flyer(mtmp->data) || is_floater(mtmp->data)));
472 inlava = (is_lava(mtmp->mx, mtmp->my)
473 && !(is_flyer(mtmp->data) || is_floater(mtmp->data)));
474 infountain = IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ);
476 /* Flying and levitation keeps our steed out of the liquid */
477 /* (but not water-walking or swimming) */
478 if (mtmp == u.usteed && (Flying || Levitation))
479 return 0;
481 /* Gremlin multiplying won't go on forever since the hit points
482 * keep going down, and when it gets to 1 hit point the clone
483 * function will fail.
485 if (mtmp->data == &mons[PM_GREMLIN] && (inpool || infountain) && rn2(3)) {
486 if (split_mon(mtmp, (struct monst *) 0))
487 dryup(mtmp->mx, mtmp->my, FALSE);
488 if (inpool)
489 water_damage_chain(mtmp->minvent, FALSE);
490 return 0;
491 } else if (mtmp->data == &mons[PM_IRON_GOLEM] && inpool && !rn2(5)) {
492 int dam = d(2, 6);
494 if (cansee(mtmp->mx, mtmp->my))
495 pline("%s rusts.", Monnam(mtmp));
496 mtmp->mhp -= dam;
497 if (mtmp->mhpmax > dam)
498 mtmp->mhpmax -= dam;
499 if (mtmp->mhp < 1) {
500 mondead(mtmp);
501 if (mtmp->mhp < 1)
502 return 1;
504 water_damage_chain(mtmp->minvent, FALSE);
505 return 0;
508 if (inlava) {
510 * Lava effects much as water effects. Lava likers are able to
511 * protect their stuff. Fire resistant monsters can only protect
512 * themselves --ALI
514 if (!is_clinger(mtmp->data) && !likes_lava(mtmp->data)) {
515 if (!resists_fire(mtmp)) {
516 if (cansee(mtmp->mx, mtmp->my))
517 pline("%s %s.", Monnam(mtmp),
518 mtmp->data == &mons[PM_WATER_ELEMENTAL]
519 ? "boils away"
520 : "burns to a crisp");
521 mondead(mtmp);
522 } else {
523 if (--mtmp->mhp < 1) {
524 if (cansee(mtmp->mx, mtmp->my))
525 pline("%s surrenders to the fire.", Monnam(mtmp));
526 mondead(mtmp);
527 } else if (cansee(mtmp->mx, mtmp->my))
528 pline("%s burns slightly.", Monnam(mtmp));
530 if (mtmp->mhp > 0) {
531 (void) fire_damage_chain(mtmp->minvent, FALSE, FALSE,
532 mtmp->mx, mtmp->my);
533 (void) rloc(mtmp, FALSE);
534 return 0;
536 return 1;
538 } else if (inpool) {
539 /* Most monsters drown in pools. flooreffects() will take care of
540 * water damage to dead monsters' inventory, but survivors need to
541 * be handled here. Swimmers are able to protect their stuff...
543 if (!is_clinger(mtmp->data) && !is_swimmer(mtmp->data)
544 && !amphibious(mtmp->data)) {
545 if (cansee(mtmp->mx, mtmp->my)) {
546 pline("%s drowns.", Monnam(mtmp));
548 if (u.ustuck && u.uswallow && u.ustuck == mtmp) {
549 /* This can happen after a purple worm plucks you off a
550 flying steed while you are over water. */
551 pline("%s sinks as water rushes in and flushes you out.",
552 Monnam(mtmp));
554 mondead(mtmp);
555 if (mtmp->mhp > 0) {
556 water_damage_chain(mtmp->minvent, FALSE);
557 (void) rloc(mtmp, FALSE);
558 return 0;
560 return 1;
562 } else {
563 /* but eels have a difficult time outside */
564 if (mtmp->data->mlet == S_EEL && !Is_waterlevel(&u.uz)) {
565 /* as mhp gets lower, the rate of further loss slows down */
566 if (mtmp->mhp > 1 && rn2(mtmp->mhp) > rn2(8))
567 mtmp->mhp--;
568 monflee(mtmp, 2, FALSE, FALSE);
571 return 0;
575 mcalcmove(mon)
576 struct monst *mon;
578 int mmove = mon->data->mmove;
580 /* Note: MSLOW's `+ 1' prevents slowed speed 1 getting reduced to 0;
581 * MFAST's `+ 2' prevents hasted speed 1 from becoming a no-op;
582 * both adjustments have negligible effect on higher speeds.
584 if (mon->mspeed == MSLOW)
585 mmove = (2 * mmove + 1) / 3;
586 else if (mon->mspeed == MFAST)
587 mmove = (4 * mmove + 2) / 3;
589 if (mon == u.usteed) {
590 if (u.ugallop && context.mv) {
591 /* average movement is 1.50 times normal */
592 mmove = ((rn2(2) ? 4 : 5) * mmove) / 3;
594 } else if (mmove) {
595 /* vary movement points allocated to slightly reduce predictability;
596 random increment (avg +2) exceeds random decrement (avg +1) by
597 a small amount; normal speed monsters will occasionally get an
598 extra move and slow ones won't be quite as slow */
599 mmove += rn2(5) - rn2(3); /* + 0..4 - 0..2, average net +1 */
600 if (mmove < 1)
601 mmove = 1;
604 return mmove;
607 /* actions that happen once per ``turn'', regardless of each
608 individual monster's metabolism; some of these might need to
609 be reclassified to occur more in proportion with movement rate */
610 void
611 mcalcdistress()
613 struct monst *mtmp;
615 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
616 if (DEADMONSTER(mtmp))
617 continue;
619 /* must check non-moving monsters once/turn in case
620 * they managed to end up in liquid */
621 if (mtmp->data->mmove == 0) {
622 if (vision_full_recalc)
623 vision_recalc(0);
624 if (minliquid(mtmp))
625 continue;
628 /* regenerate hit points */
629 mon_regen(mtmp, FALSE);
631 /* possibly polymorph shapechangers and lycanthropes */
632 if (mtmp->cham >= LOW_PM)
633 decide_to_shapeshift(mtmp, (canspotmon(mtmp)
634 || (u.uswallow && mtmp == u.ustuck))
635 ? SHIFT_MSG : 0);
636 were_change(mtmp);
638 /* gradually time out temporary problems */
639 if (mtmp->mblinded && !--mtmp->mblinded)
640 mtmp->mcansee = 1;
641 if (mtmp->mfrozen && !--mtmp->mfrozen)
642 mtmp->mcanmove = 1;
643 if (mtmp->mfleetim && !--mtmp->mfleetim)
644 mtmp->mflee = 0;
646 /* FIXME: mtmp->mlstmv ought to be updated here */
651 movemon()
653 register struct monst *mtmp, *nmtmp;
654 register boolean somebody_can_move = FALSE;
657 * Some of you may remember the former assertion here that
658 * because of deaths and other actions, a simple one-pass
659 * algorithm wasn't possible for movemon. Deaths are no longer
660 * removed to the separate list fdmon; they are simply left in
661 * the chain with hit points <= 0, to be cleaned up at the end
662 * of the pass.
664 * The only other actions which cause monsters to be removed from
665 * the chain are level migrations and losedogs(). I believe losedogs()
666 * is a cleanup routine not associated with monster movements, and
667 * monsters can only affect level migrations on themselves, not others
668 * (hence the fetching of nmon before moving the monster). Currently,
669 * monsters can jump into traps, read cursed scrolls of teleportation,
670 * and drink cursed potions of raise level to change levels. These are
671 * all reflexive at this point. Should one monster be able to level
672 * teleport another, this scheme would have problems.
675 for (mtmp = fmon; mtmp; mtmp = nmtmp) {
676 /* end monster movement early if hero is flagged to leave the level */
677 if (u.utotype
678 #ifdef SAFERHANGUP
679 /* or if the program has lost contact with the user */
680 || program_state.done_hup
681 #endif
683 somebody_can_move = FALSE;
684 break;
686 nmtmp = mtmp->nmon;
687 /* one dead monster needs to perform a move after death:
688 vault guard whose temporary corridor is still on the map */
689 if (mtmp->isgd && !mtmp->mx && mtmp->mhp <= 0)
690 (void) gd_move(mtmp);
691 if (DEADMONSTER(mtmp))
692 continue;
694 /* Find a monster that we have not treated yet. */
695 if (mtmp->movement < NORMAL_SPEED)
696 continue;
698 mtmp->movement -= NORMAL_SPEED;
699 if (mtmp->movement >= NORMAL_SPEED)
700 somebody_can_move = TRUE;
702 if (vision_full_recalc)
703 vision_recalc(0); /* vision! */
705 /* reset obj bypasses before next monster moves */
706 if (context.bypasses)
707 clear_bypasses();
708 clear_splitobjs();
709 if (minliquid(mtmp))
710 continue;
712 if (is_hider(mtmp->data)) {
713 /* unwatched mimics and piercers may hide again [MRS] */
714 if (restrap(mtmp))
715 continue;
716 if (mtmp->m_ap_type == M_AP_FURNITURE
717 || mtmp->m_ap_type == M_AP_OBJECT)
718 continue;
719 if (mtmp->mundetected)
720 continue;
721 } else if (mtmp->data->mlet == S_EEL && !mtmp->mundetected
722 && (mtmp->mflee || distu(mtmp->mx, mtmp->my) > 2)
723 && !canseemon(mtmp) && !rn2(4)) {
724 /* some eels end up stuck in isolated pools, where they
725 can't--or at least won't--move, so they never reach
726 their post-move chance to re-hide */
727 if (hideunder(mtmp))
728 continue;
731 /* continue if the monster died fighting */
732 if (Conflict && !mtmp->iswiz && mtmp->mcansee) {
733 /* Note:
734 * Conflict does not take effect in the first round.
735 * Therefore, A monster when stepping into the area will
736 * get to swing at you.
738 * The call to fightm() must be _last_. The monster might
739 * have died if it returns 1.
741 if (couldsee(mtmp->mx, mtmp->my)
742 && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM)
743 && fightm(mtmp))
744 continue; /* mon might have died */
746 if (dochugw(mtmp)) /* otherwise just move the monster */
747 continue;
750 if (any_light_source())
751 vision_full_recalc = 1; /* in case a mon moved with a light source */
752 /* reset obj bypasses after last monster has moved */
753 if (context.bypasses)
754 clear_bypasses();
755 clear_splitobjs();
756 /* remove dead monsters; dead vault guard will be left at <0,0>
757 if temporary corridor out of vault hasn't been removed yet */
758 dmonsfree();
760 /* a monster may have levteleported player -dlc */
761 if (u.utotype) {
762 deferred_goto();
763 /* changed levels, so these monsters are dormant */
764 somebody_can_move = FALSE;
767 return somebody_can_move;
770 #define mstoning(obj) \
771 (ofood(obj) && (touch_petrifies(&mons[(obj)->corpsenm]) \
772 || (obj)->corpsenm == PM_MEDUSA))
775 * Maybe eat a metallic object (not just gold).
776 * Return value: 0 => nothing happened, 1 => monster ate something,
777 * 2 => monster died (it must have grown into a genocided form, but
778 * that can't happen at present because nothing which eats objects
779 * has young and old forms).
782 meatmetal(mtmp)
783 register struct monst *mtmp;
785 register struct obj *otmp;
786 struct permonst *ptr;
787 int poly, grow, heal, mstone;
789 /* If a pet, eating is handled separately, in dog.c */
790 if (mtmp->mtame)
791 return 0;
793 /* Eats topmost metal object if it is there */
794 for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp;
795 otmp = otmp->nexthere) {
796 /* Don't eat indigestible/choking/inappropriate objects */
797 if ((mtmp->data == &mons[PM_RUST_MONSTER] && !is_rustprone(otmp))
798 || (otmp->otyp == AMULET_OF_STRANGULATION)
799 || (otmp->otyp == RIN_SLOW_DIGESTION))
800 continue;
801 if (is_metallic(otmp) && !obj_resists(otmp, 5, 95)
802 && touch_artifact(otmp, mtmp)) {
803 if (mtmp->data == &mons[PM_RUST_MONSTER] && otmp->oerodeproof) {
804 if (canseemon(mtmp) && flags.verbose) {
805 pline("%s eats %s!", Monnam(mtmp),
806 distant_name(otmp, doname));
808 /* The object's rustproofing is gone now */
809 otmp->oerodeproof = 0;
810 mtmp->mstun = 1;
811 if (canseemon(mtmp) && flags.verbose) {
812 pline("%s spits %s out in disgust!", Monnam(mtmp),
813 distant_name(otmp, doname));
815 } else {
816 if (cansee(mtmp->mx, mtmp->my) && flags.verbose)
817 pline("%s eats %s!", Monnam(mtmp),
818 distant_name(otmp, doname));
819 else if (flags.verbose)
820 You_hear("a crunching sound.");
821 mtmp->meating = otmp->owt / 2 + 1;
822 /* Heal up to the object's weight in hp */
823 if (mtmp->mhp < mtmp->mhpmax) {
824 mtmp->mhp += objects[otmp->otyp].oc_weight;
825 if (mtmp->mhp > mtmp->mhpmax)
826 mtmp->mhp = mtmp->mhpmax;
828 if (otmp == uball) {
829 unpunish();
830 delobj(otmp);
831 } else if (otmp == uchain) {
832 unpunish(); /* frees uchain */
833 } else {
834 poly = polyfodder(otmp);
835 grow = mlevelgain(otmp);
836 heal = mhealup(otmp);
837 mstone = mstoning(otmp);
838 delobj(otmp);
839 ptr = mtmp->data;
840 if (poly) {
841 if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE))
842 ptr = mtmp->data;
843 } else if (grow) {
844 ptr = grow_up(mtmp, (struct monst *) 0);
845 } else if (mstone) {
846 if (poly_when_stoned(ptr)) {
847 mon_to_stone(mtmp);
848 ptr = mtmp->data;
849 } else if (!resists_ston(mtmp)) {
850 if (canseemon(mtmp))
851 pline("%s turns to stone!", Monnam(mtmp));
852 monstone(mtmp);
853 ptr = (struct permonst *) 0;
855 } else if (heal) {
856 mtmp->mhp = mtmp->mhpmax;
858 if (!ptr)
859 return 2; /* it died */
861 /* Left behind a pile? */
862 if (rnd(25) < 3)
863 (void) mksobj_at(ROCK, mtmp->mx, mtmp->my, TRUE, FALSE);
864 newsym(mtmp->mx, mtmp->my);
865 return 1;
869 return 0;
872 /* monster eats a pile of objects */
874 meatobj(mtmp) /* for gelatinous cubes */
875 struct monst *mtmp;
877 register struct obj *otmp, *otmp2;
878 struct permonst *ptr, *original_ptr = mtmp->data;
879 int poly, grow, heal, count = 0, ecount = 0;
880 char buf[BUFSZ];
882 buf[0] = '\0';
883 /* If a pet, eating is handled separately, in dog.c */
884 if (mtmp->mtame)
885 return 0;
887 /* eat organic objects, including cloth and wood, if present;
888 engulf others, except huge rocks and metal attached to player
889 [despite comment at top, doesn't assume that eater is a g.cube] */
890 for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
891 otmp2 = otmp->nexthere;
893 /* touch sensitive items */
894 if (otmp->otyp == CORPSE && is_rider(&mons[otmp->corpsenm])) {
895 /* Rider corpse isn't just inedible; can't engulf it either */
896 (void) revive_corpse(otmp);
898 /* untouchable (or inaccessible) items */
899 } else if ((otmp->otyp == CORPSE
900 && touch_petrifies(&mons[otmp->corpsenm])
901 && !resists_ston(mtmp))
902 /* don't engulf boulders and statues or ball&chain */
903 || otmp->oclass == ROCK_CLASS
904 || otmp == uball || otmp == uchain) {
905 /* do nothing--neither eaten nor engulfed */
906 continue;
908 /* inedible items -- engulf these */
909 } else if (!is_organic(otmp) || obj_resists(otmp, 5, 95)
910 || !touch_artifact(otmp, mtmp)
911 /* redundant due to non-organic composition but
912 included for emphasis */
913 || (otmp->otyp == AMULET_OF_STRANGULATION
914 || otmp->otyp == RIN_SLOW_DIGESTION)
915 /* cockatrice corpses handled above; this
916 touch_petrifies() check catches eggs */
917 || ((otmp->otyp == CORPSE || otmp->otyp == EGG)
918 && ((touch_petrifies(&mons[otmp->corpsenm])
919 && !resists_ston(mtmp))
920 || (otmp->corpsenm == PM_GREEN_SLIME
921 && !slimeproof(mtmp->data))))) {
922 /* engulf */
923 ++ecount;
924 if (ecount == 1)
925 Sprintf(buf, "%s engulfs %s.", Monnam(mtmp),
926 distant_name(otmp, doname));
927 else if (ecount == 2)
928 Sprintf(buf, "%s engulfs several objects.", Monnam(mtmp));
929 obj_extract_self(otmp);
930 (void) mpickobj(mtmp, otmp); /* slurp */
932 /* lastly, edible items; yum! */
933 } else {
934 /* devour */
935 ++count;
936 if (cansee(mtmp->mx, mtmp->my) && flags.verbose)
937 pline("%s eats %s!", Monnam(mtmp),
938 distant_name(otmp, doname));
939 else if (flags.verbose)
940 You_hear("a slurping sound.");
941 /* Heal up to the object's weight in hp */
942 if (mtmp->mhp < mtmp->mhpmax) {
943 mtmp->mhp += objects[otmp->otyp].oc_weight;
944 if (mtmp->mhp > mtmp->mhpmax)
945 mtmp->mhp = mtmp->mhpmax;
947 if (Has_contents(otmp)) {
948 register struct obj *otmp3;
950 /* contents of eaten containers become engulfed; this
951 is arbitrary, but otherwise g.cubes are too powerful */
952 while ((otmp3 = otmp->cobj) != 0) {
953 obj_extract_self(otmp3);
954 if (otmp->otyp == ICE_BOX && otmp3->otyp == CORPSE) {
955 otmp3->age = monstermoves - otmp3->age;
956 start_corpse_timeout(otmp3);
958 (void) mpickobj(mtmp, otmp3);
961 poly = polyfodder(otmp);
962 grow = mlevelgain(otmp);
963 heal = mhealup(otmp);
964 delobj(otmp); /* munch */
965 ptr = mtmp->data;
966 if (poly) {
967 if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE))
968 ptr = mtmp->data;
969 } else if (grow) {
970 ptr = grow_up(mtmp, (struct monst *) 0);
971 } else if (heal) {
972 mtmp->mhp = mtmp->mhpmax;
974 /* in case it polymorphed or died */
975 if (ptr != original_ptr)
976 return !ptr ? 2 : 1;
979 /* Engulf & devour is instant, so don't set meating */
980 if (mtmp->minvis)
981 newsym(mtmp->mx, mtmp->my);
984 if (ecount > 0) {
985 if (cansee(mtmp->mx, mtmp->my) && flags.verbose && buf[0])
986 pline1(buf);
987 else if (flags.verbose)
988 You_hear("%s slurping sound%s.",
989 (ecount == 1) ? "a" : "several", plur(ecount));
991 return (count > 0 || ecount > 0) ? 1 : 0;
994 void
995 mpickgold(mtmp)
996 register struct monst *mtmp;
998 register struct obj *gold;
999 int mat_idx;
1001 if ((gold = g_at(mtmp->mx, mtmp->my)) != 0) {
1002 mat_idx = objects[gold->otyp].oc_material;
1003 obj_extract_self(gold);
1004 add_to_minv(mtmp, gold);
1005 if (cansee(mtmp->mx, mtmp->my)) {
1006 if (flags.verbose && !mtmp->isgd)
1007 pline("%s picks up some %s.", Monnam(mtmp),
1008 mat_idx == GOLD ? "gold" : "money");
1009 newsym(mtmp->mx, mtmp->my);
1014 boolean
1015 mpickstuff(mtmp, str)
1016 register struct monst *mtmp;
1017 register const char *str;
1019 register struct obj *otmp, *otmp2, *otmp3;
1020 int carryamt = 0;
1022 /* prevent shopkeepers from leaving the door of their shop */
1023 if (mtmp->isshk && inhishop(mtmp))
1024 return FALSE;
1026 for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
1027 otmp2 = otmp->nexthere;
1028 /* Nymphs take everything. Most monsters don't pick up corpses. */
1029 if (!str ? searches_for_item(mtmp, otmp)
1030 : !!(index(str, otmp->oclass))) {
1031 if (otmp->otyp == CORPSE && mtmp->data->mlet != S_NYMPH
1032 /* let a handful of corpse types thru to can_carry() */
1033 && !touch_petrifies(&mons[otmp->corpsenm])
1034 && otmp->corpsenm != PM_LIZARD
1035 && !acidic(&mons[otmp->corpsenm]))
1036 continue;
1037 if (!touch_artifact(otmp, mtmp))
1038 continue;
1039 carryamt = can_carry(mtmp, otmp);
1040 if (carryamt == 0)
1041 continue;
1042 if (is_pool(mtmp->mx, mtmp->my))
1043 continue;
1044 /* handle cases where the critter can only get some */
1045 otmp3 = otmp;
1046 if (carryamt != otmp->quan) {
1047 otmp3 = splitobj(otmp, carryamt);
1049 if (cansee(mtmp->mx, mtmp->my) && flags.verbose)
1050 pline("%s picks up %s.", Monnam(mtmp),
1051 (distu(mtmp->mx, mtmp->my) <= 5)
1052 ? doname(otmp3)
1053 : distant_name(otmp3, doname));
1054 obj_extract_self(otmp3); /* remove from floor */
1055 (void) mpickobj(mtmp, otmp3); /* may merge and free otmp3 */
1056 m_dowear(mtmp, FALSE);
1057 newsym(mtmp->mx, mtmp->my);
1058 return TRUE; /* pick only one object */
1061 return FALSE;
1065 curr_mon_load(mtmp)
1066 struct monst *mtmp;
1068 int curload = 0;
1069 struct obj *obj;
1071 for (obj = mtmp->minvent; obj; obj = obj->nobj) {
1072 if (obj->otyp != BOULDER || !throws_rocks(mtmp->data))
1073 curload += obj->owt;
1076 return curload;
1080 max_mon_load(mtmp)
1081 struct monst *mtmp;
1083 long maxload;
1085 /* Base monster carrying capacity is equal to human maximum
1086 * carrying capacity, or half human maximum if not strong.
1087 * (for a polymorphed player, the value used would be the
1088 * non-polymorphed carrying capacity instead of max/half max).
1089 * This is then modified by the ratio between the monster weights
1090 * and human weights. Corpseless monsters are given a capacity
1091 * proportional to their size instead of weight.
1093 if (!mtmp->data->cwt)
1094 maxload = (MAX_CARR_CAP * (long) mtmp->data->msize) / MZ_HUMAN;
1095 else if (!strongmonst(mtmp->data)
1096 || (strongmonst(mtmp->data) && (mtmp->data->cwt > WT_HUMAN)))
1097 maxload = (MAX_CARR_CAP * (long) mtmp->data->cwt) / WT_HUMAN;
1098 else
1099 maxload = MAX_CARR_CAP; /*strong monsters w/cwt <= WT_HUMAN*/
1101 if (!strongmonst(mtmp->data))
1102 maxload /= 2;
1104 if (maxload < 1)
1105 maxload = 1;
1107 return (int) maxload;
1110 /* for restricting monsters' object-pickup.
1112 * to support the new pet behavior, this now returns the max # of objects
1113 * that a given monster could pick up from a pile. frequently this will be
1114 * otmp->quan, but special cases for 'only one' now exist so.
1116 * this will probably cause very amusing behavior with pets and gold coins.
1118 * TODO: allow picking up 2-N objects from a pile of N based on weight.
1119 * Change from 'int' to 'long' to accomate big stacks of gold.
1120 * Right now we fake it by reporting a partial quantity, but the
1121 * likesgold handling m_move results in picking up the whole stack.
1124 can_carry(mtmp, otmp)
1125 struct monst *mtmp;
1126 struct obj *otmp;
1128 int iquan, otyp = otmp->otyp, newload = otmp->owt;
1129 struct permonst *mdat = mtmp->data;
1130 short nattk = 0;
1132 if (notake(mdat))
1133 return 0; /* can't carry anything */
1135 if (otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm])
1136 && !(mtmp->misc_worn_check & W_ARMG) && !resists_ston(mtmp))
1137 return 0;
1138 if (otyp == CORPSE && is_rider(&mons[otmp->corpsenm]))
1139 return 0;
1140 if (objects[otyp].oc_material == SILVER && mon_hates_silver(mtmp)
1141 && (otyp != BELL_OF_OPENING || !is_covetous(mdat)))
1142 return 0;
1144 /* hostile monsters who like gold will pick up the whole stack;
1145 tame mosnters with hands will pick up the partial stack */
1146 iquan = (otmp->quan > (long) LARGEST_INT)
1147 ? 20000 + rn2(LARGEST_INT - 20000 + 1)
1148 : (int) otmp->quan;
1150 /* monsters without hands can't pick up multiple objects at once
1151 * unless they have an engulfing attack
1153 * ...dragons, of course, can always carry gold pieces and gems somehow
1155 if (iquan > 1) {
1156 boolean glomper = FALSE;
1158 if (mtmp->data->mlet == S_DRAGON
1159 && (otmp->oclass == COIN_CLASS
1160 || otmp->oclass == GEM_CLASS))
1161 glomper = TRUE;
1162 else
1163 for (nattk = 0; nattk < NATTK; nattk++)
1164 if (mtmp->data->mattk[nattk].aatyp == AT_ENGL) {
1165 glomper = TRUE;
1166 break;
1168 if ((mtmp->data->mflags1 & M1_NOHANDS) && !glomper)
1169 return 1;
1172 /* steeds don't pick up stuff (to avoid shop abuse) */
1173 if (mtmp == u.usteed)
1174 return 0;
1175 if (mtmp->isshk)
1176 return iquan; /* no limit */
1177 if (mtmp->mpeaceful && !mtmp->mtame)
1178 return 0;
1179 /* otherwise players might find themselves obligated to violate
1180 * their alignment if the monster takes something they need
1183 /* special--boulder throwers carry unlimited amounts of boulders */
1184 if (throws_rocks(mdat) && otyp == BOULDER)
1185 return iquan;
1187 /* nymphs deal in stolen merchandise, but not boulders or statues */
1188 if (mdat->mlet == S_NYMPH)
1189 return (otmp->oclass == ROCK_CLASS) ? 0 : iquan;
1191 if (curr_mon_load(mtmp) + newload > max_mon_load(mtmp))
1192 return 0;
1194 return iquan;
1197 /* return number of acceptable neighbour positions */
1199 mfndpos(mon, poss, info, flag)
1200 struct monst *mon;
1201 coord *poss; /* coord poss[9] */
1202 long *info; /* long info[9] */
1203 long flag;
1205 struct permonst *mdat = mon->data;
1206 register struct trap *ttmp;
1207 xchar x, y, nx, ny;
1208 int cnt = 0;
1209 uchar ntyp;
1210 uchar nowtyp;
1211 boolean wantpool, poolok, lavaok, nodiag;
1212 boolean rockok = FALSE, treeok = FALSE, thrudoor;
1213 int maxx, maxy;
1214 boolean poisongas_ok, in_poisongas;
1215 NhRegion *gas_reg;
1216 int gas_glyph = cmap_to_glyph(S_poisoncloud);
1218 x = mon->mx;
1219 y = mon->my;
1220 nowtyp = levl[x][y].typ;
1222 nodiag = NODIAG(mdat - mons);
1223 wantpool = mdat->mlet == S_EEL;
1224 poolok = (is_flyer(mdat) || is_clinger(mdat)
1225 || (is_swimmer(mdat) && !wantpool));
1226 lavaok = (is_flyer(mdat) || is_clinger(mdat) || likes_lava(mdat));
1227 thrudoor = ((flag & (ALLOW_WALL | BUSTDOOR)) != 0L);
1228 poisongas_ok = ((nonliving(mdat) || is_vampshifter(mon)
1229 || breathless(mdat)) || resists_poison(mon));
1230 in_poisongas = ((gas_reg = visible_region_at(x,y)) != 0
1231 && gas_reg->glyph == gas_glyph);
1233 if (flag & ALLOW_DIG) {
1234 struct obj *mw_tmp;
1236 /* need to be specific about what can currently be dug */
1237 if (!needspick(mdat)) {
1238 rockok = treeok = TRUE;
1239 } else if ((mw_tmp = MON_WEP(mon)) && mw_tmp->cursed
1240 && mon->weapon_check == NO_WEAPON_WANTED) {
1241 rockok = is_pick(mw_tmp);
1242 treeok = is_axe(mw_tmp);
1243 } else {
1244 rockok = (m_carrying(mon, PICK_AXE)
1245 || (m_carrying(mon, DWARVISH_MATTOCK)
1246 && !which_armor(mon, W_ARMS)));
1247 treeok = (m_carrying(mon, AXE) || (m_carrying(mon, BATTLE_AXE)
1248 && !which_armor(mon, W_ARMS)));
1250 if (rockok || treeok)
1251 thrudoor = TRUE;
1254 nexttry: /* eels prefer the water, but if there is no water nearby,
1255 they will crawl over land */
1256 if (mon->mconf) {
1257 flag |= ALLOW_ALL;
1258 flag &= ~NOTONL;
1260 if (!mon->mcansee)
1261 flag |= ALLOW_SSM;
1262 maxx = min(x + 1, COLNO - 1);
1263 maxy = min(y + 1, ROWNO - 1);
1264 for (nx = max(1, x - 1); nx <= maxx; nx++)
1265 for (ny = max(0, y - 1); ny <= maxy; ny++) {
1266 if (nx == x && ny == y)
1267 continue;
1268 ntyp = levl[nx][ny].typ;
1269 if (IS_ROCK(ntyp)
1270 && !((flag & ALLOW_WALL) && may_passwall(nx, ny))
1271 && !((IS_TREE(ntyp) ? treeok : rockok) && may_dig(nx, ny)))
1272 continue;
1273 /* KMH -- Added iron bars */
1274 if (ntyp == IRONBARS && !(flag & ALLOW_BARS))
1275 continue;
1276 if (IS_DOOR(ntyp) && !(amorphous(mdat) || can_fog(mon))
1277 && (((levl[nx][ny].doormask & D_CLOSED) && !(flag & OPENDOOR))
1278 || ((levl[nx][ny].doormask & D_LOCKED)
1279 && !(flag & UNLOCKDOOR))) && !thrudoor)
1280 continue;
1281 /* avoid poison gas? */
1282 if (!poisongas_ok && !in_poisongas
1283 && (gas_reg = visible_region_at(nx,ny)) != 0
1284 && gas_reg->glyph == gas_glyph)
1285 continue;
1286 /* first diagonal checks (tight squeezes handled below) */
1287 if (nx != x && ny != y
1288 && (nodiag
1289 || (IS_DOOR(nowtyp) && (levl[x][y].doormask & ~D_BROKEN))
1290 || (IS_DOOR(ntyp) && (levl[nx][ny].doormask & ~D_BROKEN))
1291 || ((IS_DOOR(nowtyp) || IS_DOOR(ntyp))
1292 && Is_rogue_level(&u.uz))
1293 /* mustn't pass between adjacent long worm segments,
1294 but can attack that way */
1295 || (m_at(x, ny) && m_at(nx, y) && worm_cross(x, y, nx, ny)
1296 && !m_at(nx, ny) && (nx != u.ux || ny != u.uy))))
1297 continue;
1298 if ((is_pool(nx, ny) == wantpool || poolok)
1299 && (lavaok || !is_lava(nx, ny))) {
1300 int dispx, dispy;
1301 boolean monseeu = (mon->mcansee
1302 && (!Invis || perceives(mdat)));
1303 boolean checkobj = OBJ_AT(nx, ny);
1305 /* Displacement also displaces the Elbereth/scare monster,
1306 * as long as you are visible.
1308 if (Displaced && monseeu && mon->mux == nx && mon->muy == ny) {
1309 dispx = u.ux;
1310 dispy = u.uy;
1311 } else {
1312 dispx = nx;
1313 dispy = ny;
1316 info[cnt] = 0;
1317 if (onscary(dispx, dispy, mon)) {
1318 if (!(flag & ALLOW_SSM))
1319 continue;
1320 info[cnt] |= ALLOW_SSM;
1322 if ((nx == u.ux && ny == u.uy)
1323 || (nx == mon->mux && ny == mon->muy)) {
1324 if (nx == u.ux && ny == u.uy) {
1325 /* If it's right next to you, it found you,
1326 * displaced or no. We must set mux and muy
1327 * right now, so when we return we can tell
1328 * that the ALLOW_U means to attack _you_ and
1329 * not the image.
1331 mon->mux = u.ux;
1332 mon->muy = u.uy;
1334 if (!(flag & ALLOW_U))
1335 continue;
1336 info[cnt] |= ALLOW_U;
1337 } else {
1338 if (MON_AT(nx, ny)) {
1339 struct monst *mtmp2 = m_at(nx, ny);
1340 long mmflag = flag | mm_aggression(mon, mtmp2);
1342 if (mmflag & ALLOW_M) {
1343 info[cnt] |= ALLOW_M;
1344 if (mtmp2->mtame) {
1345 if (!(mmflag & ALLOW_TM))
1346 continue;
1347 info[cnt] |= ALLOW_TM;
1349 } else {
1350 mmflag = flag | mm_displacement(mon, mtmp2);
1351 if (!(mmflag & ALLOW_MDISP))
1352 continue;
1353 info[cnt] |= ALLOW_MDISP;
1356 /* Note: ALLOW_SANCT only prevents movement, not
1357 attack, into a temple. */
1358 if (level.flags.has_temple && *in_rooms(nx, ny, TEMPLE)
1359 && !*in_rooms(x, y, TEMPLE)
1360 && in_your_sanctuary((struct monst *) 0, nx, ny)) {
1361 if (!(flag & ALLOW_SANCT))
1362 continue;
1363 info[cnt] |= ALLOW_SANCT;
1366 if (checkobj && sobj_at(CLOVE_OF_GARLIC, nx, ny)) {
1367 if (flag & NOGARLIC)
1368 continue;
1369 info[cnt] |= NOGARLIC;
1371 if (checkobj && sobj_at(BOULDER, nx, ny)) {
1372 if (!(flag & ALLOW_ROCK))
1373 continue;
1374 info[cnt] |= ALLOW_ROCK;
1376 if (monseeu && onlineu(nx, ny)) {
1377 if (flag & NOTONL)
1378 continue;
1379 info[cnt] |= NOTONL;
1381 /* check for diagonal tight squeeze */
1382 if (nx != x && ny != y && bad_rock(mdat, x, ny)
1383 && bad_rock(mdat, nx, y) && cant_squeeze_thru(mon))
1384 continue;
1385 /* The monster avoids a particular type of trap if it's
1386 * familiar with the trap type. Pets get ALLOW_TRAPS
1387 * and checking is done in dogmove.c. In either case,
1388 * "harmless" traps are neither avoided nor marked in info[].
1390 if ((ttmp = t_at(nx, ny)) != 0) {
1391 if (ttmp->ttyp >= TRAPNUM || ttmp->ttyp == 0) {
1392 impossible(
1393 "A monster looked at a very strange trap of type %d.",
1394 ttmp->ttyp);
1395 continue;
1397 if ((ttmp->ttyp != RUST_TRAP
1398 || mdat == &mons[PM_IRON_GOLEM])
1399 && ttmp->ttyp != STATUE_TRAP
1400 && ((ttmp->ttyp != PIT && ttmp->ttyp != SPIKED_PIT
1401 && ttmp->ttyp != TRAPDOOR && ttmp->ttyp != HOLE)
1402 || (!is_flyer(mdat) && !is_floater(mdat)
1403 && !is_clinger(mdat)) || Sokoban)
1404 && (ttmp->ttyp != SLP_GAS_TRAP || !resists_sleep(mon))
1405 && (ttmp->ttyp != BEAR_TRAP
1406 || (mdat->msize > MZ_SMALL && !amorphous(mdat)
1407 && !is_flyer(mdat) && !is_floater(mdat)
1408 && !is_whirly(mdat) && !unsolid(mdat)))
1409 && (ttmp->ttyp != FIRE_TRAP || !resists_fire(mon))
1410 && (ttmp->ttyp != SQKY_BOARD || !is_flyer(mdat))
1411 && (ttmp->ttyp != WEB
1412 || (!amorphous(mdat) && !webmaker(mdat)
1413 && !is_whirly(mdat) && !unsolid(mdat)))
1414 && (ttmp->ttyp != ANTI_MAGIC || !resists_magm(mon))) {
1415 if (!(flag & ALLOW_TRAPS)) {
1416 if (mon->mtrapseen & (1L << (ttmp->ttyp - 1)))
1417 continue;
1419 info[cnt] |= ALLOW_TRAPS;
1422 poss[cnt].x = nx;
1423 poss[cnt].y = ny;
1424 cnt++;
1427 if (!cnt && wantpool && !is_pool(x, y)) {
1428 wantpool = FALSE;
1429 goto nexttry;
1431 return cnt;
1434 /* Monster against monster special attacks; for the specified monster
1435 combinations, this allows one monster to attack another adjacent one
1436 in the absence of Conflict. There is no provision for targetting
1437 other monsters; just hand to hand fighting when they happen to be
1438 next to each other. */
1439 STATIC_OVL long
1440 mm_aggression(magr, mdef)
1441 struct monst *magr, /* monster that is currently deciding where to move */
1442 *mdef; /* another monster which is next to it */
1444 /* supposedly purple worms are attracted to shrieking because they
1445 like to eat shriekers, so attack the latter when feasible */
1446 if (magr->data == &mons[PM_PURPLE_WORM]
1447 && mdef->data == &mons[PM_SHRIEKER])
1448 return ALLOW_M | ALLOW_TM;
1449 /* Various other combinations such as dog vs cat, cat vs rat, and
1450 elf vs orc have been suggested. For the time being we don't
1451 support those. */
1452 return 0L;
1455 /* Monster displacing another monster out of the way */
1456 STATIC_OVL long
1457 mm_displacement(magr, mdef)
1458 struct monst *magr, /* monster that is currently deciding where to move */
1459 *mdef; /* another monster which is next to it */
1461 struct permonst *pa = magr->data, *pd = mdef->data;
1463 /* if attacker can't barge through, there's nothing to do;
1464 or if defender can barge through too, don't let attacker
1465 do so, otherwise they might just end up swapping places
1466 again when defender gets its chance to move */
1467 if ((pa->mflags3 & M3_DISPLACES) != 0 && (pd->mflags3 & M3_DISPLACES) == 0
1468 /* no displacing grid bugs diagonally */
1469 && !(magr->mx != mdef->mx && magr->my != mdef->my
1470 && NODIAG(monsndx(pd)))
1471 /* no displacing trapped monsters or multi-location longworms */
1472 && !mdef->mtrapped && (!mdef->wormno || !count_wsegs(mdef))
1473 /* riders can move anything; others, same size or smaller only */
1474 && (is_rider(pa) || pa->msize >= pd->msize))
1475 return ALLOW_MDISP;
1476 return 0L;
1479 /* Is the square close enough for the monster to move or attack into? */
1480 boolean
1481 monnear(mon, x, y)
1482 struct monst *mon;
1483 int x, y;
1485 int distance = dist2(mon->mx, mon->my, x, y);
1487 if (distance == 2 && NODIAG(mon->data - mons))
1488 return 0;
1489 return (boolean) (distance < 3);
1492 /* really free dead monsters */
1493 void
1494 dmonsfree()
1496 struct monst **mtmp, *freetmp;
1497 int count = 0;
1499 for (mtmp = &fmon; *mtmp;) {
1500 freetmp = *mtmp;
1501 if (freetmp->mhp <= 0 && !freetmp->isgd) {
1502 *mtmp = freetmp->nmon;
1503 freetmp->nmon = NULL;
1504 dealloc_monst(freetmp);
1505 count++;
1506 } else
1507 mtmp = &(freetmp->nmon);
1510 if (count != iflags.purge_monsters)
1511 impossible("dmonsfree: %d removed doesn't match %d pending",
1512 count, iflags.purge_monsters);
1513 iflags.purge_monsters = 0;
1516 /* called when monster is moved to larger structure */
1517 void
1518 replmon(mtmp, mtmp2)
1519 struct monst *mtmp, *mtmp2;
1521 struct obj *otmp;
1523 /* transfer the monster's inventory */
1524 for (otmp = mtmp2->minvent; otmp; otmp = otmp->nobj) {
1525 if (otmp->where != OBJ_MINVENT || otmp->ocarry != mtmp)
1526 impossible("replmon: minvent inconsistency");
1527 otmp->ocarry = mtmp2;
1529 mtmp->minvent = 0;
1531 /* remove the old monster from the map and from `fmon' list */
1532 relmon(mtmp, (struct monst **) 0);
1534 /* finish adding its replacement */
1535 if (mtmp != u.usteed) /* don't place steed onto the map */
1536 place_monster(mtmp2, mtmp2->mx, mtmp2->my);
1537 if (mtmp2->wormno) /* update level.monsters[wseg->wx][wseg->wy] */
1538 place_wsegs(mtmp2); /* locations to mtmp2 not mtmp. */
1539 if (emits_light(mtmp2->data)) {
1540 /* since this is so rare, we don't have any `mon_move_light_source' */
1541 new_light_source(mtmp2->mx, mtmp2->my, emits_light(mtmp2->data),
1542 LS_MONSTER, monst_to_any(mtmp2));
1543 /* here we rely on fact that `mtmp' hasn't actually been deleted */
1544 del_light_source(LS_MONSTER, monst_to_any(mtmp));
1546 mtmp2->nmon = fmon;
1547 fmon = mtmp2;
1548 if (u.ustuck == mtmp)
1549 u.ustuck = mtmp2;
1550 if (u.usteed == mtmp)
1551 u.usteed = mtmp2;
1552 if (mtmp2->isshk)
1553 replshk(mtmp, mtmp2);
1555 /* discard the old monster */
1556 dealloc_monst(mtmp);
1559 /* release mon from the display and the map's monster list,
1560 maybe transfer it to one of the other monster lists */
1561 void
1562 relmon(mon, monst_list)
1563 struct monst *mon;
1564 struct monst **monst_list; /* &migrating_mons or &mydogs or null */
1566 struct monst *mtmp;
1567 boolean unhide = (monst_list != 0);
1568 int mx = mon->mx, my = mon->my;
1570 if (!fmon)
1571 panic("relmon: no fmon available.");
1573 if (unhide) {
1574 /* can't remain hidden across level changes (exception: wizard
1575 clone can continue imitating some other monster form); also,
1576 might be imitating a boulder so need line-of-sight unblocking */
1577 mon->mundetected = 0;
1578 if (mon->m_ap_type && mon->m_ap_type != M_AP_MONSTER)
1579 seemimic(mon);
1582 remove_monster(mx, my);
1584 if (mon == fmon) {
1585 fmon = fmon->nmon;
1586 } else {
1587 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
1588 if (mtmp->nmon == mon)
1589 break;
1591 if (mtmp)
1592 mtmp->nmon = mon->nmon;
1593 else
1594 panic("relmon: mon not in list.");
1597 if (unhide) {
1598 newsym(mx, my);
1599 /* insert into mydogs or migrating_mons */
1600 mon->nmon = *monst_list;
1601 *monst_list = mon;
1602 } else {
1603 /* orphan has no next monster */
1604 mon->nmon = 0;
1608 void
1609 copy_mextra(mtmp2, mtmp1)
1610 struct monst *mtmp2, *mtmp1;
1612 if (!mtmp2 || !mtmp1 || !mtmp1->mextra)
1613 return;
1615 if (!mtmp2->mextra)
1616 mtmp2->mextra = newmextra();
1617 if (MNAME(mtmp1)) {
1618 new_mname(mtmp2, (int) strlen(MNAME(mtmp1)) + 1);
1619 Strcpy(MNAME(mtmp2), MNAME(mtmp1));
1621 if (EGD(mtmp1)) {
1622 if (!EGD(mtmp2))
1623 newegd(mtmp2);
1624 (void) memcpy((genericptr_t) EGD(mtmp2), (genericptr_t) EGD(mtmp1),
1625 sizeof (struct egd));
1627 if (EPRI(mtmp1)) {
1628 if (!EPRI(mtmp2))
1629 newepri(mtmp2);
1630 (void) memcpy((genericptr_t) EPRI(mtmp2), (genericptr_t) EPRI(mtmp1),
1631 sizeof (struct epri));
1633 if (ESHK(mtmp1)) {
1634 if (!ESHK(mtmp2))
1635 neweshk(mtmp2);
1636 (void) memcpy((genericptr_t) ESHK(mtmp2), (genericptr_t) ESHK(mtmp1),
1637 sizeof (struct eshk));
1639 if (EMIN(mtmp1)) {
1640 if (!EMIN(mtmp2))
1641 newemin(mtmp2);
1642 (void) memcpy((genericptr_t) EMIN(mtmp2), (genericptr_t) EMIN(mtmp1),
1643 sizeof (struct emin));
1645 if (EDOG(mtmp1)) {
1646 if (!EDOG(mtmp2))
1647 newedog(mtmp2);
1648 (void) memcpy((genericptr_t) EDOG(mtmp2), (genericptr_t) EDOG(mtmp1),
1649 sizeof (struct edog));
1651 if (has_mcorpsenm(mtmp1))
1652 MCORPSENM(mtmp2) = MCORPSENM(mtmp1);
1655 void
1656 dealloc_mextra(m)
1657 struct monst *m;
1659 struct mextra *x = m->mextra;
1661 if (x) {
1662 if (x->mname)
1663 free((genericptr_t) x->mname);
1664 if (x->egd)
1665 free((genericptr_t) x->egd);
1666 if (x->epri)
1667 free((genericptr_t) x->epri);
1668 if (x->eshk)
1669 free((genericptr_t) x->eshk);
1670 if (x->emin)
1671 free((genericptr_t) x->emin);
1672 if (x->edog)
1673 free((genericptr_t) x->edog);
1674 /* [no action needed for x->mcorpsenm] */
1676 free((genericptr_t) x);
1677 m->mextra = (struct mextra *) 0;
1681 void
1682 dealloc_monst(mon)
1683 struct monst *mon;
1685 if (mon->nmon)
1686 panic("dealloc_monst with nmon");
1687 if (mon->mextra)
1688 dealloc_mextra(mon);
1689 free((genericptr_t) mon);
1692 /* remove effects of mtmp from other data structures */
1693 STATIC_OVL void
1694 m_detach(mtmp, mptr)
1695 struct monst *mtmp;
1696 struct permonst *mptr; /* reflects mtmp->data _prior_ to mtmp's death */
1698 if (mtmp == context.polearm.hitmon)
1699 context.polearm.hitmon = 0;
1700 if (mtmp->mleashed)
1701 m_unleash(mtmp, FALSE);
1702 /* to prevent an infinite relobj-flooreffects-hmon-killed loop */
1703 mtmp->mtrapped = 0;
1704 mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */
1705 relobj(mtmp, 0, FALSE);
1706 remove_monster(mtmp->mx, mtmp->my);
1707 if (emits_light(mptr))
1708 del_light_source(LS_MONSTER, monst_to_any(mtmp));
1709 if (mtmp->m_ap_type)
1710 seemimic(mtmp);
1711 newsym(mtmp->mx, mtmp->my);
1712 unstuck(mtmp);
1713 fill_pit(mtmp->mx, mtmp->my);
1715 if (mtmp->isshk)
1716 shkgone(mtmp);
1717 if (mtmp->wormno)
1718 wormgone(mtmp);
1719 iflags.purge_monsters++;
1722 /* find the worn amulet of life saving which will save a monster */
1723 struct obj *
1724 mlifesaver(mon)
1725 struct monst *mon;
1727 if (!nonliving(mon->data) || is_vampshifter(mon)) {
1728 struct obj *otmp = which_armor(mon, W_AMUL);
1730 if (otmp && otmp->otyp == AMULET_OF_LIFE_SAVING)
1731 return otmp;
1733 return (struct obj *) 0;
1736 STATIC_OVL void
1737 lifesaved_monster(mtmp)
1738 struct monst *mtmp;
1740 boolean surviver;
1741 struct obj *lifesave = mlifesaver(mtmp);
1743 if (lifesave) {
1744 /* not canseemon; amulets are on the head, so you don't want
1745 * to show this for a long worm with only a tail visible.
1746 * Nor do you check invisibility, because glowing and
1747 * disintegrating amulets are always visible. */
1748 if (cansee(mtmp->mx, mtmp->my)) {
1749 pline("But wait...");
1750 pline("%s medallion begins to glow!", s_suffix(Monnam(mtmp)));
1751 makeknown(AMULET_OF_LIFE_SAVING);
1752 /* amulet is visible, but monster might not be */
1753 if (canseemon(mtmp)) {
1754 if (attacktype(mtmp->data, AT_EXPL)
1755 || attacktype(mtmp->data, AT_BOOM))
1756 pline("%s reconstitutes!", Monnam(mtmp));
1757 else
1758 pline("%s looks much better!", Monnam(mtmp));
1760 pline_The("medallion crumbles to dust!");
1762 m_useup(mtmp, lifesave);
1764 surviver = !(mvitals[monsndx(mtmp->data)].mvflags & G_GENOD);
1765 mtmp->mcanmove = 1;
1766 mtmp->mfrozen = 0;
1767 if (mtmp->mtame && !mtmp->isminion) {
1768 wary_dog(mtmp, !surviver);
1770 if (mtmp->mhpmax <= 0)
1771 mtmp->mhpmax = 10;
1772 mtmp->mhp = mtmp->mhpmax;
1773 if (surviver)
1774 return;
1776 /* genocided monster can't be life-saved */
1777 if (cansee(mtmp->mx, mtmp->my))
1778 pline("Unfortunately, %s is still genocided...", mon_nam(mtmp));
1780 mtmp->mhp = 0;
1783 void
1784 mondead(mtmp)
1785 register struct monst *mtmp;
1787 struct permonst *mptr;
1788 int tmp;
1790 lifesaved_monster(mtmp);
1791 if (mtmp->mhp > 0)
1792 return;
1794 if (is_vampshifter(mtmp)) {
1795 int mndx = mtmp->cham;
1796 int x = mtmp->mx, y = mtmp->my;
1798 /* this only happens if shapeshifted */
1799 if (mndx >= LOW_PM && mndx != monsndx(mtmp->data)
1800 && !(mvitals[mndx].mvflags & G_GENOD)) {
1801 char buf[BUFSZ];
1802 boolean in_door = (amorphous(mtmp->data)
1803 && closed_door(mtmp->mx, mtmp->my)),
1804 /* alternate message phrasing for some monster types */
1805 spec_mon = (nonliving(mtmp->data)
1806 || noncorporeal(mtmp->data)
1807 || amorphous(mtmp->data));
1809 /* construct a format string before transformation */
1810 Sprintf(buf, "The %s%s suddenly %s and rises as %%s!",
1811 spec_mon ? "" : "seemingly dead ",
1812 x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
1813 SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION
1814 | SUPPRESS_INVISIBLE | SUPPRESS_IT,
1815 FALSE),
1816 spec_mon ? "reconstitutes" : "transforms");
1817 mtmp->mcanmove = 1;
1818 mtmp->mfrozen = 0;
1819 if (mtmp->mhpmax <= 0)
1820 mtmp->mhpmax = 10;
1821 mtmp->mhp = mtmp->mhpmax;
1822 /* this can happen if previously a fog cloud */
1823 if (u.uswallow && (mtmp == u.ustuck))
1824 expels(mtmp, mtmp->data, FALSE);
1825 if (in_door) {
1826 coord new_xy;
1828 if (enexto(&new_xy, mtmp->mx, mtmp->my, &mons[mndx])) {
1829 rloc_to(mtmp, new_xy.x, new_xy.y);
1832 newcham(mtmp, &mons[mndx], FALSE, FALSE);
1833 if (mtmp->data == &mons[mndx])
1834 mtmp->cham = NON_PM;
1835 else
1836 mtmp->cham = mndx;
1837 if (canspotmon(mtmp)) {
1838 pline(buf, a_monnam(mtmp));
1839 vamp_rise_msg = TRUE;
1841 newsym(x, y);
1842 return;
1846 /* dead vault guard is actually kept at coordinate <0,0> until
1847 his temporary corridor to/from the vault has been removed;
1848 need to do this after life-saving and before m_detach() */
1849 if (mtmp->isgd && !grddead(mtmp))
1850 return;
1852 /* Player is thrown from his steed when it dies */
1853 if (mtmp == u.usteed)
1854 dismount_steed(DISMOUNT_GENERIC);
1856 mptr = mtmp->data; /* save this for m_detach() */
1857 /* restore chameleon, lycanthropes to true form at death */
1858 if (mtmp->cham >= LOW_PM) {
1859 set_mon_data(mtmp, &mons[mtmp->cham], -1);
1860 mtmp->cham = NON_PM;
1861 } else if (mtmp->data == &mons[PM_WEREJACKAL])
1862 set_mon_data(mtmp, &mons[PM_HUMAN_WEREJACKAL], -1);
1863 else if (mtmp->data == &mons[PM_WEREWOLF])
1864 set_mon_data(mtmp, &mons[PM_HUMAN_WEREWOLF], -1);
1865 else if (mtmp->data == &mons[PM_WERERAT])
1866 set_mon_data(mtmp, &mons[PM_HUMAN_WERERAT], -1);
1868 /* if MAXMONNO monsters of a given type have died, and it
1869 * can be done, extinguish that monster.
1871 * mvitals[].died does double duty as total number of dead monsters
1872 * and as experience factor for the player killing more monsters.
1873 * this means that a dragon dying by other means reduces the
1874 * experience the player gets for killing a dragon directly; this
1875 * is probably not too bad, since the player likely finagled the
1876 * first dead dragon via ring of conflict or pets, and extinguishing
1877 * based on only player kills probably opens more avenues of abuse
1878 * for rings of conflict and such.
1880 tmp = monsndx(mtmp->data);
1881 if (mvitals[tmp].died < 255)
1882 mvitals[tmp].died++;
1884 /* if it's a (possibly polymorphed) quest leader, mark him as dead */
1885 if (mtmp->m_id == quest_status.leader_m_id)
1886 quest_status.leader_is_dead = TRUE;
1887 #ifdef MAIL
1888 /* if the mail daemon dies, no more mail delivery. -3. */
1889 if (tmp == PM_MAIL_DAEMON)
1890 mvitals[tmp].mvflags |= G_GENOD;
1891 #endif
1893 if (mtmp->data->mlet == S_KOP) {
1894 /* Dead Kops may come back. */
1895 switch (rnd(5)) {
1896 case 1: /* returns near the stairs */
1897 (void) makemon(mtmp->data, xdnstair, ydnstair, NO_MM_FLAGS);
1898 break;
1899 case 2: /* randomly */
1900 (void) makemon(mtmp->data, 0, 0, NO_MM_FLAGS);
1901 break;
1902 default:
1903 break;
1906 if (mtmp->iswiz)
1907 wizdead();
1908 if (mtmp->data->msound == MS_NEMESIS)
1909 nemdead();
1910 if (mtmp->data == &mons[PM_MEDUSA])
1911 u.uachieve.killed_medusa = 1;
1912 if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
1913 unmap_object(mtmp->mx, mtmp->my);
1914 m_detach(mtmp, mptr);
1917 /* TRUE if corpse might be dropped, magr may die if mon was swallowed */
1918 boolean
1919 corpse_chance(mon, magr, was_swallowed)
1920 struct monst *mon;
1921 struct monst *magr; /* killer, if swallowed */
1922 boolean was_swallowed; /* digestion */
1924 struct permonst *mdat = mon->data;
1925 int i, tmp;
1927 if (mdat == &mons[PM_VLAD_THE_IMPALER] || mdat->mlet == S_LICH) {
1928 if (cansee(mon->mx, mon->my) && !was_swallowed)
1929 pline("%s body crumbles into dust.", s_suffix(Monnam(mon)));
1930 return FALSE;
1933 /* Gas spores always explode upon death */
1934 for (i = 0; i < NATTK; i++) {
1935 if (mdat->mattk[i].aatyp == AT_BOOM) {
1936 if (mdat->mattk[i].damn)
1937 tmp = d((int) mdat->mattk[i].damn, (int) mdat->mattk[i].damd);
1938 else if (mdat->mattk[i].damd)
1939 tmp = d((int) mdat->mlevel + 1, (int) mdat->mattk[i].damd);
1940 else
1941 tmp = 0;
1942 if (was_swallowed && magr) {
1943 if (magr == &youmonst) {
1944 There("is an explosion in your %s!", body_part(STOMACH));
1945 Sprintf(killer.name, "%s explosion",
1946 s_suffix(mdat->mname));
1947 losehp(Maybe_Half_Phys(tmp), killer.name, KILLED_BY_AN);
1948 } else {
1949 You_hear("an explosion.");
1950 magr->mhp -= tmp;
1951 if (magr->mhp < 1)
1952 mondied(magr);
1953 if (magr->mhp < 1) { /* maybe lifesaved */
1954 if (canspotmon(magr))
1955 pline("%s rips open!", Monnam(magr));
1956 } else if (canseemon(magr))
1957 pline("%s seems to have indigestion.", Monnam(magr));
1960 return FALSE;
1963 Sprintf(killer.name, "%s explosion", s_suffix(mdat->mname));
1964 killer.format = KILLED_BY_AN;
1965 explode(mon->mx, mon->my, -1, tmp, MON_EXPLODE, EXPL_NOXIOUS);
1966 return FALSE;
1970 /* must duplicate this below check in xkilled() since it results in
1971 * creating no objects as well as no corpse
1973 if (LEVEL_SPECIFIC_NOCORPSE(mdat))
1974 return FALSE;
1976 if (((bigmonst(mdat) || mdat == &mons[PM_LIZARD]) && !mon->mcloned)
1977 || is_golem(mdat) || is_mplayer(mdat) || is_rider(mdat))
1978 return TRUE;
1979 tmp = 2 + ((mdat->geno & G_FREQ) < 2) + verysmall(mdat);
1980 return (boolean) !rn2(tmp);
1983 /* drop (perhaps) a cadaver and remove monster */
1984 void
1985 mondied(mdef)
1986 register struct monst *mdef;
1988 mondead(mdef);
1989 if (mdef->mhp > 0)
1990 return; /* lifesaved */
1992 if (corpse_chance(mdef, (struct monst *) 0, FALSE)
1993 && (accessible(mdef->mx, mdef->my) || is_pool(mdef->mx, mdef->my)))
1994 (void) make_corpse(mdef, CORPSTAT_NONE);
1997 /* monster disappears, not dies */
1998 void
1999 mongone(mdef)
2000 struct monst *mdef;
2002 mdef->mhp = 0; /* can skip some inventory bookkeeping */
2004 /* dead vault guard is actually kept at coordinate <0,0> until
2005 his temporary corridor to/from the vault has been removed */
2006 if (mdef->isgd && !grddead(mdef))
2007 return;
2008 /* hero is thrown from his steed when it disappears */
2009 if (mdef == u.usteed)
2010 dismount_steed(DISMOUNT_GENERIC);
2011 /* drop special items like the Amulet so that a dismissed Kop or nurse
2012 can't remove them from the game */
2013 mdrop_special_objs(mdef);
2014 /* release rest of monster's inventory--it is removed from game */
2015 discard_minvent(mdef);
2016 m_detach(mdef, mdef->data);
2019 /* drop a statue or rock and remove monster */
2020 void
2021 monstone(mdef)
2022 struct monst *mdef;
2024 struct obj *otmp, *obj, *oldminvent;
2025 xchar x = mdef->mx, y = mdef->my;
2026 boolean wasinside = FALSE;
2028 /* we have to make the statue before calling mondead, to be able to
2029 * put inventory in it, and we have to check for lifesaving before
2030 * making the statue....
2032 lifesaved_monster(mdef);
2033 if (mdef->mhp > 0)
2034 return;
2036 mdef->mtrapped = 0; /* (see m_detach) */
2038 if ((int) mdef->data->msize > MZ_TINY
2039 || !rn2(2 + ((int) (mdef->data->geno & G_FREQ) > 2))) {
2040 oldminvent = 0;
2041 /* some objects may end up outside the statue */
2042 while ((obj = mdef->minvent) != 0) {
2043 obj_extract_self(obj);
2044 if (obj->owornmask)
2045 update_mon_intrinsics(mdef, obj, FALSE, TRUE);
2046 obj_no_longer_held(obj);
2047 if (obj->owornmask & W_WEP)
2048 setmnotwielded(mdef, obj);
2049 obj->owornmask = 0L;
2050 if (obj->otyp == BOULDER
2051 #if 0 /* monsters don't carry statues */
2052 || (obj->otyp == STATUE
2053 && mons[obj->corpsenm].msize >= mdef->data->msize)
2054 #endif
2055 /* invocation tools resist even with 0% resistance */
2056 || obj_resists(obj, 0, 0)) {
2057 if (flooreffects(obj, x, y, "fall"))
2058 continue;
2059 place_object(obj, x, y);
2060 } else {
2061 if (obj->lamplit)
2062 end_burn(obj, TRUE);
2063 obj->nobj = oldminvent;
2064 oldminvent = obj;
2067 /* defer statue creation until after inventory removal
2068 so that saved monster traits won't retain any stale
2069 item-conferred attributes */
2070 otmp = mkcorpstat(STATUE, mdef, mdef->data, x, y, CORPSTAT_NONE);
2071 if (has_mname(mdef))
2072 otmp = oname(otmp, MNAME(mdef));
2073 while ((obj = oldminvent) != 0) {
2074 oldminvent = obj->nobj;
2075 (void) add_to_container(otmp, obj);
2077 /* Archeologists should not break unique statues */
2078 if (mdef->data->geno & G_UNIQ)
2079 otmp->spe = 1;
2080 otmp->owt = weight(otmp);
2081 } else
2082 otmp = mksobj_at(ROCK, x, y, TRUE, FALSE);
2084 stackobj(otmp);
2085 /* mondead() already does this, but we must do it before the newsym */
2086 if (glyph_is_invisible(levl[x][y].glyph))
2087 unmap_object(x, y);
2088 if (cansee(x, y))
2089 newsym(x, y);
2090 /* We don't currently trap the hero in the statue in this case but we
2091 * could */
2092 if (u.uswallow && u.ustuck == mdef)
2093 wasinside = TRUE;
2094 mondead(mdef);
2095 if (wasinside) {
2096 if (is_animal(mdef->data))
2097 You("%s through an opening in the new %s.",
2098 locomotion(youmonst.data, "jump"), xname(otmp));
2102 /* another monster has killed the monster mdef */
2103 void
2104 monkilled(mdef, fltxt, how)
2105 struct monst *mdef;
2106 const char *fltxt;
2107 int how;
2109 boolean be_sad = FALSE; /* true if unseen pet is killed */
2111 if ((mdef->wormno ? worm_known(mdef) : cansee(mdef->mx, mdef->my))
2112 && fltxt)
2113 pline("%s is %s%s%s!", Monnam(mdef),
2114 nonliving(mdef->data) ? "destroyed" : "killed",
2115 *fltxt ? " by the " : "", fltxt);
2116 else
2117 be_sad = (mdef->mtame != 0);
2119 /* no corpses if digested or disintegrated */
2120 if (how == AD_DGST || how == -AD_RBRE)
2121 mondead(mdef);
2122 else
2123 mondied(mdef);
2125 if (be_sad && mdef->mhp <= 0)
2126 You("have a sad feeling for a moment, then it passes.");
2129 void
2130 unstuck(mtmp)
2131 struct monst *mtmp;
2133 if (u.ustuck == mtmp) {
2134 if (u.uswallow) {
2135 u.ux = mtmp->mx;
2136 u.uy = mtmp->my;
2137 u.uswallow = 0;
2138 u.uswldtim = 0;
2139 if (Punished && uchain->where != OBJ_FLOOR)
2140 placebc();
2141 vision_full_recalc = 1;
2142 docrt();
2144 u.ustuck = 0;
2148 void
2149 killed(mtmp)
2150 struct monst *mtmp;
2152 xkilled(mtmp, 1);
2155 /* the player has killed the monster mtmp */
2156 void
2157 xkilled(mtmp, dest)
2158 struct monst *mtmp;
2159 int dest; /* dest==1, normal; dest==0, don't print message; dest==2, don't
2160 drop corpse either; dest==3, message but no corpse */
2162 int tmp, mndx, x = mtmp->mx, y = mtmp->my;
2163 struct permonst *mdat;
2164 struct obj *otmp;
2165 struct trap *t;
2166 boolean wasinside = u.uswallow && (u.ustuck == mtmp);
2167 boolean burycorpse = FALSE;
2169 /* KMH, conduct */
2170 u.uconduct.killer++;
2172 if (dest & 1) {
2173 const char *verb = nonliving(mtmp->data) ? "destroy" : "kill";
2175 if (!wasinside && !canspotmon(mtmp))
2176 You("%s it!", verb);
2177 else {
2178 You("%s %s!", verb,
2179 !mtmp->mtame
2180 ? mon_nam(mtmp)
2181 : x_monnam(mtmp,
2182 (has_mname(mtmp)) ? ARTICLE_NONE : ARTICLE_THE,
2183 "poor",
2184 (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0,
2185 FALSE));
2189 if (mtmp->mtrapped && (t = t_at(x, y)) != 0
2190 && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
2191 if (sobj_at(BOULDER, x, y))
2192 dest |= 2; /*
2193 * Prevent corpses/treasure being created "on top"
2194 * of the boulder that is about to fall in. This is
2195 * out of order, but cannot be helped unless this
2196 * whole routine is rearranged.
2198 if (m_carrying(mtmp, BOULDER))
2199 burycorpse = TRUE;
2202 /* your pet knows who just killed it...watch out */
2203 if (mtmp->mtame && !mtmp->isminion)
2204 EDOG(mtmp)->killed_by_u = 1;
2206 if (wasinside && thrownobj && thrownobj != uball) {
2207 /* thrown object has killed hero's engulfer; add it to mon's
2208 inventory now so that it will be placed with mon's other
2209 stuff prior to lookhere/autopickup when hero is expelled
2210 below (as a side-effect, this missile has immunity from
2211 being consumed [for this shot/throw only]) */
2212 mpickobj(mtmp, thrownobj);
2213 /* let throwing code know that missile has been disposed of */
2214 thrownobj = 0;
2217 vamp_rise_msg = FALSE; /* might get set in mondead() */
2218 /* dispose of monster and make cadaver */
2219 if (stoned)
2220 monstone(mtmp);
2221 else
2222 mondead(mtmp);
2224 if (mtmp->mhp > 0) { /* monster lifesaved */
2225 /* Cannot put the non-visible lifesaving message in
2226 * lifesaved_monster() since the message appears only when you
2227 * kill it (as opposed to visible lifesaving which always
2228 * appears).
2230 stoned = FALSE;
2231 if (!cansee(x, y) && !vamp_rise_msg)
2232 pline("Maybe not...");
2233 return;
2236 mdat = mtmp->data; /* note: mondead can change mtmp->data */
2237 mndx = monsndx(mdat);
2239 if (stoned) {
2240 stoned = FALSE;
2241 goto cleanup;
2244 if ((dest & 2) || LEVEL_SPECIFIC_NOCORPSE(mdat))
2245 goto cleanup;
2247 #ifdef MAIL
2248 if (mdat == &mons[PM_MAIL_DAEMON]) {
2249 stackobj(mksobj_at(SCR_MAIL, x, y, FALSE, FALSE));
2251 #endif
2252 if (accessible(x, y) || is_pool(x, y)) {
2253 struct obj *cadaver;
2254 int otyp;
2256 /* illogical but traditional "treasure drop" */
2257 if (!rn2(6) && !(mvitals[mndx].mvflags & G_NOCORPSE)
2258 /* no extra item from swallower or steed */
2259 && (x != u.ux || y != u.uy)
2260 /* no extra item from kops--too easy to abuse */
2261 && mdat->mlet != S_KOP
2262 /* no items from cloned monsters */
2263 && !mtmp->mcloned) {
2264 otmp = mkobj(RANDOM_CLASS, TRUE);
2265 /* don't create large objects from small monsters */
2266 otyp = otmp->otyp;
2267 if (mdat->msize < MZ_HUMAN && otyp != FIGURINE
2268 /* oc_big is also oc_bimanual and oc_bulky */
2269 && (otmp->owt > 30 || objects[otyp].oc_big)) {
2270 delobj(otmp);
2271 } else if (!flooreffects(otmp, x, y, (dest & 1) ? "fall" : "")) {
2272 place_object(otmp, x, y);
2273 stackobj(otmp);
2276 /* corpse--none if hero was inside the monster */
2277 if (!wasinside && corpse_chance(mtmp, (struct monst *) 0, FALSE)) {
2278 cadaver = make_corpse(mtmp, burycorpse ? CORPSTAT_BURIED
2279 : CORPSTAT_NONE);
2280 if (burycorpse && cadaver && cansee(x, y) && !mtmp->minvis
2281 && cadaver->where == OBJ_BURIED && (dest & 1)) {
2282 pline("%s corpse ends up buried.", s_suffix(Monnam(mtmp)));
2286 if (wasinside)
2287 spoteffects(TRUE); /* poor man's expels() */
2288 /* monster is gone, corpse or other object might now be visible */
2289 newsym(x, y);
2291 cleanup:
2292 /* punish bad behaviour */
2293 if (is_human(mdat) && (!always_hostile(mdat) && mtmp->malign <= 0)
2294 && (mndx < PM_ARCHEOLOGIST || mndx > PM_WIZARD)
2295 && u.ualign.type != A_CHAOTIC) {
2296 HTelepat &= ~INTRINSIC;
2297 change_luck(-2);
2298 You("murderer!");
2299 if (Blind && !Blind_telepat)
2300 see_monsters(); /* Can't sense monsters any more. */
2302 if ((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame)
2303 change_luck(-1);
2304 if (is_unicorn(mdat) && sgn(u.ualign.type) == sgn(mdat->maligntyp)) {
2305 change_luck(-5);
2306 You_feel("guilty...");
2309 /* give experience points */
2310 tmp = experience(mtmp, (int) mvitals[mndx].died);
2311 more_experienced(tmp, 0);
2312 newexplevel(); /* will decide if you go up */
2314 /* adjust alignment points */
2315 if (mtmp->m_id == quest_status.leader_m_id) { /* REAL BAD! */
2316 adjalign(-(u.ualign.record + (int) ALIGNLIM / 2));
2317 pline("That was %sa bad idea...",
2318 u.uevent.qcompleted ? "probably " : "");
2319 } else if (mdat->msound == MS_NEMESIS) { /* Real good! */
2320 adjalign((int) (ALIGNLIM / 4));
2321 } else if (mdat->msound == MS_GUARDIAN) { /* Bad */
2322 adjalign(-(int) (ALIGNLIM / 8));
2323 if (!Hallucination)
2324 pline("That was probably a bad idea...");
2325 else
2326 pline("Whoopsie-daisy!");
2327 } else if (mtmp->ispriest) {
2328 adjalign((p_coaligned(mtmp)) ? -2 : 2);
2329 /* cancel divine protection for killing your priest */
2330 if (p_coaligned(mtmp))
2331 u.ublessed = 0;
2332 if (mdat->maligntyp == A_NONE)
2333 adjalign((int) (ALIGNLIM / 4)); /* BIG bonus */
2334 } else if (mtmp->mtame) {
2335 adjalign(-15); /* bad!! */
2336 /* your god is mighty displeased... */
2337 if (!Hallucination)
2338 You_hear("the rumble of distant thunder...");
2339 else
2340 You_hear("the studio audience applaud!");
2341 } else if (mtmp->mpeaceful)
2342 adjalign(-5);
2344 /* malign was already adjusted for u.ualign.type and randomization */
2345 adjalign(mtmp->malign);
2348 /* changes the monster into a stone monster of the same type
2349 this should only be called when poly_when_stoned() is true */
2350 void
2351 mon_to_stone(mtmp)
2352 struct monst *mtmp;
2354 if (mtmp->data->mlet == S_GOLEM) {
2355 /* it's a golem, and not a stone golem */
2356 if (canseemon(mtmp))
2357 pline("%s solidifies...", Monnam(mtmp));
2358 if (newcham(mtmp, &mons[PM_STONE_GOLEM], FALSE, FALSE)) {
2359 if (canseemon(mtmp))
2360 pline("Now it's %s.", an(mtmp->data->mname));
2361 } else {
2362 if (canseemon(mtmp))
2363 pline("... and returns to normal.");
2365 } else
2366 impossible("Can't polystone %s!", a_monnam(mtmp));
2369 boolean
2370 vamp_stone(mtmp)
2371 struct monst *mtmp;
2373 if (is_vampshifter(mtmp)) {
2374 int mndx = mtmp->cham;
2375 int x = mtmp->mx, y = mtmp->my;
2377 /* this only happens if shapeshifted */
2378 if (mndx >= LOW_PM && mndx != monsndx(mtmp->data)
2379 && !(mvitals[mndx].mvflags & G_GENOD)) {
2380 char buf[BUFSZ];
2381 boolean in_door = (amorphous(mtmp->data)
2382 && closed_door(mtmp->mx, mtmp->my));
2384 /* construct a format string before transformation */
2385 Sprintf(buf, "The lapidifying %s %s %s",
2386 x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
2387 SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION
2388 | SUPPRESS_INVISIBLE | SUPPRESS_IT,
2389 FALSE),
2390 amorphous(mtmp->data) ? "coalesces on the" :
2391 is_flyer(mtmp->data) ? "drops to the" : "writhes on the",
2392 surface(x,y));
2393 mtmp->mcanmove = 1;
2394 mtmp->mfrozen = 0;
2395 if (mtmp->mhpmax <= 0)
2396 mtmp->mhpmax = 10;
2397 mtmp->mhp = mtmp->mhpmax;
2398 /* this can happen if previously a fog cloud */
2399 if (u.uswallow && (mtmp == u.ustuck))
2400 expels(mtmp, mtmp->data, FALSE);
2401 if (in_door) {
2402 coord new_xy;
2404 if (enexto(&new_xy, mtmp->mx, mtmp->my, &mons[mndx])) {
2405 rloc_to(mtmp, new_xy.x, new_xy.y);
2408 if (canspotmon(mtmp)) {
2409 pline("%s!", buf);
2410 display_nhwindow(WIN_MESSAGE, FALSE);
2412 newcham(mtmp, &mons[mndx], FALSE, FALSE);
2413 if (mtmp->data == &mons[mndx])
2414 mtmp->cham = NON_PM;
2415 else
2416 mtmp->cham = mndx;
2417 if (canspotmon(mtmp)) {
2418 pline("%s rises from the %s with renewed agility!",
2419 Amonnam(mtmp), surface(mtmp->mx, mtmp->my));
2421 newsym(mtmp->mx, mtmp->my);
2422 return FALSE; /* didn't petrify */
2425 return TRUE;
2428 /* make monster mtmp next to you (if possible);
2429 might place monst on far side of a wall or boulder */
2430 void
2431 mnexto(mtmp)
2432 struct monst *mtmp;
2434 coord mm;
2435 boolean couldspot = canspotmon(mtmp);
2437 if (mtmp == u.usteed) {
2438 /* Keep your steed in sync with you instead */
2439 mtmp->mx = u.ux;
2440 mtmp->my = u.uy;
2441 return;
2444 if (!enexto(&mm, u.ux, u.uy, mtmp->data))
2445 return;
2446 rloc_to(mtmp, mm.x, mm.y);
2447 if (!in_mklev && (mtmp->mstrategy & STRAT_APPEARMSG)) {
2448 mtmp->mstrategy &= ~STRAT_APPEARMSG; /* one chance only */
2449 if (!couldspot && canspotmon(mtmp))
2450 pline("%s suddenly %s!", Amonnam(mtmp),
2451 !Blind ? "appears" : "arrives");
2453 return;
2456 /* like mnexto() but requires destination to be directly accessible */
2457 void
2458 maybe_mnexto(mtmp)
2459 struct monst *mtmp;
2461 coord mm;
2462 struct permonst *ptr = mtmp->data;
2463 boolean diagok = !NODIAG(ptr - mons);
2464 int tryct = 20;
2466 do {
2467 if (!enexto(&mm, u.ux, u.uy, ptr))
2468 return;
2469 if (couldsee(mm.x, mm.y)
2470 /* don't move grid bugs diagonally */
2471 && (diagok || mm.x == mtmp->mx || mm.y == mtmp->my)) {
2472 rloc_to(mtmp, mm.x, mm.y);
2473 return;
2475 } while (--tryct > 0);
2478 /* mnearto()
2479 * Put monster near (or at) location if possible.
2480 * Returns:
2481 * 1 - if a monster was moved from x, y to put mtmp at x, y.
2482 * 0 - in most cases.
2484 boolean
2485 mnearto(mtmp, x, y, move_other)
2486 register struct monst *mtmp;
2487 xchar x, y;
2488 boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */
2490 struct monst *othermon = (struct monst *) 0;
2491 xchar newx, newy;
2492 coord mm;
2494 if (mtmp->mx == x && mtmp->my == y)
2495 return FALSE;
2497 if (move_other && (othermon = m_at(x, y)) != 0) {
2498 if (othermon->wormno)
2499 remove_worm(othermon);
2500 else
2501 remove_monster(x, y);
2504 newx = x;
2505 newy = y;
2506 if (!goodpos(newx, newy, mtmp, 0)) {
2507 /* Actually we have real problems if enexto ever fails.
2508 * Migrating_mons that need to be placed will cause
2509 * no end of trouble.
2511 if (!enexto(&mm, newx, newy, mtmp->data))
2512 return FALSE;
2513 newx = mm.x;
2514 newy = mm.y;
2516 rloc_to(mtmp, newx, newy);
2518 if (move_other && othermon) {
2519 xchar oldx = othermon->mx, oldy = othermon->my;
2521 othermon->mx = othermon->my = 0;
2522 (void) mnearto(othermon, x, y, FALSE);
2523 if (othermon->mx == 0 && othermon->my == 0) {
2524 /* reloc failed, dump monster into "limbo"
2525 (aka migrate to current level) */
2526 othermon->mx = oldx;
2527 othermon->my = oldy;
2528 mdrop_special_objs(othermon);
2529 migrate_to_level(othermon, ledger_no(&u.uz), MIGR_APPROX_XY, NULL);
2533 return FALSE;
2536 /* monster responds to player action; not the same as a passive attack;
2537 assumes reason for response has been tested, and response _must_ be made */
2538 void
2539 m_respond(mtmp)
2540 struct monst *mtmp;
2542 if (mtmp->data->msound == MS_SHRIEK) {
2543 if (!Deaf) {
2544 pline("%s shrieks.", Monnam(mtmp));
2545 stop_occupation();
2547 if (!rn2(10)) {
2548 if (!rn2(13))
2549 (void) makemon(&mons[PM_PURPLE_WORM], 0, 0, NO_MM_FLAGS);
2550 else
2551 (void) makemon((struct permonst *) 0, 0, 0, NO_MM_FLAGS);
2553 aggravate();
2555 if (mtmp->data == &mons[PM_MEDUSA]) {
2556 register int i;
2558 for (i = 0; i < NATTK; i++)
2559 if (mtmp->data->mattk[i].aatyp == AT_GAZE) {
2560 (void) gazemu(mtmp, &mtmp->data->mattk[i]);
2561 break;
2566 void
2567 setmangry(mtmp)
2568 struct monst *mtmp;
2570 mtmp->mstrategy &= ~STRAT_WAITMASK;
2571 if (!mtmp->mpeaceful)
2572 return;
2573 if (mtmp->mtame)
2574 return;
2575 mtmp->mpeaceful = 0;
2576 if (mtmp->ispriest) {
2577 if (p_coaligned(mtmp))
2578 adjalign(-5); /* very bad */
2579 else
2580 adjalign(2);
2581 } else
2582 adjalign(-1); /* attacking peaceful monsters is bad */
2583 if (couldsee(mtmp->mx, mtmp->my)) {
2584 if (humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd)
2585 pline("%s gets angry!", Monnam(mtmp));
2586 else if (flags.verbose && !Deaf)
2587 growl(mtmp);
2590 /* attacking your own quest leader will anger his or her guardians */
2591 if (!context.mon_moving /* should always be the case here */
2592 && mtmp->data == &mons[quest_info(MS_LEADER)]) {
2593 struct monst *mon;
2594 struct permonst *q_guardian = &mons[quest_info(MS_GUARDIAN)];
2595 int got_mad = 0;
2597 /* guardians will sense this attack even if they can't see it */
2598 for (mon = fmon; mon; mon = mon->nmon) {
2599 if (DEADMONSTER(mon))
2600 continue;
2601 if (mon->data == q_guardian && mon->mpeaceful) {
2602 mon->mpeaceful = 0;
2603 if (canseemon(mon))
2604 ++got_mad;
2607 if (got_mad && !Hallucination)
2608 pline_The("%s appear%s to be angry too...",
2609 got_mad == 1 ? q_guardian->mname
2610 : makeplural(q_guardian->mname),
2611 got_mad == 1 ? "s" : "");
2615 /* wake up a monster, usually making it angry in the process */
2616 void
2617 wakeup(mtmp)
2618 register struct monst *mtmp;
2620 mtmp->msleeping = 0;
2621 finish_meating(mtmp);
2622 setmangry(mtmp);
2623 if (mtmp->m_ap_type) {
2624 seemimic(mtmp);
2625 } else if (context.forcefight && !context.mon_moving
2626 && mtmp->mundetected) {
2627 mtmp->mundetected = 0;
2628 newsym(mtmp->mx, mtmp->my);
2632 /* Wake up nearby monsters without angering them. */
2633 void
2634 wake_nearby()
2636 register struct monst *mtmp;
2638 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2639 if (DEADMONSTER(mtmp))
2640 continue;
2641 if (distu(mtmp->mx, mtmp->my) < u.ulevel * 20) {
2642 mtmp->msleeping = 0;
2643 if (!unique_corpstat(mtmp->data))
2644 mtmp->mstrategy &= ~STRAT_WAITMASK;
2645 if (mtmp->mtame && !mtmp->isminion)
2646 EDOG(mtmp)->whistletime = moves;
2651 /* Wake up monsters near some particular location. */
2652 void
2653 wake_nearto(x, y, distance)
2654 register int x, y, distance;
2656 register struct monst *mtmp;
2658 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2659 if (DEADMONSTER(mtmp))
2660 continue;
2661 if (distance == 0 || dist2(mtmp->mx, mtmp->my, x, y) < distance) {
2662 mtmp->msleeping = 0;
2663 if (!unique_corpstat(mtmp->data))
2664 mtmp->mstrategy &= ~STRAT_WAITMASK;
2669 /* NOTE: we must check for mimicry before calling this routine */
2670 void
2671 seemimic(mtmp)
2672 register struct monst *mtmp;
2674 boolean is_blocker_appear = (is_lightblocker_mappear(mtmp));
2676 if (has_mcorpsenm(mtmp))
2677 freemcorpsenm(mtmp);
2679 mtmp->m_ap_type = M_AP_NOTHING;
2680 mtmp->mappearance = 0;
2683 * Discovered mimics don't block light.
2685 if (is_blocker_appear
2686 && !does_block(mtmp->mx, mtmp->my, &levl[mtmp->mx][mtmp->my]))
2687 unblock_point(mtmp->mx, mtmp->my);
2689 newsym(mtmp->mx, mtmp->my);
2692 /* force all chameleons to become normal */
2693 void
2694 rescham()
2696 register struct monst *mtmp;
2697 int mcham;
2699 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2700 if (DEADMONSTER(mtmp))
2701 continue;
2702 mcham = (int) mtmp->cham;
2703 if (mcham >= LOW_PM) {
2704 (void) newcham(mtmp, &mons[mcham], FALSE, FALSE);
2705 mtmp->cham = NON_PM;
2707 if (is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN)
2708 new_were(mtmp);
2709 if (mtmp->m_ap_type && cansee(mtmp->mx, mtmp->my)) {
2710 seemimic(mtmp);
2711 /* we pretend that the mimic doesn't
2712 know that it has been unmasked */
2713 mtmp->msleeping = 1;
2718 /* Let the chameleons change again -dgk */
2719 void
2720 restartcham()
2722 register struct monst *mtmp;
2724 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2725 if (DEADMONSTER(mtmp))
2726 continue;
2727 mtmp->cham = pm_to_cham(monsndx(mtmp->data));
2728 if (mtmp->data->mlet == S_MIMIC && mtmp->msleeping
2729 && cansee(mtmp->mx, mtmp->my)) {
2730 set_mimic_sym(mtmp);
2731 newsym(mtmp->mx, mtmp->my);
2736 /* called when restoring a monster from a saved level; protection
2737 against shape-changing might be different now than it was at the
2738 time the level was saved. */
2739 void
2740 restore_cham(mon)
2741 struct monst *mon;
2743 int mcham;
2745 if (Protection_from_shape_changers) {
2746 mcham = (int) mon->cham;
2747 if (mcham >= LOW_PM) {
2748 mon->cham = NON_PM;
2749 (void) newcham(mon, &mons[mcham], FALSE, FALSE);
2750 } else if (is_were(mon->data) && !is_human(mon->data)) {
2751 new_were(mon);
2753 } else if (mon->cham == NON_PM) {
2754 mon->cham = pm_to_cham(monsndx(mon->data));
2758 /* unwatched hiders may hide again; if so, returns True */
2759 STATIC_OVL boolean
2760 restrap(mtmp)
2761 register struct monst *mtmp;
2763 struct trap *t;
2765 if (mtmp->mcan || mtmp->m_ap_type || cansee(mtmp->mx, mtmp->my)
2766 || rn2(3) || mtmp == u.ustuck
2767 /* can't hide while trapped except in pits */
2768 || (mtmp->mtrapped && (t = t_at(mtmp->mx, mtmp->my)) != 0
2769 && !(t->ttyp == PIT || t->ttyp == SPIKED_PIT))
2770 || (sensemon(mtmp) && distu(mtmp->mx, mtmp->my) <= 2))
2771 return FALSE;
2773 if (mtmp->data->mlet == S_MIMIC) {
2774 set_mimic_sym(mtmp);
2775 return TRUE;
2776 } else if (levl[mtmp->mx][mtmp->my].typ == ROOM) {
2777 mtmp->mundetected = 1;
2778 return TRUE;
2781 return FALSE;
2784 /* monster/hero tries to hide under something at the current location */
2785 boolean
2786 hideunder(mtmp)
2787 struct monst *mtmp;
2789 struct trap *t;
2790 boolean undetected = FALSE, is_u = (mtmp == &youmonst);
2791 xchar x = is_u ? u.ux : mtmp->mx, y = is_u ? u.uy : mtmp->my;
2793 if (mtmp == u.ustuck) {
2794 ; /* can't hide if holding you or held by you */
2795 } else if (is_u ? (u.utrap && u.utraptype != TT_PIT)
2796 : (mtmp->mtrapped && (t = t_at(x, y)) != 0
2797 && !(t->ttyp == PIT || t->ttyp == SPIKED_PIT))) {
2798 ; /* can't hide while stuck in a non-pit trap */
2799 } else if (mtmp->data->mlet == S_EEL) {
2800 undetected = (is_pool(x, y) && !Is_waterlevel(&u.uz));
2801 } else if (hides_under(mtmp->data) && OBJ_AT(x, y)) {
2802 struct obj *otmp = level.objects[x][y];
2804 /* most monsters won't hide under cockatrice corpse */
2805 if (otmp->nexthere || otmp->otyp != CORPSE
2806 || (mtmp == &youmonst ? Stone_resistance : resists_ston(mtmp))
2807 || !touch_petrifies(&mons[otmp->corpsenm]))
2808 undetected = TRUE;
2811 if (is_u)
2812 u.uundetected = undetected;
2813 else
2814 mtmp->mundetected = undetected;
2815 return undetected;
2818 /* called when returning to a previously visited level */
2819 void
2820 hide_monst(mon)
2821 struct monst *mon;
2823 boolean hider_under = hides_under(mon->data) || mon->data->mlet == S_EEL;
2825 if ((is_hider(mon->data) || hider_under)
2826 && !(mon->mundetected || mon->m_ap_type)) {
2827 xchar x = mon->mx, y = mon->my;
2828 char save_viz = viz_array[y][x];
2830 /* override vision, forcing hero to be unable to see monster's spot */
2831 viz_array[y][x] &= ~(IN_SIGHT | COULD_SEE);
2832 if (is_hider(mon->data))
2833 (void) restrap(mon);
2834 /* try again if mimic missed its 1/3 chance to hide */
2835 if (mon->data->mlet == S_MIMIC && !mon->m_ap_type)
2836 (void) restrap(mon);
2837 if (hider_under)
2838 (void) hideunder(mon);
2839 viz_array[y][x] = save_viz;
2843 static short *animal_list = 0; /* list of PM values for animal monsters */
2844 static int animal_list_count;
2846 void
2847 mon_animal_list(construct)
2848 boolean construct;
2850 if (construct) {
2851 short animal_temp[SPECIAL_PM];
2852 int i, n;
2854 /* if (animal_list) impossible("animal_list already exists"); */
2856 for (n = 0, i = LOW_PM; i < SPECIAL_PM; i++)
2857 if (is_animal(&mons[i]))
2858 animal_temp[n++] = i;
2859 /* if (n == 0) animal_temp[n++] = NON_PM; */
2861 animal_list = (short *) alloc(n * sizeof *animal_list);
2862 (void) memcpy((genericptr_t) animal_list, (genericptr_t) animal_temp,
2863 n * sizeof *animal_list);
2864 animal_list_count = n;
2865 } else { /* release */
2866 if (animal_list)
2867 free((genericptr_t) animal_list), animal_list = 0;
2868 animal_list_count = 0;
2872 STATIC_OVL int
2873 pick_animal()
2875 int res;
2877 if (!animal_list)
2878 mon_animal_list(TRUE);
2880 res = animal_list[rn2(animal_list_count)];
2881 /* rogue level should use monsters represented by uppercase letters
2882 only, but since chameleons aren't generated there (not uppercase!)
2883 we don't perform a lot of retries */
2884 if (Is_rogue_level(&u.uz) && !isupper((uchar) mons[res].mlet))
2885 res = animal_list[rn2(animal_list_count)];
2886 return res;
2889 void
2890 decide_to_shapeshift(mon, shiftflags)
2891 struct monst *mon;
2892 int shiftflags;
2894 struct permonst *ptr;
2895 unsigned was_female = mon->female;
2896 boolean msg = FALSE;
2898 if ((shiftflags & SHIFT_MSG)
2899 || ((shiftflags & SHIFT_SEENMSG) && sensemon(mon)))
2900 msg = TRUE;
2902 if (!is_vampshifter(mon)) {
2903 /* regular shapeshifter */
2904 if (!rn2(6))
2905 (void) newcham(mon, (struct permonst *) 0, FALSE, msg);
2906 } else {
2907 /* The vampire has to be in good health (mhp) to maintain
2908 * its shifted form.
2910 * If we're shifted and getting low on hp, maybe shift back.
2911 * If we're not already shifted and in good health, maybe shift.
2913 if (mon->data->mlet != S_VAMPIRE) {
2914 if ((mon->mhp <= (mon->mhpmax + 5) / 6) && rn2(4)
2915 && mon->cham >= LOW_PM)
2916 (void) newcham(mon, &mons[mon->cham], FALSE, msg);
2917 } else {
2918 if (mon->mhp >= 9 * mon->mhpmax / 10 && !rn2(6)
2919 && (!canseemon(mon)
2920 || distu(mon->mx, mon->my) > BOLT_LIM * BOLT_LIM))
2921 (void) newcham(mon, (struct permonst *) 0, FALSE, msg);
2923 /* override the 10% chance for sex change */
2924 ptr = mon->data;
2925 if (!is_male(ptr) && !is_female(ptr) && !is_neuter(ptr))
2926 mon->female = was_female;
2930 STATIC_OVL int
2931 pickvampshape(mon)
2932 struct monst *mon;
2934 int mndx = mon->cham, wolfchance = 10;
2935 /* avoid picking monsters with lowercase display symbols ('d' for wolf
2936 and 'v' for fog cloud) on rogue level*/
2937 boolean uppercase_only = Is_rogue_level(&u.uz);
2939 switch (mndx) {
2940 case PM_VLAD_THE_IMPALER:
2941 /* ensure Vlad can keep carrying the Candelabrum */
2942 if (mon_has_special(mon))
2943 break; /* leave mndx as is */
2944 wolfchance = 3;
2945 /*FALLTHRU*/
2946 case PM_VAMPIRE_LORD: /* vampire lord or Vlad can become wolf */
2947 if (!rn2(wolfchance) && !uppercase_only) {
2948 mndx = PM_WOLF;
2949 break;
2951 /*FALLTHRU*/
2952 case PM_VAMPIRE: /* any vampire can become fog or bat */
2953 mndx = (!rn2(4) && !uppercase_only) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT;
2954 break;
2956 return mndx;
2959 /* nonshapechangers who warrant special polymorph handling */
2960 STATIC_OVL boolean
2961 isspecmon(mon)
2962 struct monst *mon;
2964 return (mon->isshk || mon->ispriest || mon->isgd
2965 || mon->m_id == quest_status.leader_m_id);
2968 /* restrict certain special monsters (shopkeepers, aligned priests,
2969 vault guards) to forms that allow them to behave sensibly (catching
2970 gold, speaking?) so that they don't need too much extra code */
2971 STATIC_OVL boolean
2972 validspecmon(mon, mndx)
2973 struct monst *mon;
2974 int mndx;
2976 if (mndx == NON_PM)
2977 return TRUE; /* caller wants random */
2979 if (!accept_newcham_form(mndx))
2980 return FALSE; /* geno'd or !polyok */
2982 if (isspecmon(mon)) {
2983 struct permonst *ptr = &mons[mndx];
2985 /* reject notake because object manipulation is expected
2986 and nohead because speech capability is expected */
2987 if (notake(ptr) || !has_head(ptr))
2988 return FALSE;
2989 /* [should we check ptr->msound here too?] */
2991 return TRUE; /* potential new form is ok */
2994 /* prevent wizard mode user from specifying invalid vampshifter shape */
2995 STATIC_OVL boolean
2996 validvamp(mon, mndx_p, monclass)
2997 struct monst *mon;
2998 int *mndx_p, monclass;
3000 /* simplify caller's usage */
3001 if (!is_vampshifter(mon))
3002 return validspecmon(mon, *mndx_p);
3004 if (*mndx_p == PM_VAMPIRE || *mndx_p == PM_VAMPIRE_LORD
3005 || *mndx_p == PM_VLAD_THE_IMPALER) {
3006 /* player picked some type of vampire; use mon's self */
3007 *mndx_p = mon->cham;
3008 return TRUE;
3010 if (mon->cham == PM_VLAD_THE_IMPALER && mon_has_special(mon)) {
3011 /* Vlad with Candelabrum; override choice, then accept it */
3012 *mndx_p = PM_VLAD_THE_IMPALER;
3013 return TRUE;
3015 /* basic vampires can't become wolves; any can become fog or bat
3016 (we don't enforce upper-case only for rogue level here) */
3017 if (*mndx_p == PM_WOLF)
3018 return (boolean) (mon->cham != PM_VAMPIRE);
3019 if (*mndx_p == PM_FOG_CLOUD || *mndx_p == PM_VAMPIRE_BAT)
3020 return TRUE;
3022 /* if we get here, specific type was no good; try by class */
3023 switch (monclass) {
3024 case S_VAMPIRE:
3025 *mndx_p = mon->cham;
3026 break;
3027 case S_BAT:
3028 *mndx_p = PM_VAMPIRE_BAT;
3029 break;
3030 case S_VORTEX:
3031 *mndx_p = PM_FOG_CLOUD;
3032 break;
3033 case S_DOG:
3034 if (mon->cham != PM_VAMPIRE) {
3035 *mndx_p = PM_WOLF;
3036 break;
3038 /*FALLTHRU*/
3039 default:
3040 *mndx_p = NON_PM;
3041 break;
3043 return (boolean) (*mndx_p != NON_PM);
3047 select_newcham_form(mon)
3048 struct monst *mon;
3050 int mndx = NON_PM, tryct;
3052 switch (mon->cham) {
3053 case PM_SANDESTIN:
3054 if (rn2(7))
3055 mndx = pick_nasty();
3056 break;
3057 case PM_DOPPELGANGER:
3058 if (!rn2(7)) {
3059 mndx = pick_nasty();
3060 } else if (rn2(3)) { /* role monsters */
3061 mndx = rn1(PM_WIZARD - PM_ARCHEOLOGIST + 1, PM_ARCHEOLOGIST);
3062 } else if (!rn2(3)) { /* quest guardians */
3063 mndx = rn1(PM_APPRENTICE - PM_STUDENT + 1, PM_STUDENT);
3064 /* avoid own role's guardian */
3065 if (mndx == urole.guardnum)
3066 mndx = NON_PM;
3067 } else { /* general humanoids */
3068 tryct = 5;
3069 do {
3070 mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
3071 if (humanoid(&mons[mndx]) && polyok(&mons[mndx]))
3072 break;
3073 } while (--tryct > 0);
3074 if (!tryct)
3075 mndx = NON_PM;
3077 break;
3078 case PM_CHAMELEON:
3079 if (!rn2(3))
3080 mndx = pick_animal();
3081 break;
3082 case PM_VLAD_THE_IMPALER:
3083 case PM_VAMPIRE_LORD:
3084 case PM_VAMPIRE:
3085 mndx = pickvampshape(mon);
3086 break;
3087 case NON_PM: /* ordinary */
3089 struct obj *m_armr = which_armor(mon, W_ARM);
3091 if (m_armr && Is_dragon_scales(m_armr))
3092 mndx = (int) (Dragon_scales_to_pm(m_armr) - mons);
3093 else if (m_armr && Is_dragon_mail(m_armr))
3094 mndx = (int) (Dragon_mail_to_pm(m_armr) - mons);
3096 break;
3099 /* for debugging: allow control of polymorphed monster */
3100 if (wizard && iflags.mon_polycontrol) {
3101 char pprompt[BUFSZ], buf[BUFSZ];
3102 int monclass;
3104 Sprintf(pprompt, "Change %s @ %s into what kind of monster?",
3105 noit_mon_nam(mon),
3106 coord_desc((int) mon->mx, (int) mon->my, buf,
3107 (iflags.getpos_coords != GPCOORDS_NONE)
3108 ? iflags.getpos_coords : GPCOORDS_MAP));
3109 tryct = 5;
3110 do {
3111 monclass = 0;
3112 getlin(pprompt, buf);
3113 mungspaces(buf);
3114 /* for ESC, take form selected above (might be NON_PM) */
3115 if (*buf == '\033')
3116 break;
3117 /* for "*", use NON_PM to pick an arbitrary shape below */
3118 if (!strcmp(buf, "*") || !strcmp(buf, "random")) {
3119 mndx = NON_PM;
3120 break;
3122 mndx = name_to_mon(buf);
3123 if (mndx == NON_PM) {
3124 /* didn't get a type, so check whether it's a class
3125 (single letter or text match with def_monsyms[]) */
3126 monclass = name_to_monclass(buf, &mndx);
3127 if (monclass && mndx == NON_PM)
3128 mndx = mkclass_poly(monclass);
3130 if (mndx >= LOW_PM) {
3131 /* got a specific type of monster; use it if we can */
3132 if (validvamp(mon, &mndx, monclass))
3133 break;
3134 /* can't; revert to random in case we exhaust tryct */
3135 mndx = NON_PM;
3138 pline("It can't become that.");
3139 } while (--tryct > 0);
3140 if (!tryct)
3141 pline1(thats_enough_tries);
3142 if (is_vampshifter(mon) && !validvamp(mon, &mndx, monclass))
3143 mndx = pickvampshape(mon); /* don't resort to arbitrary */
3146 /* if no form was specified above, pick one at random now */
3147 if (mndx == NON_PM) {
3148 tryct = 50;
3149 do {
3150 mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
3151 } while (--tryct > 0 && !validspecmon(mon, mndx)
3152 /* try harder to select uppercase monster on rogue level */
3153 && (tryct > 40 && Is_rogue_level(&u.uz)
3154 && !isupper((uchar) mons[mndx].mlet)));
3156 return mndx;
3159 /* this used to be inline within newcham() but monpolycontrol needs it too */
3160 STATIC_OVL struct permonst *
3161 accept_newcham_form(mndx)
3162 int mndx;
3164 struct permonst *mdat;
3166 if (mndx == NON_PM)
3167 return 0;
3168 mdat = &mons[mndx];
3169 if ((mvitals[mndx].mvflags & G_GENOD) != 0)
3170 return 0;
3171 if (is_placeholder(mdat))
3172 return 0;
3173 /* select_newcham_form() might deliberately pick a player
3174 character type (random selection never does) which
3175 polyok() rejects, so we need a special case here */
3176 if (is_mplayer(mdat))
3177 return mdat;
3178 /* polyok() rules out M2_PNAME, M2_WERE, and all humans except Kops */
3179 return polyok(mdat) ? mdat : 0;
3182 void
3183 mgender_from_permonst(mtmp, mdat)
3184 struct monst *mtmp;
3185 struct permonst *mdat;
3187 if (is_male(mdat)) {
3188 if (mtmp->female)
3189 mtmp->female = FALSE;
3190 } else if (is_female(mdat)) {
3191 if (!mtmp->female)
3192 mtmp->female = TRUE;
3193 } else if (!is_neuter(mdat)) {
3194 if (!rn2(10))
3195 mtmp->female = !mtmp->female;
3199 /* make a chameleon take on another shape, or a polymorph target
3200 (possibly self-inflicted) become a different monster;
3201 returns 1 if it actually changes form */
3203 newcham(mtmp, mdat, polyspot, msg)
3204 struct monst *mtmp;
3205 struct permonst *mdat;
3206 boolean polyspot; /* change is the result of wand or spell of polymorph */
3207 boolean msg; /* "The oldmon turns into a newmon!" */
3209 int hpn, hpd;
3210 int mndx, tryct;
3211 struct permonst *olddata = mtmp->data;
3212 char oldname[BUFSZ], l_oldname[BUFSZ], newname[BUFSZ];
3214 /* Riders are immune to polymorph and green slime
3215 (but apparent Rider might actually be a doppelganger) */
3216 if (is_rider(mtmp->data) && mtmp->cham == NON_PM)
3217 return 0;
3219 if (msg) {
3220 /* like Monnam() but never mention saddle */
3221 Strcpy(oldname, x_monnam(mtmp, ARTICLE_THE, (char *) 0,
3222 SUPPRESS_SADDLE, FALSE));
3223 oldname[0] = highc(oldname[0]);
3225 /* we need this one whether msg is true or not */
3226 Strcpy(l_oldname, x_monnam(mtmp, ARTICLE_THE, (char *) 0,
3227 (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE));
3229 /* mdat = 0 -> caller wants a random monster shape */
3230 if (mdat == 0) {
3231 /* select_newcham_form() loops when resorting to random but
3232 it doesn't always pick that so we still retry here too */
3233 tryct = 20;
3234 do {
3235 mndx = select_newcham_form(mtmp);
3236 mdat = accept_newcham_form(mndx);
3237 /* for the first several tries we require upper-case on
3238 the rogue level (after that, we take whatever we get) */
3239 if (tryct > 15 && Is_rogue_level(&u.uz)
3240 && mdat && !isupper((uchar) mdat->mlet))
3241 mdat = 0;
3242 if (mdat)
3243 break;
3244 } while (--tryct > 0);
3245 if (!tryct)
3246 return 0;
3247 } else if (mvitals[monsndx(mdat)].mvflags & G_GENOD)
3248 return 0; /* passed in mdat is genocided */
3250 if (mdat == mtmp->data)
3251 return 0; /* still the same monster */
3253 mgender_from_permonst(mtmp, mdat);
3255 if (In_endgame(&u.uz) && is_mplayer(olddata) && has_mname(mtmp)) {
3256 /* mplayers start out as "Foo the Bar", but some of the
3257 * titles are inappropriate when polymorphed, particularly
3258 * into the opposite sex. players don't use ranks when
3259 * polymorphed, so dropping the rank for mplayers seems
3260 * reasonable.
3262 char *p = index(MNAME(mtmp), ' ');
3264 if (p)
3265 *p = '\0';
3268 if (mtmp->wormno) { /* throw tail away */
3269 wormgone(mtmp);
3270 place_monster(mtmp, mtmp->mx, mtmp->my);
3272 if (mtmp->m_ap_type && mdat->mlet != S_MIMIC)
3273 seemimic(mtmp); /* revert to normal monster */
3275 /* (this code used to try to adjust the monster's health based on
3276 a normal one of its type but there are too many special cases
3277 which need to handled in order to do that correctly, so just
3278 give the new form the same proportion of HP as its old one had) */
3279 hpn = mtmp->mhp;
3280 hpd = mtmp->mhpmax;
3281 /* set level and hit points */
3282 newmonhp(mtmp, monsndx(mdat));
3283 /* new hp: same fraction of max as before */
3284 #ifndef LINT
3285 mtmp->mhp = (int) (((long) hpn * (long) mtmp->mhp) / (long) hpd);
3286 #endif
3287 /* sanity check (potential overflow) */
3288 if (mtmp->mhp < 0 || mtmp->mhp > mtmp->mhpmax)
3289 mtmp->mhp = mtmp->mhpmax;
3290 /* unlikely but not impossible; a 1HD creature with 1HP that changes
3291 into a 0HD creature will require this statement */
3292 if (!mtmp->mhp)
3293 mtmp->mhp = 1;
3295 /* take on the new form... */
3296 set_mon_data(mtmp, mdat, 0);
3298 if (emits_light(olddata) != emits_light(mtmp->data)) {
3299 /* used to give light, now doesn't, or vice versa,
3300 or light's range has changed */
3301 if (emits_light(olddata))
3302 del_light_source(LS_MONSTER, monst_to_any(mtmp));
3303 if (emits_light(mtmp->data))
3304 new_light_source(mtmp->mx, mtmp->my, emits_light(mtmp->data),
3305 LS_MONSTER, monst_to_any(mtmp));
3307 if (!mtmp->perminvis || pm_invisible(olddata))
3308 mtmp->perminvis = pm_invisible(mdat);
3309 mtmp->minvis = mtmp->invis_blkd ? 0 : mtmp->perminvis;
3310 if (mtmp->mundetected)
3311 (void) hideunder(mtmp);
3312 if (u.ustuck == mtmp) {
3313 if (u.uswallow) {
3314 if (!attacktype(mdat, AT_ENGL)) {
3315 /* Does mdat care? */
3316 if (!noncorporeal(mdat) && !amorphous(mdat)
3317 && !is_whirly(mdat) && (mdat != &mons[PM_YELLOW_LIGHT])) {
3318 char msgtrail[BUFSZ];
3320 if (is_vampshifter(mtmp)) {
3321 Sprintf(msgtrail, " which was a shapeshifted %s",
3322 m_monnam(mtmp));
3323 } else if (is_animal(mdat)) {
3324 Strcpy(msgtrail, "'s stomach");
3325 } else {
3326 msgtrail[0] = '\0';
3329 /* Do this even if msg is FALSE */
3330 You("%s %s%s!",
3331 (amorphous(olddata) || is_whirly(olddata))
3332 ? "emerge from" : "break out of",
3333 l_oldname, msgtrail);
3334 msg = FALSE; /* message has been given */
3335 mtmp->mhp = 1; /* almost dead */
3337 expels(mtmp, olddata, FALSE);
3338 } else {
3339 /* update swallow glyphs for new monster */
3340 swallowed(0);
3342 } else if (!sticks(mdat) && !sticks(youmonst.data))
3343 unstuck(mtmp);
3346 #ifndef DCC30_BUG
3347 if (mdat == &mons[PM_LONG_WORM] && (mtmp->wormno = get_wormno()) != 0) {
3348 #else
3349 /* DICE 3.0 doesn't like assigning and comparing mtmp->wormno in the
3350 * same expression.
3352 if (mdat == &mons[PM_LONG_WORM]
3353 && (mtmp->wormno = get_wormno(), mtmp->wormno != 0)) {
3354 #endif
3355 /* we can now create worms with tails - 11/91 */
3356 initworm(mtmp, rn2(5));
3357 if (count_wsegs(mtmp))
3358 place_worm_tail_randomly(mtmp, mtmp->mx, mtmp->my);
3361 newsym(mtmp->mx, mtmp->my);
3363 if (msg) {
3364 char *save_mname = 0;
3366 if (has_mname(mtmp)) {
3367 save_mname = MNAME(mtmp);
3368 MNAME(mtmp) = (char *) 0;
3370 Strcpy(newname, (mdat == &mons[PM_GREEN_SLIME])
3371 ? "slime"
3372 : x_monnam(mtmp, ARTICLE_A, (char *) 0,
3373 SUPPRESS_SADDLE, FALSE));
3374 if (!strcmpi(oldname, "it") && !strcmpi(newname, "it"))
3375 (void) usmellmon(mdat);
3376 else
3377 pline("%s turns into %s!", oldname, newname);
3378 if (save_mname)
3379 MNAME(mtmp) = save_mname;
3382 /* when polymorph trap/wand/potion produces a vampire, turn in into
3383 a full-fledged vampshifter unless shape-changing is blocked */
3384 if (mtmp->cham == NON_PM && mdat->mlet == S_VAMPIRE
3385 && !Protection_from_shape_changers)
3386 mtmp->cham = pm_to_cham(monsndx(mdat));
3388 possibly_unwield(mtmp, polyspot); /* might lose use of weapon */
3389 mon_break_armor(mtmp, polyspot);
3390 if (!(mtmp->misc_worn_check & W_ARMG))
3391 mselftouch(mtmp, "No longer petrify-resistant, ",
3392 !context.mon_moving);
3393 m_dowear(mtmp, FALSE);
3395 /* This ought to re-test can_carry() on each item in the inventory
3396 * rather than just checking ex-giants & boulders, but that'd be
3397 * pretty expensive to perform. If implemented, then perhaps
3398 * minvent should be sorted in order to drop heaviest items first.
3400 /* former giants can't continue carrying boulders */
3401 if (mtmp->minvent && !throws_rocks(mdat)) {
3402 register struct obj *otmp, *otmp2;
3404 for (otmp = mtmp->minvent; otmp; otmp = otmp2) {
3405 otmp2 = otmp->nobj;
3406 if (otmp->otyp == BOULDER) {
3407 /* this keeps otmp from being polymorphed in the
3408 same zap that the monster that held it is polymorphed */
3409 if (polyspot)
3410 bypass_obj(otmp);
3411 obj_extract_self(otmp);
3412 /* probably ought to give some "drop" message here */
3413 if (flooreffects(otmp, mtmp->mx, mtmp->my, ""))
3414 continue;
3415 place_object(otmp, mtmp->mx, mtmp->my);
3420 return 1;
3423 /* sometimes an egg will be special */
3424 #define BREEDER_EGG (!rn2(77))
3427 * Determine if the given monster number can be hatched from an egg.
3428 * Return the monster number to use as the egg's corpsenm. Return
3429 * NON_PM if the given monster can't be hatched.
3432 can_be_hatched(mnum)
3433 int mnum;
3435 /* ranger quest nemesis has the oviparous bit set, making it
3436 be possible to wish for eggs of that unique monster; turn
3437 such into ordinary eggs rather than forbidding them outright */
3438 if (mnum == PM_SCORPIUS)
3439 mnum = PM_SCORPION;
3441 mnum = little_to_big(mnum);
3443 * Queen bees lay killer bee eggs (usually), but killer bees don't
3444 * grow into queen bees. Ditto for [winged-]gargoyles.
3446 if (mnum == PM_KILLER_BEE || mnum == PM_GARGOYLE
3447 || (lays_eggs(&mons[mnum])
3448 && (BREEDER_EGG
3449 || (mnum != PM_QUEEN_BEE && mnum != PM_WINGED_GARGOYLE))))
3450 return mnum;
3451 return NON_PM;
3454 /* type of egg laid by #sit; usually matches parent */
3456 egg_type_from_parent(mnum, force_ordinary)
3457 int mnum; /* parent monster; caller must handle lays_eggs() check */
3458 boolean force_ordinary;
3460 if (force_ordinary || !BREEDER_EGG) {
3461 if (mnum == PM_QUEEN_BEE)
3462 mnum = PM_KILLER_BEE;
3463 else if (mnum == PM_WINGED_GARGOYLE)
3464 mnum = PM_GARGOYLE;
3466 return mnum;
3469 /* decide whether an egg of the indicated monster type is viable;
3470 also used to determine whether an egg or tin can be created... */
3471 boolean
3472 dead_species(m_idx, egg)
3473 int m_idx;
3474 boolean egg;
3476 int alt_idx;
3478 /* generic eggs are unhatchable and have corpsenm of NON_PM */
3479 if (m_idx < LOW_PM)
3480 return TRUE;
3482 * For monsters with both baby and adult forms, genociding either
3483 * form kills all eggs of that monster. Monsters with more than
3484 * two forms (small->large->giant mimics) are more or less ignored;
3485 * fortunately, none of them have eggs. Species extinction due to
3486 * overpopulation does not kill eggs.
3488 alt_idx = egg ? big_to_little(m_idx) : m_idx;
3489 return (boolean) ((mvitals[m_idx].mvflags & G_GENOD) != 0
3490 || (mvitals[alt_idx].mvflags & G_GENOD) != 0);
3493 /* kill off any eggs of genocided monsters */
3494 STATIC_OVL void
3495 kill_eggs(obj_list)
3496 struct obj *obj_list;
3498 struct obj *otmp;
3500 for (otmp = obj_list; otmp; otmp = otmp->nobj)
3501 if (otmp->otyp == EGG) {
3502 if (dead_species(otmp->corpsenm, TRUE)) {
3504 * It seems we could also just catch this when
3505 * it attempted to hatch, so we wouldn't have to
3506 * search all of the objlists.. or stop all
3507 * hatch timers based on a corpsenm.
3509 kill_egg(otmp);
3511 #if 0 /* not used */
3512 } else if (otmp->otyp == TIN) {
3513 if (dead_species(otmp->corpsenm, FALSE))
3514 otmp->corpsenm = NON_PM; /* empty tin */
3515 } else if (otmp->otyp == CORPSE) {
3516 if (dead_species(otmp->corpsenm, FALSE))
3517 ; /* not yet implemented... */
3518 #endif
3519 } else if (Has_contents(otmp)) {
3520 kill_eggs(otmp->cobj);
3524 /* kill all members of genocided species */
3525 void
3526 kill_genocided_monsters()
3528 struct monst *mtmp, *mtmp2;
3529 boolean kill_cham;
3530 int mndx;
3533 * Called during genocide, and again upon level change. The latter
3534 * catches up with any migrating monsters as they finally arrive at
3535 * their intended destinations, so possessions get deposited there.
3537 * Chameleon handling:
3538 * 1) if chameleons have been genocided, destroy them
3539 * regardless of current form;
3540 * 2) otherwise, force every chameleon which is imitating
3541 * any genocided species to take on a new form.
3543 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
3544 mtmp2 = mtmp->nmon;
3545 if (DEADMONSTER(mtmp))
3546 continue;
3547 mndx = monsndx(mtmp->data);
3548 kill_cham = (mtmp->cham >= LOW_PM
3549 && (mvitals[mtmp->cham].mvflags & G_GENOD));
3550 if ((mvitals[mndx].mvflags & G_GENOD) || kill_cham) {
3551 if (mtmp->cham >= LOW_PM && !kill_cham)
3552 (void) newcham(mtmp, (struct permonst *) 0, FALSE, FALSE);
3553 else
3554 mondead(mtmp);
3556 if (mtmp->minvent)
3557 kill_eggs(mtmp->minvent);
3560 kill_eggs(invent);
3561 kill_eggs(fobj);
3562 kill_eggs(migrating_objs);
3563 kill_eggs(level.buriedobjlist);
3566 void
3567 golemeffects(mon, damtype, dam)
3568 register struct monst *mon;
3569 int damtype, dam;
3571 int heal = 0, slow = 0;
3573 if (mon->data == &mons[PM_FLESH_GOLEM]) {
3574 if (damtype == AD_ELEC)
3575 heal = (dam + 5) / 6;
3576 else if (damtype == AD_FIRE || damtype == AD_COLD)
3577 slow = 1;
3578 } else if (mon->data == &mons[PM_IRON_GOLEM]) {
3579 if (damtype == AD_ELEC)
3580 slow = 1;
3581 else if (damtype == AD_FIRE)
3582 heal = dam;
3583 } else {
3584 return;
3586 if (slow) {
3587 if (mon->mspeed != MSLOW)
3588 mon_adjust_speed(mon, -1, (struct obj *) 0);
3590 if (heal) {
3591 if (mon->mhp < mon->mhpmax) {
3592 mon->mhp += heal;
3593 if (mon->mhp > mon->mhpmax)
3594 mon->mhp = mon->mhpmax;
3595 if (cansee(mon->mx, mon->my))
3596 pline("%s seems healthier.", Monnam(mon));
3601 boolean
3602 angry_guards(silent)
3603 boolean silent;
3605 struct monst *mtmp;
3606 int ct = 0, nct = 0, sct = 0, slct = 0;
3608 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
3609 if (DEADMONSTER(mtmp))
3610 continue;
3611 if (is_watch(mtmp->data) && mtmp->mpeaceful) {
3612 ct++;
3613 if (cansee(mtmp->mx, mtmp->my) && mtmp->mcanmove) {
3614 if (distu(mtmp->mx, mtmp->my) == 2)
3615 nct++;
3616 else
3617 sct++;
3619 if (mtmp->msleeping || mtmp->mfrozen) {
3620 slct++;
3621 mtmp->msleeping = mtmp->mfrozen = 0;
3623 mtmp->mpeaceful = 0;
3626 if (ct) {
3627 if (!silent) { /* do we want pline msgs? */
3628 if (slct)
3629 pline_The("guard%s wake%s up!", slct > 1 ? "s" : "",
3630 slct == 1 ? "s" : "");
3631 if (nct || sct) {
3632 if (nct)
3633 pline_The("guard%s get%s angry!", nct == 1 ? "" : "s",
3634 nct == 1 ? "s" : "");
3635 else if (!Blind)
3636 You_see("%sangry guard%s approaching!",
3637 sct == 1 ? "an " : "", sct > 1 ? "s" : "");
3638 } else
3639 You_hear("the shrill sound of a guard's whistle.");
3641 return TRUE;
3643 return FALSE;
3646 void
3647 pacify_guards()
3649 struct monst *mtmp;
3651 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
3652 if (DEADMONSTER(mtmp))
3653 continue;
3654 if (is_watch(mtmp->data))
3655 mtmp->mpeaceful = 1;
3659 void
3660 mimic_hit_msg(mtmp, otyp)
3661 struct monst *mtmp;
3662 short otyp;
3664 short ap = mtmp->mappearance;
3666 switch (mtmp->m_ap_type) {
3667 case M_AP_NOTHING:
3668 case M_AP_FURNITURE:
3669 case M_AP_MONSTER:
3670 break;
3671 case M_AP_OBJECT:
3672 if (otyp == SPE_HEALING || otyp == SPE_EXTRA_HEALING) {
3673 pline("%s seems a more vivid %s than before.",
3674 The(simple_typename(ap)),
3675 c_obj_colors[objects[ap].oc_color]);
3677 break;
3681 boolean
3682 usmellmon(mdat)
3683 struct permonst *mdat;
3685 int mndx;
3686 boolean nonspecific = FALSE;
3687 boolean msg_given = FALSE;
3689 if (mdat) {
3690 if (!olfaction(youmonst.data))
3691 return FALSE;
3692 mndx = monsndx(mdat);
3693 switch (mndx) {
3694 case PM_ROTHE:
3695 case PM_MINOTAUR:
3696 You("notice a bovine smell.");
3697 msg_given = TRUE;
3698 break;
3699 case PM_CAVEMAN:
3700 case PM_CAVEWOMAN:
3701 case PM_BARBARIAN:
3702 case PM_NEANDERTHAL:
3703 You("smell body odor.");
3704 msg_given = TRUE;
3705 break;
3707 case PM_PESTILENCE:
3708 case PM_FAMINE:
3709 case PM_DEATH:
3710 break;
3712 case PM_HORNED_DEVIL:
3713 case PM_BALROG:
3714 case PM_ASMODEUS:
3715 case PM_DISPATER:
3716 case PM_YEENOGHU:
3717 case PM_ORCUS:
3718 break;
3719 case PM_HUMAN_WEREJACKAL:
3720 case PM_HUMAN_WERERAT:
3721 case PM_HUMAN_WEREWOLF:
3722 case PM_WEREJACKAL:
3723 case PM_WERERAT:
3724 case PM_WEREWOLF:
3725 case PM_OWLBEAR:
3726 You("detect an odor reminiscent of an animal's den.");
3727 msg_given = TRUE;
3728 break;
3730 case PM_PURPLE_WORM:
3731 break;
3733 case PM_STEAM_VORTEX:
3734 You("smell steam.");
3735 msg_given = TRUE;
3736 break;
3737 case PM_GREEN_SLIME:
3738 pline("%s stinks.", Something);
3739 msg_given = TRUE;
3740 break;
3741 case PM_VIOLET_FUNGUS:
3742 case PM_SHRIEKER:
3743 You("smell mushrooms.");
3744 msg_given = TRUE;
3745 break;
3746 /* These are here to avoid triggering the
3747 nonspecific treatment through the default case below*/
3748 case PM_WHITE_UNICORN:
3749 case PM_GRAY_UNICORN:
3750 case PM_BLACK_UNICORN:
3751 case PM_JELLYFISH:
3752 break;
3753 default:
3754 nonspecific = TRUE;
3755 break;
3758 if (nonspecific)
3759 switch (mdat->mlet) {
3760 case S_DOG:
3761 You("notice a dog smell.");
3762 msg_given = TRUE;
3763 break;
3764 case S_DRAGON:
3765 You("smell a dragon!");
3766 msg_given = TRUE;
3767 break;
3768 case S_FUNGUS:
3769 pline("%s smells moldy.", Something);
3770 msg_given = TRUE;
3771 break;
3772 case S_UNICORN:
3773 You("detect a%s odor reminiscent of a stable.",
3774 (mndx == PM_PONY) ? "n" : " strong");
3775 msg_given = TRUE;
3776 break;
3777 case S_ZOMBIE:
3778 You("smell rotting flesh.");
3779 msg_given = TRUE;
3780 break;
3781 case S_EEL:
3782 You("smell fish.");
3783 msg_given = TRUE;
3784 break;
3785 case S_ORC:
3786 if (maybe_polyd(is_orc(youmonst.data), Race_if(PM_ORC)))
3787 You("notice an attractive smell.");
3788 else
3789 pline("A foul stench makes you feel a little nauseated.");
3790 msg_given = TRUE;
3791 break;
3792 default:
3793 break;
3796 return msg_given ? TRUE : FALSE;
3799 /*mon.c*/