Fandom

Wikihack

Source:Mon.c

2,034pages on
this wiki
Add New Page
Talk0

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Below is the full text to src/mon.c from NetHack 3.4.3. To link to a particular line, write [[mon.c#line123]], for example.

Top of file Edit

1.    /*	SCCS Id: @(#)mon.c	3.4	2003/12/04	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
5.    /* If you're using precompiled headers, you don't want this either */
6.    #ifdef MICROPORT_BUG
7.    #define MKROOM_H
8.    #endif
9.    
10.   #include "hack.h"
11.   #include "mfndpos.h"
12.   #include "edog.h"
13.   #include <ctype.h>
14.   
15.   STATIC_DCL boolean FDECL(restrap,(struct monst *));
16.   STATIC_DCL long FDECL(mm_aggression, (struct monst *,struct monst *));
17.   #ifdef OVL2
18.   STATIC_DCL int NDECL(pick_animal);
19.   STATIC_DCL int FDECL(select_newcham_form, (struct monst *));
20.   STATIC_DCL void FDECL(kill_eggs, (struct obj *));
21.   #endif
22.   
23.   #ifdef REINCARNATION
24.   #define LEVEL_SPECIFIC_NOCORPSE(mdat) \
25.   	 (Is_rogue_level(&u.uz) || \
26.   	   (level.flags.graveyard && is_undead(mdat) && rn2(3)))
27.   #else
28.   #define LEVEL_SPECIFIC_NOCORPSE(mdat) \
29.   	   (level.flags.graveyard && is_undead(mdat) && rn2(3))
30.   #endif
31.   
32.   
33.   #if 0
34.   /* part of the original warning code which was replaced in 3.3.1 */
35.   #ifdef OVL1
36.   #define warnDelay 10
37.   long lastwarntime;
38.   int lastwarnlev;
39.   
40.   const char *warnings[] = {
41.   	"white", "pink", "red", "ruby", "purple", "black"
42.   };
43.   
44.   STATIC_DCL void NDECL(warn_effects);
45.   #endif /* OVL1 */
46.   #endif /* 0 */
47.   
48.   #ifndef OVLB
49.   STATIC_VAR short cham_to_pm[];
50.   #else
51.   STATIC_DCL struct obj *FDECL(make_corpse,(struct monst *));
52.   STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *));
53.   STATIC_DCL void FDECL(lifesaved_monster, (struct monst *));
54.   

undead_to_corpse Edit

55.   /* convert the monster index of an undead to its living counterpart */
56.   int
57.   undead_to_corpse(mndx)
58.   int mndx;
59.   {
60.   	switch (mndx) {
61.   	case PM_KOBOLD_ZOMBIE:
62.   	case PM_KOBOLD_MUMMY:	mndx = PM_KOBOLD;  break;
63.   	case PM_DWARF_ZOMBIE:
64.   	case PM_DWARF_MUMMY:	mndx = PM_DWARF;  break;
65.   	case PM_GNOME_ZOMBIE:
66.   	case PM_GNOME_MUMMY:	mndx = PM_GNOME;  break;
67.   	case PM_ORC_ZOMBIE:
68.   	case PM_ORC_MUMMY:	mndx = PM_ORC;  break;
69.   	case PM_ELF_ZOMBIE:
70.   	case PM_ELF_MUMMY:	mndx = PM_ELF;  break;
71.   	case PM_VAMPIRE:
72.   	case PM_VAMPIRE_LORD:
73.   #if 0	/* DEFERRED */
74.   	case PM_VAMPIRE_MAGE:
75.   #endif
76.   	case PM_HUMAN_ZOMBIE:
77.   	case PM_HUMAN_MUMMY:	mndx = PM_HUMAN;  break;
78.   	case PM_GIANT_ZOMBIE:
79.   	case PM_GIANT_MUMMY:	mndx = PM_GIANT;  break;
80.   	case PM_ETTIN_ZOMBIE:
81.   	case PM_ETTIN_MUMMY:	mndx = PM_ETTIN;  break;
82.   	default:  break;
83.   	}
84.   	return mndx;
85.   }
86.   

genus Edit

87.   /* Convert the monster index of some monsters (such as quest guardians)
88.    * to their generic species type.
89.    *
90.    * Return associated character class monster, rather than species
91.    * if mode is 1.
92.    */
93.   int
94.   genus(mndx, mode)
95.   int mndx, mode;
96.   {
97.   	switch (mndx) {
98.   /* Quest guardians */
99.   	case PM_STUDENT:     mndx = mode ? PM_ARCHEOLOGIST  : PM_HUMAN; break;
100.  	case PM_CHIEFTAIN:   mndx = mode ? PM_BARBARIAN : PM_HUMAN; break;
101.  	case PM_NEANDERTHAL: mndx = mode ? PM_CAVEMAN   : PM_HUMAN; break;
102.  	case PM_ATTENDANT:   mndx = mode ? PM_HEALER    : PM_HUMAN; break;
103.  	case PM_PAGE:        mndx = mode ? PM_KNIGHT    : PM_HUMAN; break;
104.  	case PM_ABBOT:       mndx = mode ? PM_MONK      : PM_HUMAN; break;
105.  	case PM_ACOLYTE:     mndx = mode ? PM_PRIEST    : PM_HUMAN; break;
106.  	case PM_HUNTER:      mndx = mode ? PM_RANGER    : PM_HUMAN; break;
107.  	case PM_THUG:        mndx = mode ? PM_ROGUE     : PM_HUMAN; break;
108.  	case PM_ROSHI:       mndx = mode ? PM_SAMURAI   : PM_HUMAN; break;
109.  #ifdef TOURIST
110.  	case PM_GUIDE:       mndx = mode ? PM_TOURIST   : PM_HUMAN; break;
111.  #endif
112.  	case PM_APPRENTICE:  mndx = mode ? PM_WIZARD    : PM_HUMAN; break;
113.  	case PM_WARRIOR:     mndx = mode ? PM_VALKYRIE  : PM_HUMAN; break;
114.  	default:
115.  		if (mndx >= LOW_PM && mndx < NUMMONS) {
116.  			struct permonst *ptr = &mons[mndx];
117.  			if (is_human(ptr))      mndx = PM_HUMAN;
118.  			else if (is_elf(ptr))   mndx = PM_ELF;
119.  			else if (is_dwarf(ptr)) mndx = PM_DWARF;
120.  			else if (is_gnome(ptr)) mndx = PM_GNOME;
121.  			else if (is_orc(ptr))   mndx = PM_ORC;
122.  		}
123.  		break;
124.  	}
125.  	return mndx;
126.  }
127.  

pm_to_cham Edit

128.  /* convert monster index to chameleon index */
129.  int
130.  pm_to_cham(mndx)
131.  int mndx;
132.  {
133.  	int mcham;
134.  
135.  	switch (mndx) {
136.  	case PM_CHAMELEON:	mcham = CHAM_CHAMELEON; break;
137.  	case PM_DOPPELGANGER:	mcham = CHAM_DOPPELGANGER; break;
138.  	case PM_SANDESTIN:	mcham = CHAM_SANDESTIN; break;
139.  	default: mcham = CHAM_ORDINARY; break;
140.  	}
141.  	return mcham;
142.  }
143.  
144.  /* convert chameleon index to monster index */
145.  STATIC_VAR short cham_to_pm[] = {
146.  		NON_PM,		/* placeholder for CHAM_ORDINARY */
147.  		PM_CHAMELEON,
148.  		PM_DOPPELGANGER,
149.  		PM_SANDESTIN,
150.  };
151.  
152.  /* for deciding whether corpse or statue will carry along full monster data */
153.  #define KEEPTRAITS(mon)	((mon)->isshk || (mon)->mtame ||		\
154.  			 ((mon)->data->geno & G_UNIQ) ||		\
155.  			 is_reviver((mon)->data) ||			\
156.  			 /* normally leader the will be unique, */	\
157.  			 /* but he might have been polymorphed  */	\
158.  			 (mon)->m_id == quest_status.leader_m_id ||	\
159.  			 /* special cancellation handling for these */	\
160.  			 (dmgtype((mon)->data, AD_SEDU) ||		\
161.  			  dmgtype((mon)->data, AD_SSEX)))
162.  

make_corpse Edit

163.  /* Creates a monster corpse, a "special" corpse, or nothing if it doesn't
164.   * leave corpses.  Monsters which leave "special" corpses should have
165.   * G_NOCORPSE set in order to prevent wishing for one, finding tins of one,
166.   * etc....
167.   */
168.  STATIC_OVL struct obj *
169.  make_corpse(mtmp)
170.  register struct monst *mtmp;
171.  {
172.  	register struct permonst *mdat = mtmp->data;
173.  	int num;
174.  	struct obj *obj = (struct obj *)0;
175.  	int x = mtmp->mx, y = mtmp->my;
176.  	int mndx = monsndx(mdat);
177.  
178.  	switch(mndx) {
179.  	    case PM_GRAY_DRAGON:
180.  	    case PM_SILVER_DRAGON:
181.  #if 0	/* DEFERRED */
182.  	    case PM_SHIMMERING_DRAGON:
183.  #endif
184.  	    case PM_RED_DRAGON:
185.  	    case PM_ORANGE_DRAGON:
186.  	    case PM_WHITE_DRAGON:
187.  	    case PM_BLACK_DRAGON:
188.  	    case PM_BLUE_DRAGON:
189.  	    case PM_GREEN_DRAGON:
190.  	    case PM_YELLOW_DRAGON:
191.  		/* Make dragon scales.  This assumes that the order of the */
192.  		/* dragons is the same as the order of the scales.	   */
193.  		if (!rn2(mtmp->mrevived ? 20 : 3)) {
194.  		    num = GRAY_DRAGON_SCALES + monsndx(mdat) - PM_GRAY_DRAGON;
195.  		    obj = mksobj_at(num, x, y, FALSE, FALSE);
196.  		    obj->spe = 0;
197.  		    obj->cursed = obj->blessed = FALSE;
198.  		}
199.  		goto default_1;
200.  
201.  	    case PM_WHITE_UNICORN:
202.  	    case PM_GRAY_UNICORN:
203.  	    case PM_BLACK_UNICORN:
204.  		if (mtmp->mrevived && rn2(20)) {
205.  			if (canseemon(mtmp))
206.  			   pline("%s recently regrown horn crumbles to dust.",
207.  				s_suffix(Monnam(mtmp)));
208.  		} else
209.  			(void) mksobj_at(UNICORN_HORN, x, y, TRUE, FALSE);
210.  		goto default_1;
211.  	    case PM_LONG_WORM:
212.  		(void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE);
213.  		goto default_1;
214.  	    case PM_VAMPIRE:
215.  	    case PM_VAMPIRE_LORD:
216.  		/* include mtmp in the mkcorpstat() call */
217.  		num = undead_to_corpse(mndx);
218.  		obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, TRUE);
219.  		obj->age -= 100;		/* this is an *OLD* corpse */
220.  		break;
221.  	    case PM_KOBOLD_MUMMY:
222.  	    case PM_DWARF_MUMMY:
223.  	    case PM_GNOME_MUMMY:
224.  	    case PM_ORC_MUMMY:
225.  	    case PM_ELF_MUMMY:
226.  	    case PM_HUMAN_MUMMY:
227.  	    case PM_GIANT_MUMMY:
228.  	    case PM_ETTIN_MUMMY:
229.  	    case PM_KOBOLD_ZOMBIE:
230.  	    case PM_DWARF_ZOMBIE:
231.  	    case PM_GNOME_ZOMBIE:
232.  	    case PM_ORC_ZOMBIE:
233.  	    case PM_ELF_ZOMBIE:
234.  	    case PM_HUMAN_ZOMBIE:
235.  	    case PM_GIANT_ZOMBIE:
236.  	    case PM_ETTIN_ZOMBIE:
237.  		num = undead_to_corpse(mndx);
238.  		obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, TRUE);
239.  		obj->age -= 100;		/* this is an *OLD* corpse */
240.  		break;
241.  	    case PM_IRON_GOLEM:
242.  		num = d(2,6);
243.  		while (num--)
244.  			obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE);
245.  		mtmp->mnamelth = 0;
246.  		break;
247.  	    case PM_GLASS_GOLEM:
248.  		num = d(2,4);   /* very low chance of creating all glass gems */
249.  		while (num--)
250.  			obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE);
251.  		mtmp->mnamelth = 0;
252.  		break;
253.  	    case PM_CLAY_GOLEM:
254.  		obj = mksobj_at(ROCK, x, y, FALSE, FALSE);
255.  		obj->quan = (long)(rn2(20) + 50);
256.  		obj->owt = weight(obj);
257.  		mtmp->mnamelth = 0;
258.  		break;
259.  	    case PM_STONE_GOLEM:
260.  		obj = mkcorpstat(STATUE, (struct monst *)0,
261.  			mdat, x, y, FALSE);
262.  		break;
263.  	    case PM_WOOD_GOLEM:
264.  		num = d(2,4);
265.  		while(num--) {
266.  			obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE);
267.  		}
268.  		mtmp->mnamelth = 0;
269.  		break;
270.  	    case PM_LEATHER_GOLEM:
271.  		num = d(2,4);
272.  		while(num--)
273.  			obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE);
274.  		mtmp->mnamelth = 0;
275.  		break;
276.  	    case PM_GOLD_GOLEM:
277.  		/* Good luck gives more coins */
278.  		obj = mkgold((long)(200 - rnl(101)), x, y);
279.  		mtmp->mnamelth = 0;
280.  		break;
281.  	    case PM_PAPER_GOLEM:
282.  		num = rnd(4);
283.  		while (num--)
284.  			obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE);
285.  		mtmp->mnamelth = 0;
286.  		break;
287.  	    default_1:
288.  	    default:
289.  		if (mvitals[mndx].mvflags & G_NOCORPSE)
290.  		    return (struct obj *)0;
291.  		else	/* preserve the unique traits of some creatures */
292.  		    obj = mkcorpstat(CORPSE, KEEPTRAITS(mtmp) ? mtmp : 0,
293.  				     mdat, x, y, TRUE);
294.  		break;
295.  	}
296.  	/* All special cases should precede the G_NOCORPSE check */
297.  
298.  	/* if polymorph or undead turning has killed this monster,
299.  	   prevent the same attack beam from hitting its corpse */
300.  	if (flags.bypasses) bypass_obj(obj);
301.  
302.  	if (mtmp->mnamelth)
303.  	    obj = oname(obj, NAME(mtmp));
304.  
305.  	/* Avoid "It was hidden under a green mold corpse!" 
306.  	 *  during Blind combat. An unseen monster referred to as "it"
307.  	 *  could be killed and leave a corpse.  If a hider then hid
308.  	 *  underneath it, you could be told the corpse type of a
309.  	 *  monster that you never knew was there without this.
310.  	 *  The code in hitmu() substitutes the word "something"
311.  	 *  if the corpses obj->dknown is 0.
312.  	 */
313.  	if (Blind && !sensemon(mtmp)) obj->dknown = 0;
314.  
315.  #ifdef INVISIBLE_OBJECTS
316.  	/* Invisible monster ==> invisible corpse */
317.  	obj->oinvis = mtmp->minvis;
318.  #endif
319.  
320.  	stackobj(obj);
321.  	newsym(x, y);
322.  	return obj;
323.  }
324.  
325.  #endif /* OVLB */
326.  #ifdef OVL1
327.  
328.  #if 0

warn_effects Edit

329.  /* part of the original warning code which was replaced in 3.3.1 */
330.  STATIC_OVL void
331.  warn_effects()
332.  {
333.      if (warnlevel == 100) {
334.  	if(!Blind && uwep &&
335.  	    (warnlevel > lastwarnlev || moves > lastwarntime + warnDelay)) {
336.  	    Your("%s %s!", aobjnam(uwep, "glow"),
337.  		hcolor(NH_LIGHT_BLUE));
338.  	    lastwarnlev = warnlevel;
339.  	    lastwarntime = moves;
340.  	}
341.  	warnlevel = 0;
342.  	return;
343.      }
344.  
345.      if (warnlevel >= SIZE(warnings))
346.  	warnlevel = SIZE(warnings)-1;
347.      if (!Blind &&
348.  	    (warnlevel > lastwarnlev || moves > lastwarntime + warnDelay)) {
349.  	const char *which, *what, *how;
350.  	long rings = (EWarning & (LEFT_RING|RIGHT_RING));
351.  
352.  	if (rings) {
353.  	    what = Hallucination ? "mood ring" : "ring";
354.  	    how = "glows";	/* singular verb */
355.  	    if (rings == LEFT_RING) {
356.  		which = "left ";
357.  	    } else if (rings == RIGHT_RING) {
358.  		which = "right ";
359.  	    } else {		/* both */
360.  		which = "";
361.  		what = (const char *) makeplural(what);
362.  		how = "glow";	/* plural verb */
363.  	    }
364.  	    Your("%s%s %s %s!", which, what, how, hcolor(warnings[warnlevel]));
365.  	} else {
366.  	    if (Hallucination)
367.  		Your("spider-sense is tingling...");
368.  	    else
369.  		You_feel("apprehensive as you sense a %s flash.",
370.  		    warnings[warnlevel]);
371.  	}
372.  
373.  	lastwarntime = moves;
374.  	lastwarnlev = warnlevel;
375.      }
376.  }
377.  #endif /* 0 */
378.  

minliquid Edit

379.  /* check mtmp and water/lava for compatibility, 0 (survived), 1 (died) */
380.  int
381.  minliquid(mtmp)
382.  register struct monst *mtmp;
383.  {
384.      boolean inpool, inlava, infountain;
385.  
386.      inpool = is_pool(mtmp->mx,mtmp->my) &&
387.  	     !is_flyer(mtmp->data) && !is_floater(mtmp->data);
388.      inlava = is_lava(mtmp->mx,mtmp->my) &&
389.  	     !is_flyer(mtmp->data) && !is_floater(mtmp->data);
390.      infountain = IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ);
391.  
392.  #ifdef STEED
393.  	/* Flying and levitation keeps our steed out of the liquid */
394.  	/* (but not water-walking or swimming) */
395.  	if (mtmp == u.usteed && (Flying || Levitation))
396.  		return (0);
397.  #endif
398.  
399.      /* Gremlin multiplying won't go on forever since the hit points
400.       * keep going down, and when it gets to 1 hit point the clone
401.       * function will fail.
402.       */
403.      if (mtmp->data == &mons[PM_GREMLIN] && (inpool || infountain) && rn2(3)) {
404.  	if (split_mon(mtmp, (struct monst *)0))
405.  	    dryup(mtmp->mx, mtmp->my, FALSE);
406.  	if (inpool) water_damage(mtmp->minvent, FALSE, FALSE);
407.  	return (0);
408.      } else if (mtmp->data == &mons[PM_IRON_GOLEM] && inpool && !rn2(5)) {
409.  	int dam = d(2,6);
410.  	if (cansee(mtmp->mx,mtmp->my))
411.  	    pline("%s rusts.", Monnam(mtmp));
412.  	mtmp->mhp -= dam;
413.  	if (mtmp->mhpmax > dam) mtmp->mhpmax -= dam;
414.  	if (mtmp->mhp < 1) {
415.  	    mondead(mtmp);
416.  	    if (mtmp->mhp < 1) return (1);
417.  	}
418.  	water_damage(mtmp->minvent, FALSE, FALSE);
419.  	return (0);
420.      }
421.  
422.      if (inlava) {
423.  	/*
424.  	 * Lava effects much as water effects. Lava likers are able to
425.  	 * protect their stuff. Fire resistant monsters can only protect
426.  	 * themselves  --ALI
427.  	 */
428.  	if (!is_clinger(mtmp->data) && !likes_lava(mtmp->data)) {
429.  	    if (!resists_fire(mtmp)) {
430.  		if (cansee(mtmp->mx,mtmp->my))
431.  		    pline("%s %s.", Monnam(mtmp),
432.  			  mtmp->data == &mons[PM_WATER_ELEMENTAL] ?
433.  			  "boils away" : "burns to a crisp");
434.  		mondead(mtmp);
435.  	    }
436.  	    else {
437.  		if (--mtmp->mhp < 1) {
438.  		    if (cansee(mtmp->mx,mtmp->my))
439.  			pline("%s surrenders to the fire.", Monnam(mtmp));
440.  		    mondead(mtmp);
441.  		}
442.  		else if (cansee(mtmp->mx,mtmp->my))
443.  		    pline("%s burns slightly.", Monnam(mtmp));
444.  	    }
445.  	    if (mtmp->mhp > 0) {
446.  		(void) fire_damage(mtmp->minvent, FALSE, FALSE,
447.  						mtmp->mx, mtmp->my);
448.  		(void) rloc(mtmp, FALSE);
449.  		return 0;
450.  	    }
451.  	    return (1);
452.  	}
453.      } else if (inpool) {
454.  	/* Most monsters drown in pools.  flooreffects() will take care of
455.  	 * water damage to dead monsters' inventory, but survivors need to
456.  	 * be handled here.  Swimmers are able to protect their stuff...
457.  	 */
458.  	if (!is_clinger(mtmp->data)
459.  	    && !is_swimmer(mtmp->data) && !amphibious(mtmp->data)) {
460.  	    if (cansee(mtmp->mx,mtmp->my)) {
461.  		    pline("%s drowns.", Monnam(mtmp));
462.  	    }
463.  	    if (u.ustuck && u.uswallow && u.ustuck == mtmp) {
464.  	    /* This can happen after a purple worm plucks you off a
465.  		flying steed while you are over water. */
466.  		pline("%s sinks as water rushes in and flushes you out.",
467.  			Monnam(mtmp));
468.  	    }
469.  	    mondead(mtmp);
470.  	    if (mtmp->mhp > 0) {
471.  		(void) rloc(mtmp, FALSE);
472.  		water_damage(mtmp->minvent, FALSE, FALSE);
473.  		return 0;
474.  	    }
475.  	    return (1);
476.  	}
477.      } else {
478.  	/* but eels have a difficult time outside */
479.  	if (mtmp->data->mlet == S_EEL && !Is_waterlevel(&u.uz)) {
480.  	    if(mtmp->mhp > 1) mtmp->mhp--;
481.  	    monflee(mtmp, 2, FALSE, FALSE);
482.  	}
483.      }
484.      return (0);
485.  }
486.  
487.  

mcalcmove Edit

488.  int
489.  mcalcmove(mon)
490.  struct monst *mon;
491.  {
492.      int mmove = mon->data->mmove;
493.  
494.      /* Note: MSLOW's `+ 1' prevents slowed speed 1 getting reduced to 0;
495.       *	     MFAST's `+ 2' prevents hasted speed 1 from becoming a no-op;
496.       *	     both adjustments have negligible effect on higher speeds.
497.       */
498.      if (mon->mspeed == MSLOW)
499.  	mmove = (2 * mmove + 1) / 3;
500.      else if (mon->mspeed == MFAST)
501.  	mmove = (4 * mmove + 2) / 3;
502.  
503.  #ifdef STEED
504.      if (mon == u.usteed) {
505.  	if (u.ugallop && flags.mv) {
506.  	    /* average movement is 1.50 times normal */
507.  	    mmove = ((rn2(2) ? 4 : 5) * mmove) / 3;
508.  	}
509.      }
510.  #endif
511.  
512.      return mmove;
513.  }
514.  

mcalcdistress Edit

515.  /* actions that happen once per ``turn, regardless of each
516.     individual monster's metabolism; some of these might need to
517.     be reclassified to occur more in proportion with movement rate */
518.  void
519.  mcalcdistress()
520.  {
521.      struct monst *mtmp;
522.  
523.      for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
524.  	if (DEADMONSTER(mtmp)) continue;
525.  
526.  	/* must check non-moving monsters once/turn in case
527.  	 * they managed to end up in liquid */
528.  	if (mtmp->data->mmove == 0) {
529.  	    if (vision_full_recalc) vision_recalc(0);
530.  	    if (minliquid(mtmp)) continue;
531.  	}
532.  
533.  	/* regenerate hit points */
534.  	mon_regen(mtmp, FALSE);
535.  
536.  	/* possibly polymorph shapechangers and lycanthropes */
537.  	if (mtmp->cham && !rn2(6))
538.  	    (void) newcham(mtmp, (struct permonst *)0, FALSE, FALSE);
539.  	were_change(mtmp);
540.  
541.  	/* gradually time out temporary problems */
542.  	if (mtmp->mblinded && !--mtmp->mblinded)
543.  	    mtmp->mcansee = 1;
544.  	if (mtmp->mfrozen && !--mtmp->mfrozen)
545.  	    mtmp->mcanmove = 1;
546.  	if (mtmp->mfleetim && !--mtmp->mfleetim)
547.  	    mtmp->mflee = 0;
548.  
549.  	/* FIXME: mtmp->mlstmv ought to be updated here */
550.      }
551.  }
552.  

movemon Edit

553.  int
554.  movemon()
555.  {
556.      register struct monst *mtmp, *nmtmp;
557.      register boolean somebody_can_move = FALSE;
558.  #if 0
559.      /* part of the original warning code which was replaced in 3.3.1 */
560.      warnlevel = 0;
561.  #endif
562.  
563.      /*
564.      Some of you may remember the former assertion here that
565.      because of deaths and other actions, a simple one-pass
566.      algorithm wasn't possible for movemon.  Deaths are no longer
567.      removed to the separate list fdmon; they are simply left in
568.      the chain with hit points <= 0, to be cleaned up at the end
569.      of the pass.
570.  
571.      The only other actions which cause monsters to be removed from
572.      the chain are level migrations and losedogs().  I believe losedogs()
573.      is a cleanup routine not associated with monster movements, and
574.      monsters can only affect level migrations on themselves, not others
575.      (hence the fetching of nmon before moving the monster).  Currently,
576.      monsters can jump into traps, read cursed scrolls of teleportation,
577.      and drink cursed potions of raise level to change levels.  These are
578.      all reflexive at this point.  Should one monster be able to level
579.      teleport another, this scheme would have problems.
580.      */
581.  
582.      for(mtmp = fmon; mtmp; mtmp = nmtmp) {
583.  	nmtmp = mtmp->nmon;
584.  
585.  	/* Find a monster that we have not treated yet.	 */
586.  	if(DEADMONSTER(mtmp))
587.  	    continue;
588.  	if(mtmp->movement < NORMAL_SPEED)
589.  	    continue;
590.  
591.  	mtmp->movement -= NORMAL_SPEED;
592.  	if (mtmp->movement >= NORMAL_SPEED)
593.  	    somebody_can_move = TRUE;
594.  
595.  	if (vision_full_recalc) vision_recalc(0);	/* vision! */
596.  
597.  	if (minliquid(mtmp)) continue;
598.  
599.  	if (is_hider(mtmp->data)) {
600.  	    /* unwatched mimics and piercers may hide again  [MRS] */
601.  	    if(restrap(mtmp))   continue;
602.  	    if(mtmp->m_ap_type == M_AP_FURNITURE ||
603.  				mtmp->m_ap_type == M_AP_OBJECT)
604.  		    continue;
605.  	    if(mtmp->mundetected) continue;
606.  	}
607.  
608.  	/* continue if the monster died fighting */
609.  	if (Conflict && !mtmp->iswiz && mtmp->mcansee) {
610.  	    /* Note:
611.  	     *  Conflict does not take effect in the first round.
612.  	     *  Therefore, A monster when stepping into the area will
613.  	     *  get to swing at you.
614.  	     *
615.  	     *  The call to fightm() must be _last_.  The monster might
616.  	     *  have died if it returns 1.
617.  	     */
618.  	    if (couldsee(mtmp->mx,mtmp->my) &&
619.  		(distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) &&
620.  							fightm(mtmp))
621.  		continue;	/* mon might have died */
622.  	}
623.  	if(dochugw(mtmp))		/* otherwise just move the monster */
624.  	    continue;
625.      }
626.  #if 0
627.      /* part of the original warning code which was replaced in 3.3.1 */
628.      if(warnlevel > 0)
629.  	warn_effects();
630.  #endif
631.  
632.      if (any_light_source())
633.  	vision_full_recalc = 1;	/* in case a mon moved with a light source */
634.      dmonsfree();	/* remove all dead monsters */
635.  
636.      /* a monster may have levteleported player -dlc */
637.      if (u.utotype) {
638.  	deferred_goto();
639.  	/* changed levels, so these monsters are dormant */
640.  	somebody_can_move = FALSE;
641.      }
642.  
643.      return somebody_can_move;
644.  }
645.  
646.  #endif /* OVL1 */
647.  #ifdef OVLB
648.  
649.  #define mstoning(obj)	(ofood(obj) && \
650.  					(touch_petrifies(&mons[(obj)->corpsenm]) || \
651.  					(obj)->corpsenm == PM_MEDUSA))
652.  

meatmetal Edit

653.  /*
654.   * Maybe eat a metallic object (not just gold).
655.   * Return value: 0 => nothing happened, 1 => monster ate something,
656.   * 2 => monster died (it must have grown into a genocided form, but
657.   * that can't happen at present because nothing which eats objects
658.   * has young and old forms).
659.   */
660.  int
661.  meatmetal(mtmp)
662.  	register struct monst *mtmp;
663.  {
664.  	register struct obj *otmp;
665.  	struct permonst *ptr;
666.  	int poly, grow, heal, mstone;
667.  
668.  	/* If a pet, eating is handled separately, in dog.c */
669.  	if (mtmp->mtame) return 0;
670.  
671.  	/* Eats topmost metal object if it is there */
672.  	for (otmp = level.objects[mtmp->mx][mtmp->my];
673.  						otmp; otmp = otmp->nexthere) {
674.  	    if (mtmp->data == &mons[PM_RUST_MONSTER] && !is_rustprone(otmp))
675.  		continue;
676.  	    if (is_metallic(otmp) && !obj_resists(otmp, 5, 95) &&
677.  		touch_artifact(otmp,mtmp)) {
678.  		if (mtmp->data == &mons[PM_RUST_MONSTER] && otmp->oerodeproof) {
679.  		    if (canseemon(mtmp) && flags.verbose) {
680.  			pline("%s eats %s!",
681.  				Monnam(mtmp),
682.  				distant_name(otmp,doname));
683.  		    }
684.  		    /* The object's rustproofing is gone now */
685.  		    otmp->oerodeproof = 0;
686.  		    mtmp->mstun = 1;
687.  		    if (canseemon(mtmp) && flags.verbose) {
688.  			pline("%s spits %s out in disgust!",
689.  			      Monnam(mtmp), distant_name(otmp,doname));
690.  		    }
691.  		/* KMH -- Don't eat indigestible/choking objects */
692.  		} else if (otmp->otyp != AMULET_OF_STRANGULATION &&
693.  				otmp->otyp != RIN_SLOW_DIGESTION) {
694.  		    if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
695.  			pline("%s eats %s!", Monnam(mtmp),
696.  				distant_name(otmp,doname));
697.  		    else if (flags.soundok && flags.verbose)
698.  			You_hear("a crunching sound.");
699.  		    mtmp->meating = otmp->owt/2 + 1;
700.  		    /* Heal up to the object's weight in hp */
701.  		    if (mtmp->mhp < mtmp->mhpmax) {
702.  			mtmp->mhp += objects[otmp->otyp].oc_weight;
703.  			if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
704.  		    }
705.  		    if(otmp == uball) {
706.  			unpunish();
707.  			delobj(otmp);
708.  		    } else if (otmp == uchain) {
709.  			unpunish();	/* frees uchain */
710.  		    } else {
711.  			poly = polyfodder(otmp);
712.  			grow = mlevelgain(otmp);
713.  			heal = mhealup(otmp);
714.  			mstone = mstoning(otmp);
715.  			delobj(otmp);
716.  			ptr = mtmp->data;
717.  			if (poly) {
718.  			    if (newcham(mtmp, (struct permonst *)0,
719.  					FALSE, FALSE))
720.  				ptr = mtmp->data;
721.  			} else if (grow) {
722.  			    ptr = grow_up(mtmp, (struct monst *)0);
723.  			} else if (mstone) {
724.  			    if (poly_when_stoned(ptr)) {
725.  				mon_to_stone(mtmp);
726.  				ptr = mtmp->data;
727.  			    } else if (!resists_ston(mtmp)) {
728.  				if (canseemon(mtmp))
729.  				    pline("%s turns to stone!", Monnam(mtmp));
730.  				monstone(mtmp);
731.  				ptr = (struct permonst *)0;
732.  			    }
733.  			} else if (heal) {
734.  			    mtmp->mhp = mtmp->mhpmax;
735.  			}
736.  			if (!ptr) return 2;		 /* it died */
737.  		    }
738.  		    /* Left behind a pile? */
739.  		    if (rnd(25) < 3)
740.  			(void)mksobj_at(ROCK, mtmp->mx, mtmp->my, TRUE, FALSE);
741.  		    newsym(mtmp->mx, mtmp->my);
742.  		    return 1;
743.  		}
744.  	    }
745.  	}
746.  	return 0;
747.  }
748.  

meatobj Edit

749.  int
750.  meatobj(mtmp)		/* for gelatinous cubes */
751.  	register struct monst *mtmp;
752.  {
753.  	register struct obj *otmp, *otmp2;
754.  	struct permonst *ptr;
755.  	int poly, grow, heal, count = 0, ecount = 0;
756.  	char buf[BUFSZ];
757.  
758.  	buf[0] = '\0';
759.  	/* If a pet, eating is handled separately, in dog.c */
760.  	if (mtmp->mtame) return 0;
761.  
762.  	/* Eats organic objects, including cloth and wood, if there */
763.  	/* Engulfs others, except huge rocks and metal attached to player */
764.  	for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
765.  	    otmp2 = otmp->nexthere;
766.  	    if (is_organic(otmp) && !obj_resists(otmp, 5, 95) &&
767.  		    touch_artifact(otmp,mtmp)) {
768.  		if (otmp->otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) &&
769.  			!resists_ston(mtmp))
770.  		    continue;
771.  		if (otmp->otyp == AMULET_OF_STRANGULATION ||
772.  				otmp->otyp == RIN_SLOW_DIGESTION)
773.  		    continue;
774.  		++count;
775.  		if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
776.  		    pline("%s eats %s!", Monnam(mtmp),
777.  			    distant_name(otmp, doname));
778.  		else if (flags.soundok && flags.verbose)
779.  		    You_hear("a slurping sound.");
780.  		/* Heal up to the object's weight in hp */
781.  		if (mtmp->mhp < mtmp->mhpmax) {
782.  		    mtmp->mhp += objects[otmp->otyp].oc_weight;
783.  		    if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
784.  		}
785.  		if (Has_contents(otmp)) {
786.  		    register struct obj *otmp3;
787.  		    /* contents of eaten containers become engulfed; this
788.  		       is arbitrary, but otherwise g.cubes are too powerful */
789.  		    while ((otmp3 = otmp->cobj) != 0) {
790.  			obj_extract_self(otmp3);
791.  			if (otmp->otyp == ICE_BOX && otmp3->otyp == CORPSE) {
792.  			    otmp3->age = monstermoves - otmp3->age;
793.  			    start_corpse_timeout(otmp3);
794.  			}
795.  			(void) mpickobj(mtmp, otmp3);
796.  		    }
797.  		}
798.  		poly = polyfodder(otmp);
799.  		grow = mlevelgain(otmp);
800.  		heal = mhealup(otmp);
801.  		delobj(otmp);		/* munch */
802.  		ptr = mtmp->data;
803.  		if (poly) {
804.  		    if (newcham(mtmp, (struct permonst *)0, FALSE, FALSE))
805.  			ptr = mtmp->data;
806.  		} else if (grow) {
807.  		    ptr = grow_up(mtmp, (struct monst *)0);
808.  		} else if (heal) {
809.  		    mtmp->mhp = mtmp->mhpmax;
810.  		}
811.  		/* in case it polymorphed or died */
812.  		if (ptr != &mons[PM_GELATINOUS_CUBE])
813.  		    return !ptr ? 2 : 1;
814.  	    } else if (otmp->oclass != ROCK_CLASS &&
815.  				    otmp != uball && otmp != uchain) {
816.  		++ecount;
817.  		if (ecount == 1) {
818.  			Sprintf(buf, "%s engulfs %s.", Monnam(mtmp),
819.  			    distant_name(otmp,doname));
820.  		} else if (ecount == 2)
821.  			Sprintf(buf, "%s engulfs several objects.", Monnam(mtmp));
822.  		obj_extract_self(otmp);
823.  		(void) mpickobj(mtmp, otmp);	/* slurp */
824.  	    }
825.  	    /* Engulf & devour is instant, so don't set meating */
826.  	    if (mtmp->minvis) newsym(mtmp->mx, mtmp->my);
827.  	}
828.  	if (ecount > 0) {
829.  	    if (cansee(mtmp->mx, mtmp->my) && flags.verbose && buf[0])
830.  		pline("%s", buf);
831.  	    else if (flags.soundok && flags.verbose)
832.  	    	You_hear("%s slurping sound%s.",
833.  			ecount == 1 ? "a" : "several",
834.  			ecount == 1 ? "" : "s");
835.  	}
836.  	return ((count > 0) || (ecount > 0)) ? 1 : 0;
837.  }
838.  

mpickgold Edit

839.  void
840.  mpickgold(mtmp)
841.  	register struct monst *mtmp;
842.  {
843.      register struct obj *gold;
844.      int mat_idx;
845.  
846.      if ((gold = g_at(mtmp->mx, mtmp->my)) != 0) {
847.  	mat_idx = objects[gold->otyp].oc_material;
848.  #ifndef GOLDOBJ
849.  	mtmp->mgold += gold->quan;
850.  	delobj(gold);
851.  #else
852.          obj_extract_self(gold);
853.          add_to_minv(mtmp, gold);
854.  #endif
855.  	if (cansee(mtmp->mx, mtmp->my) ) {
856.  	    if (flags.verbose && !mtmp->isgd)
857.  		pline("%s picks up some %s.", Monnam(mtmp),
858.  			mat_idx == GOLD ? "gold" : "money");
859.  	    newsym(mtmp->mx, mtmp->my);
860.  	}
861.      }
862.  }
863.  #endif /* OVLB */
864.  #ifdef OVL2
865.  

mpickstuff Edit

866.  boolean
867.  mpickstuff(mtmp, str)
868.  	register struct monst *mtmp;
869.  	register const char *str;
870.  {
871.  	register struct obj *otmp, *otmp2;
872.  
873.  /*	prevent shopkeepers from leaving the door of their shop */
874.  	if(mtmp->isshk && inhishop(mtmp)) return FALSE;
875.  
876.  	for(otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
877.  	    otmp2 = otmp->nexthere;
878.  /*	Nymphs take everything.  Most monsters don't pick up corpses. */
879.  	    if (!str ? searches_for_item(mtmp,otmp) :
880.  		  !!(index(str, otmp->oclass))) {
881.  		if (otmp->otyp == CORPSE && mtmp->data->mlet != S_NYMPH &&
882.  			/* let a handful of corpse types thru to can_carry() */
883.  			!touch_petrifies(&mons[otmp->corpsenm]) &&
884.  			otmp->corpsenm != PM_LIZARD &&
885.  			!acidic(&mons[otmp->corpsenm])) continue;
886.  		if (!touch_artifact(otmp,mtmp)) continue;
887.  		if (!can_carry(mtmp,otmp)) continue;
888.  		if (is_pool(mtmp->mx,mtmp->my)) continue;
889.  #ifdef INVISIBLE_OBJECTS
890.  		if (otmp->oinvis && !perceives(mtmp->data)) continue;
891.  #endif
892.  		if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
893.  			pline("%s picks up %s.", Monnam(mtmp),
894.  			      (distu(mtmp->mx, mtmp->my) <= 5) ?
895.  				doname(otmp) : distant_name(otmp, doname));
896.  		obj_extract_self(otmp);
897.  		/* unblock point after extract, before pickup */
898.  		if (otmp->otyp == BOULDER)
899.  		    unblock_point(otmp->ox,otmp->oy);	/* vision */
900.  		(void) mpickobj(mtmp, otmp);	/* may merge and free otmp */
901.  		m_dowear(mtmp, FALSE);
902.  		newsym(mtmp->mx, mtmp->my);
903.  		return TRUE;			/* pick only one object */
904.  	    }
905.  	}
906.  	return FALSE;
907.  }
908.  
909.  #endif /* OVL2 */
910.  #ifdef OVL0
911.  

curr_mon_load Edit

912.  int
913.  curr_mon_load(mtmp)
914.  register struct monst *mtmp;
915.  {
916.  	register int curload = 0;
917.  	register struct obj *obj;
918.  
919.  	for(obj = mtmp->minvent; obj; obj = obj->nobj) {
920.  		if(obj->otyp != BOULDER || !throws_rocks(mtmp->data))
921.  			curload += obj->owt;
922.  	}
923.  
924.  	return curload;
925.  }
926.  

max_mon_load Edit

927.  int
928.  max_mon_load(mtmp)
929.  register struct monst *mtmp;
930.  {
931.  	register long maxload;
932.  
933.  	/* Base monster carrying capacity is equal to human maximum
934.  	 * carrying capacity, or half human maximum if not strong.
935.  	 * (for a polymorphed player, the value used would be the
936.  	 * non-polymorphed carrying capacity instead of max/half max).
937.  	 * This is then modified by the ratio between the monster weights
938.  	 * and human weights.  Corpseless monsters are given a capacity
939.  	 * proportional to their size instead of weight.
940.  	 */
941.  	if (!mtmp->data->cwt)
942.  		maxload = (MAX_CARR_CAP * (long)mtmp->data->msize) / MZ_HUMAN;
943.  	else if (!strongmonst(mtmp->data)
944.  		|| (strongmonst(mtmp->data) && (mtmp->data->cwt > WT_HUMAN)))
945.  		maxload = (MAX_CARR_CAP * (long)mtmp->data->cwt) / WT_HUMAN;
946.  	else	maxload = MAX_CARR_CAP; /*strong monsters w/cwt <= WT_HUMAN*/
947.  
948.  	if (!strongmonst(mtmp->data)) maxload /= 2;
949.  
950.  	if (maxload < 1) maxload = 1;
951.  
952.  	return (int) maxload;
953.  }
954.  

can_carry Edit

955.  /* for restricting monsters' object-pickup */
956.  boolean
957.  can_carry(mtmp,otmp)
958.  struct monst *mtmp;
959.  struct obj *otmp;
960.  {
961.  	int otyp = otmp->otyp, newload = otmp->owt;
962.  	struct permonst *mdat = mtmp->data;
963.  
964.  	if (notake(mdat)) return FALSE;		/* can't carry anything */
965.  
966.  	if (otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) &&
967.  		!(mtmp->misc_worn_check & W_ARMG) && !resists_ston(mtmp))
968.  	    return FALSE;
969.  	if (otyp == CORPSE && is_rider(&mons[otmp->corpsenm]))
970.  	    return FALSE;
971.  	if (objects[otyp].oc_material == SILVER && hates_silver(mdat) &&
972.  		(otyp != BELL_OF_OPENING || !is_covetous(mdat)))
973.  	    return FALSE;
974.  
975.  #ifdef STEED
976.  	/* Steeds don't pick up stuff (to avoid shop abuse) */
977.  	if (mtmp == u.usteed) return (FALSE);
978.  #endif
979.  	if (mtmp->isshk) return(TRUE); /* no limit */
980.  	if (mtmp->mpeaceful && !mtmp->mtame) return(FALSE);
981.  	/* otherwise players might find themselves obligated to violate
982.  	 * their alignment if the monster takes something they need
983.  	 */
984.  
985.  	/* special--boulder throwers carry unlimited amounts of boulders */
986.  	if (throws_rocks(mdat) && otyp == BOULDER)
987.  		return(TRUE);
988.  
989.  	/* nymphs deal in stolen merchandise, but not boulders or statues */
990.  	if (mdat->mlet == S_NYMPH)
991.  		return (boolean)(otmp->oclass != ROCK_CLASS);
992.  
993.  	if (curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return FALSE;
994.  
995.  	return(TRUE);
996.  }
997.  

mfndpos Edit

998.  /* return number of acceptable neighbour positions */
999.  int
1000. mfndpos(mon, poss, info, flag)
1001. 	register struct monst *mon;
1002. 	coord *poss;	/* coord poss[9] */
1003. 	long *info;	/* long info[9] */
1004. 	long flag;
1005. {
1006. 	struct permonst *mdat = mon->data;
1007. 	register xchar x,y,nx,ny;
1008. 	register int cnt = 0;
1009. 	register uchar ntyp;
1010. 	uchar nowtyp;
1011. 	boolean wantpool,poolok,lavaok,nodiag;
1012. 	boolean rockok = FALSE, treeok = FALSE, thrudoor;
1013. 	int maxx, maxy;
1014. 
1015. 	x = mon->mx;
1016. 	y = mon->my;
1017. 	nowtyp = levl[x][y].typ;
1018. 
1019. 	nodiag = (mdat == &mons[PM_GRID_BUG]);
1020. 	wantpool = mdat->mlet == S_EEL;
1021. 	poolok = is_flyer(mdat) || is_clinger(mdat) ||
1022. 		 (is_swimmer(mdat) && !wantpool);
1023. 	lavaok = is_flyer(mdat) || is_clinger(mdat) || likes_lava(mdat);
1024. 	thrudoor = ((flag & (ALLOW_WALL|BUSTDOOR)) != 0L);
1025. 	if (flag & ALLOW_DIG) {
1026. 	    struct obj *mw_tmp;
1027. 
1028. 	    /* need to be specific about what can currently be dug */
1029. 	    if (!needspick(mdat)) {
1030. 		rockok = treeok = TRUE;
1031. 	    } else if ((mw_tmp = MON_WEP(mon)) && mw_tmp->cursed &&
1032. 		       mon->weapon_check == NO_WEAPON_WANTED) {
1033. 		rockok = is_pick(mw_tmp);
1034. 		treeok = is_axe(mw_tmp);
1035. 	    } else {
1036. 		rockok = (m_carrying(mon, PICK_AXE) ||
1037. 			  (m_carrying(mon, DWARVISH_MATTOCK) &&
1038. 			   !which_armor(mon, W_ARMS)));
1039. 		treeok = (m_carrying(mon, AXE) ||
1040. 			  (m_carrying(mon, BATTLE_AXE) &&
1041. 			   !which_armor(mon, W_ARMS)));
1042. 	    }
1043. 	    thrudoor |= rockok || treeok;
1044. 	}
1045. 
1046. nexttry:	/* eels prefer the water, but if there is no water nearby,
1047. 		   they will crawl over land */
1048. 	if(mon->mconf) {
1049. 		flag |= ALLOW_ALL;
1050. 		flag &= ~NOTONL;
1051. 	}
1052. 	if(!mon->mcansee)
1053. 		flag |= ALLOW_SSM;
1054. 	maxx = min(x+1,COLNO-1);
1055. 	maxy = min(y+1,ROWNO-1);
1056. 	for(nx = max(1,x-1); nx <= maxx; nx++)
1057. 	  for(ny = max(0,y-1); ny <= maxy; ny++) {
1058. 	    if(nx == x && ny == y) continue;
1059. 	    if(IS_ROCK(ntyp = levl[nx][ny].typ) &&
1060. 	       !((flag & ALLOW_WALL) && may_passwall(nx,ny)) &&
1061. 	       !((IS_TREE(ntyp) ? treeok : rockok) && may_dig(nx,ny))) continue;
1062. 	    /* KMH -- Added iron bars */
1063. 	    if (ntyp == IRONBARS && !(flag & ALLOW_BARS)) continue;
1064. 	    if(IS_DOOR(ntyp) && !amorphous(mdat) &&
1065. 	       ((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) ||
1066. 		(levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR))) &&
1067. 	       !thrudoor) continue;
1068. 	    if(nx != x && ny != y && (nodiag ||
1069. #ifdef REINCARNATION
1070. 	       ((IS_DOOR(nowtyp) &&
1071. 		 ((levl[x][y].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))) ||
1072. 		(IS_DOOR(ntyp) &&
1073. 		 ((levl[nx][ny].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))))
1074. #else
1075. 	       ((IS_DOOR(nowtyp) && (levl[x][y].doormask & ~D_BROKEN)) ||
1076. 		(IS_DOOR(ntyp) && (levl[nx][ny].doormask & ~D_BROKEN)))
1077. #endif
1078. 	       ))
1079. 		continue;
1080. 	    if((is_pool(nx,ny) == wantpool || poolok) &&
1081. 	       (lavaok || !is_lava(nx,ny))) {
1082. 		int dispx, dispy;
1083. 		boolean monseeu = (mon->mcansee && (!Invis || perceives(mdat)));
1084. 		boolean checkobj = OBJ_AT(nx,ny);
1085. 
1086. 		/* Displacement also displaces the Elbereth/scare monster,
1087. 		 * as long as you are visible.
1088. 		 */
1089. 		if(Displaced && monseeu && (mon->mux==nx) && (mon->muy==ny)) {
1090. 		    dispx = u.ux;
1091. 		    dispy = u.uy;
1092. 		} else {
1093. 		    dispx = nx;
1094. 		    dispy = ny;
1095. 		}
1096. 
1097. 		info[cnt] = 0;
1098. 		if ((checkobj || Displaced) && onscary(dispx, dispy, mon)) {
1099. 		    if(!(flag & ALLOW_SSM)) continue;
1100. 		    info[cnt] |= ALLOW_SSM;
1101. 		}
1102. 		if((nx == u.ux && ny == u.uy) ||
1103. 		   (nx == mon->mux && ny == mon->muy)) {
1104. 			if (nx == u.ux && ny == u.uy) {
1105. 				/* If it's right next to you, it found you,
1106. 				 * displaced or no.  We must set mux and muy
1107. 				 * right now, so when we return we can tell
1108. 				 * that the ALLOW_U means to attack _you_ and
1109. 				 * not the image.
1110. 				 */
1111. 				mon->mux = u.ux;
1112. 				mon->muy = u.uy;
1113. 			}
1114. 			if(!(flag & ALLOW_U)) continue;
1115. 			info[cnt] |= ALLOW_U;
1116. 		} else {
1117. 			if(MON_AT(nx, ny)) {
1118. 				struct monst *mtmp2 = m_at(nx, ny);
1119. 				long mmflag = flag | mm_aggression(mon, mtmp2);
1120. 
1121. 				if (!(mmflag & ALLOW_M)) continue;
1122. 				info[cnt] |= ALLOW_M;
1123. 				if (mtmp2->mtame) {
1124. 					if (!(mmflag & ALLOW_TM)) continue;
1125. 					info[cnt] |= ALLOW_TM;
1126. 				}
1127. 			}
1128. 			/* Note: ALLOW_SANCT only prevents movement, not */
1129. 			/* attack, into a temple. */
1130. 			if(level.flags.has_temple &&
1131. 			   *in_rooms(nx, ny, TEMPLE) &&
1132. 			   !*in_rooms(x, y, TEMPLE) &&
1133. 			   in_your_sanctuary((struct monst *)0, nx, ny)) {
1134. 				if(!(flag & ALLOW_SANCT)) continue;
1135. 				info[cnt] |= ALLOW_SANCT;
1136. 			}
1137. 		}
1138. 		if(checkobj && sobj_at(CLOVE_OF_GARLIC, nx, ny)) {
1139. 			if(flag & NOGARLIC) continue;
1140. 			info[cnt] |= NOGARLIC;
1141. 		}
1142. 		if(checkobj && sobj_at(BOULDER, nx, ny)) {
1143. 			if(!(flag & ALLOW_ROCK)) continue;
1144. 			info[cnt] |= ALLOW_ROCK;
1145. 		}
1146. 		if (monseeu && onlineu(nx,ny)) {
1147. 			if(flag & NOTONL) continue;
1148. 			info[cnt] |= NOTONL;
1149. 		}
1150. 		if (nx != x && ny != y && bad_rock(mdat, x, ny)
1151. 			    && bad_rock(mdat, nx, y)
1152. 			    && (bigmonst(mdat) || (curr_mon_load(mon) > 600)))
1153. 			continue;
1154. 		/* The monster avoids a particular type of trap if it's familiar
1155. 		 * with the trap type.  Pets get ALLOW_TRAPS and checking is
1156. 		 * done in dogmove.c.  In either case, "harmless" traps are
1157. 		 * neither avoided nor marked in info[].
1158. 		 */
1159. 		{ register struct trap *ttmp = t_at(nx, ny);
1160. 		    if(ttmp) {
1161. 			if(ttmp->ttyp >= TRAPNUM || ttmp->ttyp == 0)  {
1162. impossible("A monster looked at a very strange trap of type %d.", ttmp->ttyp);
1163. 			    continue;
1164. 			}
1165. 			if ((ttmp->ttyp != RUST_TRAP
1166. 					|| mdat == &mons[PM_IRON_GOLEM])
1167. 				&& ttmp->ttyp != STATUE_TRAP
1168. 				&& ((ttmp->ttyp != PIT
1169. 				    && ttmp->ttyp != SPIKED_PIT
1170. 				    && ttmp->ttyp != TRAPDOOR
1171. 				    && ttmp->ttyp != HOLE)
1172. 				      || (!is_flyer(mdat)
1173. 				    && !is_floater(mdat)
1174. 				    && !is_clinger(mdat))
1175. 				      || In_sokoban(&u.uz))
1176. 				&& (ttmp->ttyp != SLP_GAS_TRAP ||
1177. 				    !resists_sleep(mon))
1178. 				&& (ttmp->ttyp != BEAR_TRAP ||
1179. 				    (mdat->msize > MZ_SMALL &&
1180. 				     !amorphous(mdat) && !is_flyer(mdat)))
1181. 				&& (ttmp->ttyp != FIRE_TRAP ||
1182. 				    !resists_fire(mon))
1183. 				&& (ttmp->ttyp != SQKY_BOARD || !is_flyer(mdat))
1184. 				&& (ttmp->ttyp != WEB || (!amorphous(mdat) &&
1185. 				    !webmaker(mdat)))
1186. 			) {
1187. 			    if (!(flag & ALLOW_TRAPS)) {
1188. 				if (mon->mtrapseen & (1L << (ttmp->ttyp - 1)))
1189. 				    continue;
1190. 			    }
1191. 			    info[cnt] |= ALLOW_TRAPS;
1192. 			}
1193. 		    }
1194. 		}
1195. 		poss[cnt].x = nx;
1196. 		poss[cnt].y = ny;
1197. 		cnt++;
1198. 	    }
1199. 	}
1200. 	if(!cnt && wantpool && !is_pool(x,y)) {
1201. 		wantpool = FALSE;
1202. 		goto nexttry;
1203. 	}
1204. 	return(cnt);
1205. }
1206. 
1207. #endif /* OVL0 */
1208. #ifdef OVL1
1209. 

mm_aggression Edit

1210. /* Monster against monster special attacks; for the specified monster
1211.    combinations, this allows one monster to attack another adjacent one
1212.    in the absence of Conflict.  There is no provision for targetting
1213.    other monsters; just hand to hand fighting when they happen to be
1214.    next to each other. */
1215. STATIC_OVL long
1216. mm_aggression(magr, mdef)
1217. struct monst *magr,	/* monster that is currently deciding where to move */
1218. 	     *mdef;	/* another monster which is next to it */
1219. {
1220. 	/* supposedly purple worms are attracted to shrieking because they
1221. 	   like to eat shriekers, so attack the latter when feasible */
1222. 	if (magr->data == &mons[PM_PURPLE_WORM] &&
1223. 		mdef->data == &mons[PM_SHRIEKER])
1224. 	    return ALLOW_M|ALLOW_TM;
1225. 	/* Various other combinations such as dog vs cat, cat vs rat, and
1226. 	   elf vs orc have been suggested.  For the time being we don't
1227. 	   support those. */
1228. 	return 0L;
1229. }
1230. 

monnear Edit

1231. boolean
1232. monnear(mon, x, y)
1233. register struct monst *mon;
1234. register int x,y;
1235. /* Is the square close enough for the monster to move or attack into? */
1236. {
1237. 	register int distance = dist2(mon->mx, mon->my, x, y);
1238. 	if (distance==2 && mon->data==&mons[PM_GRID_BUG]) return 0;
1239. 	return((boolean)(distance < 3));
1240. }
1241. 

dmonsfree Edit

1242. /* really free dead monsters */
1243. void
1244. dmonsfree()
1245. {
1246.     struct monst **mtmp;
1247.     int count = 0;
1248. 
1249.     for (mtmp = &fmon; *mtmp;) {
1250. 	if ((*mtmp)->mhp <= 0) {
1251. 	    struct monst *freetmp = *mtmp;
1252. 	    *mtmp = (*mtmp)->nmon;
1253. 	    dealloc_monst(freetmp);
1254. 	    count++;
1255. 	} else
1256. 	    mtmp = &(*mtmp)->nmon;
1257.     }
1258. 
1259.     if (count != iflags.purge_monsters)
1260. 	impossible("dmonsfree: %d removed doesn't match %d pending",
1261. 		   count, iflags.purge_monsters);
1262.     iflags.purge_monsters = 0;
1263. }
1264. 
1265. #endif /* OVL1 */
1266. #ifdef OVLB
1267. 

replmon Edit

1268. /* called when monster is moved to larger structure */
1269. void
1270. replmon(mtmp, mtmp2)
1271. register struct monst *mtmp, *mtmp2;
1272. {
1273.     struct obj *otmp;
1274. 
1275.     /* transfer the monster's inventory */
1276.     for (otmp = mtmp2->minvent; otmp; otmp = otmp->nobj) {
1277. #ifdef DEBUG
1278. 	if (otmp->where != OBJ_MINVENT || otmp->ocarry != mtmp)
1279. 	    panic("replmon: minvent inconsistency");
1280. #endif
1281. 	otmp->ocarry = mtmp2;
1282.     }
1283.     mtmp->minvent = 0;
1284. 
1285.     /* remove the old monster from the map and from `fmon' list */
1286.     relmon(mtmp);
1287. 
1288.     /* finish adding its replacement */
1289. #ifdef STEED
1290.     if (mtmp == u.usteed) ; else	/* don't place steed onto the map */
1291. #endif
1292.     place_monster(mtmp2, mtmp2->mx, mtmp2->my);
1293.     if (mtmp2->wormno)	    /* update level.monsters[wseg->wx][wseg->wy] */
1294. 	place_wsegs(mtmp2); /* locations to mtmp2 not mtmp. */
1295.     if (emits_light(mtmp2->data)) {
1296. 	/* since this is so rare, we don't have any `mon_move_light_source' */
1297. 	new_light_source(mtmp2->mx, mtmp2->my,
1298. 			 emits_light(mtmp2->data),
1299. 			 LS_MONSTER, (genericptr_t)mtmp2);
1300. 	/* here we rely on the fact that `mtmp' hasn't actually been deleted */
1301. 	del_light_source(LS_MONSTER, (genericptr_t)mtmp);
1302.     }
1303.     mtmp2->nmon = fmon;
1304.     fmon = mtmp2;
1305.     if (u.ustuck == mtmp) u.ustuck = mtmp2;
1306. #ifdef STEED
1307.     if (u.usteed == mtmp) u.usteed = mtmp2;
1308. #endif
1309.     if (mtmp2->isshk) replshk(mtmp,mtmp2);
1310. 
1311.     /* discard the old monster */
1312.     dealloc_monst(mtmp);
1313. }
1314. 

relmon Edit

1315. /* release mon from display and monster list */
1316. void
1317. relmon(mon)
1318. register struct monst *mon;
1319. {
1320. 	register struct monst *mtmp;
1321. 
1322. 	if (fmon == (struct monst *)0)  panic ("relmon: no fmon available.");
1323. 
1324. 	remove_monster(mon->mx, mon->my);
1325. 
1326. 	if(mon == fmon) fmon = fmon->nmon;
1327. 	else {
1328. 		for(mtmp = fmon; mtmp && mtmp->nmon != mon; mtmp = mtmp->nmon) ;
1329. 		if(mtmp)    mtmp->nmon = mon->nmon;
1330. 		else	    panic("relmon: mon not in list.");
1331. 	}
1332. }
1333. 

m_detach Edit

1334. /* remove effects of mtmp from other data structures */
1335. STATIC_OVL void
1336. m_detach(mtmp, mptr)
1337. struct monst *mtmp;
1338. struct permonst *mptr;	/* reflects mtmp->data _prior_ to mtmp's death */
1339. {
1340. 	if (mtmp->mleashed) m_unleash(mtmp, FALSE);
1341. 	    /* to prevent an infinite relobj-flooreffects-hmon-killed loop */
1342. 	mtmp->mtrapped = 0;
1343. 	mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */
1344. 	relobj(mtmp, 0, FALSE);
1345. 	remove_monster(mtmp->mx, mtmp->my);
1346. 	if (emits_light(mptr))
1347. 	    del_light_source(LS_MONSTER, (genericptr_t)mtmp);
1348. 	newsym(mtmp->mx,mtmp->my);
1349. 	unstuck(mtmp);
1350. 	fill_pit(mtmp->mx, mtmp->my);
1351. 
1352. 	if(mtmp->isshk) shkgone(mtmp);
1353. 	if(mtmp->wormno) wormgone(mtmp);
1354. 	iflags.purge_monsters++;
1355. }
1356. 

mlifesaver Edit

1357. /* find the worn amulet of life saving which will save a monster */
1358. struct obj *
1359. mlifesaver(mon)
1360. struct monst *mon;
1361. {
1362. 	if (!nonliving(mon->data)) {
1363. 	    struct obj *otmp = which_armor(mon, W_AMUL);
1364. 
1365. 	    if (otmp && otmp->otyp == AMULET_OF_LIFE_SAVING)
1366. 		return otmp;
1367. 	}
1368. 	return (struct obj *)0;
1369. }
1370. 

lifesaved_monster Edit

1371. STATIC_OVL void
1372. lifesaved_monster(mtmp)
1373. struct monst *mtmp;
1374. {
1375. 	struct obj *lifesave = mlifesaver(mtmp);
1376. 
1377. 	if (lifesave) {
1378. 		/* not canseemon; amulets are on the head, so you don't want */
1379. 		/* to show this for a long worm with only a tail visible. */
1380. 		/* Nor do you check invisibility, because glowing and disinte- */
1381. 		/* grating amulets are always visible. */
1382. 		if (cansee(mtmp->mx, mtmp->my)) {
1383. 			pline("But wait...");
1384. 			pline("%s medallion begins to glow!",
1385. 				s_suffix(Monnam(mtmp)));
1386. 			makeknown(AMULET_OF_LIFE_SAVING);
1387. 			if (attacktype(mtmp->data, AT_EXPL)
1388. 			    || attacktype(mtmp->data, AT_BOOM))
1389. 				pline("%s reconstitutes!", Monnam(mtmp));
1390. 			else
1391. 				pline("%s looks much better!", Monnam(mtmp));
1392. 			pline_The("medallion crumbles to dust!");
1393. 		}
1394. 		m_useup(mtmp, lifesave);
1395. 		mtmp->mcanmove = 1;
1396. 		mtmp->mfrozen = 0;
1397. 		if (mtmp->mtame && !mtmp->isminion) {
1398. 			wary_dog(mtmp, FALSE);
1399. 		}
1400. 		if (mtmp->mhpmax <= 0) mtmp->mhpmax = 10;
1401. 		mtmp->mhp = mtmp->mhpmax;
1402. 		if (mvitals[monsndx(mtmp->data)].mvflags & G_GENOD) {
1403. 			if (cansee(mtmp->mx, mtmp->my))
1404. 			    pline("Unfortunately %s is still genocided...",
1405. 				mon_nam(mtmp));
1406. 		} else
1407. 			return;
1408. 	}
1409. 	mtmp->mhp = 0;
1410. }
1411. 

mondead Edit

1412. void
1413. mondead(mtmp)
1414. register struct monst *mtmp;
1415. {
1416. 	struct permonst *mptr;
1417. 	int tmp;
1418. 
1419. 	if(mtmp->isgd) {
1420. 		/* if we're going to abort the death, it *must* be before
1421. 		 * the m_detach or there will be relmon problems later */
1422. 		if(!grddead(mtmp)) return;
1423. 	}
1424. 	lifesaved_monster(mtmp);
1425. 	if (mtmp->mhp > 0) return;
1426. 
1427. #ifdef STEED
1428. 	/* Player is thrown from his steed when it dies */
1429. 	if (mtmp == u.usteed)
1430. 		dismount_steed(DISMOUNT_GENERIC);
1431. #endif
1432. 
1433. 	mptr = mtmp->data;		/* save this for m_detach() */
1434. 	/* restore chameleon, lycanthropes to true form at death */
1435. 	if (mtmp->cham)
1436. 	    set_mon_data(mtmp, &mons[cham_to_pm[mtmp->cham]], -1);
1437. 	else if (mtmp->data == &mons[PM_WEREJACKAL])
1438. 	    set_mon_data(mtmp, &mons[PM_HUMAN_WEREJACKAL], -1);
1439. 	else if (mtmp->data == &mons[PM_WEREWOLF])
1440. 	    set_mon_data(mtmp, &mons[PM_HUMAN_WEREWOLF], -1);
1441. 	else if (mtmp->data == &mons[PM_WERERAT])
1442. 	    set_mon_data(mtmp, &mons[PM_HUMAN_WERERAT], -1);
1443. 
1444. 	/* if MAXMONNO monsters of a given type have died, and it
1445. 	 * can be done, extinguish that monster.
1446. 	 *
1447. 	 * mvitals[].died does double duty as total number of dead monsters
1448. 	 * and as experience factor for the player killing more monsters.
1449. 	 * this means that a dragon dying by other means reduces the
1450. 	 * experience the player gets for killing a dragon directly; this
1451. 	 * is probably not too bad, since the player likely finagled the
1452. 	 * first dead dragon via ring of conflict or pets, and extinguishing
1453. 	 * based on only player kills probably opens more avenues of abuse
1454. 	 * for rings of conflict and such.
1455. 	 */
1456. 	tmp = monsndx(mtmp->data);
1457. 	if (mvitals[tmp].died < 255) mvitals[tmp].died++;
1458. 
1459. 	/* if it's a (possibly polymorphed) quest leader, mark him as dead */
1460. 	if (mtmp->m_id == quest_status.leader_m_id)
1461. 	    quest_status.leader_is_dead = TRUE;
1462. #ifdef MAIL
1463. 	/* if the mail daemon dies, no more mail delivery.  -3. */
1464. 	if (tmp == PM_MAIL_DAEMON) mvitals[tmp].mvflags |= G_GENOD;
1465. #endif
1466. 
1467. #ifdef KOPS
1468. 	if (mtmp->data->mlet == S_KOP) {
1469. 	    /* Dead Kops may come back. */
1470. 	    switch(rnd(5)) {
1471. 		case 1:	     /* returns near the stairs */
1472. 			(void) makemon(mtmp->data,xdnstair,ydnstair,NO_MM_FLAGS);
1473. 			break;
1474. 		case 2:	     /* randomly */
1475. 			(void) makemon(mtmp->data,0,0,NO_MM_FLAGS);
1476. 			break;
1477. 		default:
1478. 			break;
1479. 	    }
1480. 	}
1481. #endif
1482. 	if(mtmp->iswiz) wizdead();
1483. 	if(mtmp->data->msound == MS_NEMESIS) nemdead();
1484. 	if(glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
1485. 	    unmap_object(mtmp->mx, mtmp->my);
1486. 	m_detach(mtmp, mptr);
1487. }
1488. 

corpse_chance Edit

1489. /* TRUE if corpse might be dropped, magr may die if mon was swallowed */
1490. boolean
1491. corpse_chance(mon, magr, was_swallowed)
1492. struct monst *mon;
1493. struct monst *magr;			/* killer, if swallowed */
1494. boolean was_swallowed;			/* digestion */
1495. {
1496. 	struct permonst *mdat = mon->data;
1497. 	int i, tmp;
1498. 
1499. 	if (mdat == &mons[PM_VLAD_THE_IMPALER] || mdat->mlet == S_LICH) {
1500. 	    if (cansee(mon->mx, mon->my) && !was_swallowed)
1501. 		pline("%s body crumbles into dust.", s_suffix(Monnam(mon)));
1502. 	    return FALSE;
1503. 	}
1504. 
1505. 	/* Gas spores always explode upon death */
1506. 	for(i = 0; i < NATTK; i++) {
1507. 	    if (mdat->mattk[i].aatyp == AT_BOOM) {
1508. 	    	if (mdat->mattk[i].damn)
1509. 	    	    tmp = d((int)mdat->mattk[i].damn,
1510. 	    	    		(int)mdat->mattk[i].damd);
1511. 	    	else if(mdat->mattk[i].damd)
1512. 	    	    tmp = d((int)mdat->mlevel+1, (int)mdat->mattk[i].damd);
1513. 	    	else tmp = 0;
1514. 		if (was_swallowed && magr) {
1515. 		    if (magr == &youmonst) {
1516. 			There("is an explosion in your %s!",
1517. 			      body_part(STOMACH));
1518. 			Sprintf(killer_buf, "%s explosion",
1519. 				s_suffix(mdat->mname));
1520. 			if (Half_physical_damage) tmp = (tmp+1) / 2;
1521. 			losehp(tmp, killer_buf, KILLED_BY_AN);
1522. 		    } else {
1523. 			if (flags.soundok) You_hear("an explosion.");
1524. 			magr->mhp -= tmp;
1525. 			if (magr->mhp < 1) mondied(magr);
1526. 			if (magr->mhp < 1) { /* maybe lifesaved */
1527. 			    if (canspotmon(magr))
1528. 				pline("%s rips open!", Monnam(magr));
1529. 			} else if (canseemon(magr))
1530. 			    pline("%s seems to have indigestion.",
1531. 				  Monnam(magr));
1532. 		    }
1533. 
1534. 		    return FALSE;
1535. 		}
1536. 
1537. 	    	Sprintf(killer_buf, "%s explosion", s_suffix(mdat->mname));
1538. 	    	killer = killer_buf;
1539. 	    	killer_format = KILLED_BY_AN;
1540. 	    	explode(mon->mx, mon->my, -1, tmp, MON_EXPLODE, EXPL_NOXIOUS); 
1541. 	    	return (FALSE);
1542. 	    }
1543.   	}
1544. 
1545. 	/* must duplicate this below check in xkilled() since it results in
1546. 	 * creating no objects as well as no corpse
1547. 	 */
1548. 	if (LEVEL_SPECIFIC_NOCORPSE(mdat))
1549. 		return FALSE;
1550. 
1551. 	if (bigmonst(mdat) || mdat == &mons[PM_LIZARD]
1552. 		   || is_golem(mdat)
1553. 		   || is_mplayer(mdat)
1554. 		   || is_rider(mdat))
1555. 		return TRUE;
1556. 	return (boolean) (!rn2((int)
1557. 		(2 + ((int)(mdat->geno & G_FREQ)<2) + verysmall(mdat))));
1558. }
1559. 

mondied Edit

1560. /* drop (perhaps) a cadaver and remove monster */
1561. void
1562. mondied(mdef)
1563. register struct monst *mdef;
1564. {
1565. 	mondead(mdef);
1566. 	if (mdef->mhp > 0) return;	/* lifesaved */
1567. 
1568. 	if (corpse_chance(mdef, (struct monst *)0, FALSE) &&
1569. 	    (accessible(mdef->mx, mdef->my) || is_pool(mdef->mx, mdef->my)))
1570. 		(void) make_corpse(mdef);
1571. }
1572. 

mongone Edit

1573. /* monster disappears, not dies */
1574. void
1575. mongone(mdef)
1576. register struct monst *mdef;
1577. {
1578. 	mdef->mhp = 0;	/* can skip some inventory bookkeeping */
1579. #ifdef STEED
1580. 	/* Player is thrown from his steed when it disappears */
1581. 	if (mdef == u.usteed)
1582. 		dismount_steed(DISMOUNT_GENERIC);
1583. #endif
1584. 
1585. 	/* drop special items like the Amulet so that a dismissed Kop or nurse
1586. 	   can't remove them from the game */
1587. 	mdrop_special_objs(mdef);
1588. 	/* release rest of monster's inventory--it is removed from game */
1589. 	discard_minvent(mdef);
1590. #ifndef GOLDOBJ
1591. 	mdef->mgold = 0L;
1592. #endif
1593. 	m_detach(mdef, mdef->data);
1594. }
1595. 

monstone Edit

1596. /* drop a statue or rock and remove monster */
1597. void
1598. monstone(mdef)
1599. register struct monst *mdef;
1600. {
1601. 	struct obj *otmp, *obj, *oldminvent;
1602. 	xchar x = mdef->mx, y = mdef->my;
1603. 	boolean wasinside = FALSE;
1604. 
1605. 	/* we have to make the statue before calling mondead, to be able to
1606. 	 * put inventory in it, and we have to check for lifesaving before
1607. 	 * making the statue....
1608. 	 */
1609. 	lifesaved_monster(mdef);
1610. 	if (mdef->mhp > 0) return;
1611. 
1612. 	mdef->mtrapped = 0;	/* (see m_detach) */
1613. 
1614. 	if ((int)mdef->data->msize > MZ_TINY ||
1615. 		    !rn2(2 + ((int) (mdef->data->geno & G_FREQ) > 2))) {
1616. 		oldminvent = 0;
1617. 		/* some objects may end up outside the statue */
1618. 		while ((obj = mdef->minvent) != 0) {
1619. 		    obj_extract_self(obj);
1620. 		    if (obj->owornmask)
1621. 			update_mon_intrinsics(mdef, obj, FALSE, TRUE);
1622. 		    obj_no_longer_held(obj);
1623. 		    if (obj->owornmask & W_WEP)
1624. 			setmnotwielded(mdef,obj);
1625. 		    obj->owornmask = 0L;
1626. 		    if (obj->otyp == BOULDER ||
1627. #if 0				/* monsters don't carry statues */
1628.      (obj->otyp == STATUE && mons[obj->corpsenm].msize >= mdef->data->msize) ||
1629. #endif
1630. 				obj_resists(obj, 0, 0)) {
1631. 			if (flooreffects(obj, x, y, "fall")) continue;
1632. 			place_object(obj, x, y);
1633. 		    } else {
1634. 			if (obj->lamplit) end_burn(obj, TRUE);
1635. 			obj->nobj = oldminvent;
1636. 			oldminvent = obj;
1637. 		    }
1638. 		}
1639. 		/* defer statue creation until after inventory removal
1640. 		   so that saved monster traits won't retain any stale
1641. 		   item-conferred attributes */
1642. 		otmp = mkcorpstat(STATUE, KEEPTRAITS(mdef) ? mdef : 0,
1643. 				  mdef->data, x, y, FALSE);
1644. 		if (mdef->mnamelth) otmp = oname(otmp, NAME(mdef));
1645. 		while ((obj = oldminvent) != 0) {
1646. 		    oldminvent = obj->nobj;
1647. 		    (void) add_to_container(otmp, obj);
1648. 		}
1649. #ifndef GOLDOBJ
1650. 		if (mdef->mgold) {
1651. 			struct obj *au;
1652. 			au = mksobj(GOLD_PIECE, FALSE, FALSE);
1653. 			au->quan = mdef->mgold;
1654. 			au->owt = weight(au);
1655. 			(void) add_to_container(otmp, au);
1656. 			mdef->mgold = 0;
1657. 		}
1658. #endif
1659. 		/* Archeologists should not break unique statues */
1660. 		if (mdef->data->geno & G_UNIQ)
1661. 			otmp->spe = 1;
1662. 		otmp->owt = weight(otmp);
1663. 	} else
1664. 		otmp = mksobj_at(ROCK, x, y, TRUE, FALSE);
1665. 
1666. 	stackobj(otmp);
1667. 	/* mondead() already does this, but we must do it before the newsym */
1668. 	if(glyph_is_invisible(levl[x][y].glyph))
1669. 	    unmap_object(x, y);
1670. 	if (cansee(x, y)) newsym(x,y);
1671. 	/* We don't currently trap the hero in the statue in this case but we could */
1672. 	if (u.uswallow && u.ustuck == mdef) wasinside = TRUE;
1673. 	mondead(mdef);
1674. 	if (wasinside) {
1675. 		if (is_animal(mdef->data))
1676. 			You("%s through an opening in the new %s.",
1677. 				locomotion(youmonst.data, "jump"),
1678. 				xname(otmp));
1679. 	}
1680. }
1681. 

monkilled Edit

1682. /* another monster has killed the monster mdef */
1683. void
1684. monkilled(mdef, fltxt, how)
1685. register struct monst *mdef;
1686. const char *fltxt;
1687. int how;
1688. {
1689. 	boolean be_sad = FALSE;		/* true if unseen pet is killed */
1690. 
1691. 	if ((mdef->wormno ? worm_known(mdef) : cansee(mdef->mx, mdef->my))
1692. 		&& fltxt)
1693. 	    pline("%s is %s%s%s!", Monnam(mdef),
1694. 			nonliving(mdef->data) ? "destroyed" : "killed",
1695. 		    *fltxt ? " by the " : "",
1696. 		    fltxt
1697. 		 );
1698. 	else
1699. 	    be_sad = (mdef->mtame != 0);
1700. 
1701. 	/* no corpses if digested or disintegrated */
1702. 	if(how == AD_DGST || how == -AD_RBRE)
1703. 	    mondead(mdef);
1704. 	else
1705. 	    mondied(mdef);
1706. 
1707. 	if (be_sad && mdef->mhp <= 0)
1708. 	    You("have a sad feeling for a moment, then it passes.");
1709. }
1710. 

unstuck Edit

1711. void
1712. unstuck(mtmp)
1713. register struct monst *mtmp;
1714. {
1715. 	if(u.ustuck == mtmp) {
1716. 		if(u.uswallow){
1717. 			u.ux = mtmp->mx;
1718. 			u.uy = mtmp->my;
1719. 			u.uswallow = 0;
1720. 			u.uswldtim = 0;
1721. 			if (Punished) placebc();
1722. 			vision_full_recalc = 1;
1723. 			docrt();
1724. 		}
1725. 		u.ustuck = 0;
1726. 	}
1727. }
1728. 

killed Edit

1729. void
1730. killed(mtmp)
1731. register struct monst *mtmp;
1732. {
1733. 	xkilled(mtmp, 1);
1734. }
1735. 

xkilled Edit

1736. /* the player has killed the monster mtmp */
1737. void
1738. xkilled(mtmp, dest)
1739. 	register struct monst *mtmp;
1740. /*
1741.  * Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse
1742.  * either; dest=3, message but no corpse
1743.  */
1744. 	int	dest;
1745. {
1746. 	register int tmp, x = mtmp->mx, y = mtmp->my;
1747. 	register struct permonst *mdat;
1748. 	int mndx;
1749. 	register struct obj *otmp;
1750. 	register struct trap *t;
1751. 	boolean redisp = FALSE;
1752. 	boolean wasinside = u.uswallow && (u.ustuck == mtmp);
1753. 
1754. 
1755. 	/* KMH, conduct */
1756. 	u.uconduct.killer++;
1757. 
1758. 	if (dest & 1) {
1759. 	    const char *verb = nonliving(mtmp->data) ? "destroy" : "kill";
1760. 
1761. 	    if (!wasinside && !canspotmon(mtmp))
1762. 		You("%s it!", verb);
1763. 	    else {
1764. 		You("%s %s!", verb,
1765. 		    !mtmp->mtame ? mon_nam(mtmp) :
1766. 			x_monnam(mtmp,
1767. 				 mtmp->mnamelth ? ARTICLE_NONE : ARTICLE_THE,
1768. 				 "poor",
1769. 				 mtmp->mnamelth ? SUPPRESS_SADDLE : 0,
1770. 				 FALSE));
1771. 	    }
1772. 	}
1773. 
1774. 	if (mtmp->mtrapped && (t = t_at(x, y)) != 0 &&
1775. 		(t->ttyp == PIT || t->ttyp == SPIKED_PIT) &&
1776. 		sobj_at(BOULDER, x, y))
1777. 	    dest |= 2;     /*
1778. 			    * Prevent corpses/treasure being created "on top"
1779. 			    * of the boulder that is about to fall in. This is
1780. 			    * out of order, but cannot be helped unless this
1781. 			    * whole routine is rearranged.
1782. 			    */
1783. 
1784. 	/* your pet knows who just killed it...watch out */
1785. 	if (mtmp->mtame && !mtmp->isminion) EDOG(mtmp)->killed_by_u = 1;
1786. 
1787. 	/* dispose of monster and make cadaver */
1788. 	if(stoned) monstone(mtmp);
1789. 	else mondead(mtmp);
1790. 
1791. 	if (mtmp->mhp > 0) { /* monster lifesaved */
1792. 		/* Cannot put the non-visible lifesaving message in
1793. 		 * lifesaved_monster() since the message appears only when you
1794. 		 * kill it (as opposed to visible lifesaving which always
1795. 		 * appears).
1796. 		 */
1797. 		stoned = FALSE;
1798. 		if (!cansee(x,y)) pline("Maybe not...");
1799. 		return;
1800. 	}
1801. 
1802. 	mdat = mtmp->data; /* note: mondead can change mtmp->data */
1803. 	mndx = monsndx(mdat);
1804. 
1805. 	if (stoned) {
1806. 		stoned = FALSE;
1807. 		goto cleanup;
1808. 	}
1809. 
1810. 	if((dest & 2) || LEVEL_SPECIFIC_NOCORPSE(mdat))
1811. 		goto cleanup;
1812. 
1813. #ifdef MAIL
1814. 	if(mdat == &mons[PM_MAIL_DAEMON]) {
1815. 		stackobj(mksobj_at(SCR_MAIL, x, y, FALSE, FALSE));
1816. 		redisp = TRUE;
1817. 	}
1818. #endif
1819. 	if((!accessible(x, y) && !is_pool(x, y)) ||
1820. 	   (x == u.ux && y == u.uy)) {
1821. 	    /* might be mimic in wall or corpse in lava or on player's spot */
1822. 	    redisp = TRUE;
1823. 	    if(wasinside) spoteffects(TRUE);
1824. 	} else if(x != u.ux || y != u.uy) {
1825. 		/* might be here after swallowed */
1826. 		if (!rn2(6) && !(mvitals[mndx].mvflags & G_NOCORPSE)
1827. #ifdef KOPS
1828. 					&& mdat->mlet != S_KOP
1829. #endif
1830. 							) {
1831. 			int typ;
1832. 
1833. 			otmp = mkobj_at(RANDOM_CLASS, x, y, TRUE);
1834. 			/* Don't create large objects from small monsters */
1835. 			typ = otmp->otyp;
1836. 			if (mdat->msize < MZ_HUMAN && typ != FOOD_RATION
1837. 			    && typ != LEASH
1838. 			    && typ != FIGURINE
1839. 			    && (otmp->owt > 3 ||
1840. 				objects[typ].oc_big /*oc_bimanual/oc_bulky*/ ||
1841. 				is_spear(otmp) || is_pole(otmp) ||
1842. 				typ == MORNING_STAR)) {
1843. 			    delobj(otmp);
1844. 			} else redisp = TRUE;
1845. 		}
1846. 		/* Whether or not it always makes a corpse is, in theory,
1847. 		 * different from whether or not the corpse is "special";
1848. 		 * if we want both, we have to specify it explicitly.
1849. 		 */
1850. 		if (corpse_chance(mtmp, (struct monst *)0, FALSE))
1851. 			(void) make_corpse(mtmp);
1852. 	}
1853. 	if(redisp) newsym(x,y);
1854. cleanup:
1855. 	/* punish bad behaviour */
1856. 	if(is_human(mdat) && (!always_hostile(mdat) && mtmp->malign <= 0) &&
1857. 	   (mndx < PM_ARCHEOLOGIST || mndx > PM_WIZARD) &&
1858. 	   u.ualign.type != A_CHAOTIC) {
1859. 		HTelepat &= ~INTRINSIC;
1860. 		change_luck(-2);
1861. 		You("murderer!");
1862. 		if (Blind && !Blind_telepat)
1863. 		    see_monsters(); /* Can't sense monsters any more. */
1864. 	}
1865. 	if((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame)	change_luck(-1);
1866. 	if (is_unicorn(mdat) &&
1867. 				sgn(u.ualign.type) == sgn(mdat->maligntyp)) {
1868. 		change_luck(-5);
1869. 		You_feel("guilty...");
1870. 	}
1871. 
1872. 	/* give experience points */
1873. 	tmp = experience(mtmp, (int)mvitals[mndx].died + 1);
1874. 	more_experienced(tmp, 0);
1875. 	newexplevel();		/* will decide if you go up */
1876. 
1877. 	/* adjust alignment points */
1878. 	if (mtmp->m_id == quest_status.leader_m_id) {		/* REAL BAD! */
1879. 	    adjalign(-(u.ualign.record+(int)ALIGNLIM/2));
1880. 	    pline("That was %sa bad idea...",
1881. 	    		u.uevent.qcompleted ? "probably " : "");
1882. 	} else if (mdat->msound == MS_NEMESIS)	/* Real good! */
1883. 	    adjalign((int)(ALIGNLIM/4));
1884. 	else if (mdat->msound == MS_GUARDIAN) {	/* Bad */
1885. 	    adjalign(-(int)(ALIGNLIM/8));
1886. 	    if (!Hallucination) pline("That was probably a bad idea...");
1887. 	    else pline("Whoopsie-daisy!");
1888. 	}else if (mtmp->ispriest) {
1889. 		adjalign((p_coaligned(mtmp)) ? -2 : 2);
1890. 		/* cancel divine protection for killing your priest */
1891. 		if (p_coaligned(mtmp)) u.ublessed = 0;
1892. 		if (mdat->maligntyp == A_NONE)
1893. 			adjalign((int)(ALIGNLIM / 4));		/* BIG bonus */
1894. 	} else if (mtmp->mtame) {
1895. 		adjalign(-15);	/* bad!! */
1896. 		/* your god is mighty displeased... */
1897. 		if (!Hallucination) You_hear("the rumble of distant thunder...");
1898. 		else You_hear("the studio audience applaud!");
1899. 	} else if (mtmp->mpeaceful)
1900. 		adjalign(-5);
1901. 
1902. 	/* malign was already adjusted for u.ualign.type and randomization */
1903. 	adjalign(mtmp->malign);
1904. }
1905. 

mon_to_stone Edit

1906. /* changes the monster into a stone monster of the same type */
1907. /* this should only be called when poly_when_stoned() is true */
1908. void
1909. mon_to_stone(mtmp)
1910.     register struct monst *mtmp;
1911. {
1912.     if(mtmp->data->mlet == S_GOLEM) {
1913. 	/* it's a golem, and not a stone golem */
1914. 	if(canseemon(mtmp))
1915. 	    pline("%s solidifies...", Monnam(mtmp));
1916. 	if (newcham(mtmp, &mons[PM_STONE_GOLEM], FALSE, FALSE)) {
1917. 	    if(canseemon(mtmp))
1918. 		pline("Now it's %s.", an(mtmp->data->mname));
1919. 	} else {
1920. 	    if(canseemon(mtmp))
1921. 		pline("... and returns to normal.");
1922. 	}
1923.     } else
1924. 	impossible("Can't polystone %s!", a_monnam(mtmp));
1925. }
1926. 

mnexto Edit

1927. void
1928. mnexto(mtmp)	/* Make monster mtmp next to you (if possible) */
1929. 	struct monst *mtmp;
1930. {
1931. 	coord mm;
1932. 
1933. #ifdef STEED
1934. 	if (mtmp == u.usteed) {
1935. 		/* Keep your steed in sync with you instead */
1936. 		mtmp->mx = u.ux;
1937. 		mtmp->my = u.uy;
1938. 		return;
1939. 	}
1940. #endif
1941. 
1942. 	if(!enexto(&mm, u.ux, u.uy, mtmp->data)) return;
1943. 	rloc_to(mtmp, mm.x, mm.y);
1944. 	return;
1945. }
1946. 

mnearto Edit

1947. /* mnearto()
1948.  * Put monster near (or at) location if possible.
1949.  * Returns:
1950.  *	1 - if a monster was moved from x, y to put mtmp at x, y.
1951.  *	0 - in most cases.
1952.  */
1953. boolean
1954. mnearto(mtmp,x,y,move_other)
1955. register struct monst *mtmp;
1956. xchar x, y;
1957. boolean move_other;	/* make sure mtmp gets to x, y! so move m_at(x, y) */
1958. {
1959. 	struct monst *othermon = (struct monst *)0;
1960. 	xchar newx, newy;
1961. 	coord mm;
1962. 
1963. 	if ((mtmp->mx == x) && (mtmp->my == y)) return(FALSE);
1964. 
1965. 	if (move_other && (othermon = m_at(x, y))) {
1966. 		if (othermon->wormno)
1967. 			remove_worm(othermon);
1968. 		else
1969. 			remove_monster(x, y);
1970. 	}
1971. 
1972. 	newx = x;
1973. 	newy = y;
1974. 
1975. 	if (!goodpos(newx, newy, mtmp, 0)) {
1976. 		/* actually we have real problems if enexto ever fails.
1977. 		 * migrating_mons that need to be placed will cause
1978. 		 * no end of trouble.
1979. 		 */
1980. 		if (!enexto(&mm, newx, newy, mtmp->data)) return(FALSE);
1981. 		newx = mm.x; newy = mm.y;
1982. 	}
1983. 
1984. 	rloc_to(mtmp, newx, newy);
1985. 
1986. 	if (move_other && othermon) {
1987. 	    othermon->mx = othermon->my = 0;
1988. 	    (void) mnearto(othermon, x, y, FALSE);
1989. 	    if ((othermon->mx != x) || (othermon->my != y))
1990. 		return(TRUE);
1991. 	}
1992. 
1993. 	return(FALSE);
1994. }
1995. 
1996. 
1997. static const char *poiseff[] = {
1998. 
1999. 	" feel weaker", "r brain is on fire",
2000. 	"r judgement is impaired", "r muscles won't obey you",
2001. 	" feel very sick", " break out in hives"
2002. };
2003. 

poisontell Edit

2004. void
2005. poisontell(typ)
2006. 
2007. 	int	typ;
2008. {
2009. 	pline("You%s.", poiseff[typ]);
2010. }
2011. 

poisoned Edit

2012. void
2013. poisoned(string, typ, pname, fatal)
2014. const char *string, *pname;
2015. int  typ, fatal;
2016. {
2017. 	int i, plural, kprefix = KILLED_BY_AN;
2018. 	boolean thrown_weapon = (fatal < 0);
2019. 
2020. 	if (thrown_weapon) fatal = -fatal;
2021. 	if(strcmp(string, "blast") && !thrown_weapon) {
2022. 	    /* 'blast' has already given a 'poison gas' message */
2023. 	    /* so have "poison arrow", "poison dart", etc... */
2024. 	    plural = (string[strlen(string) - 1] == 's')? 1 : 0;
2025. 	    /* avoid "The" Orcus's sting was poisoned... */
2026. 	    pline("%s%s %s poisoned!", isupper(*string) ? "" : "The ",
2027. 			string, plural ? "were" : "was");
2028. 	}
2029. 
2030. 	if(Poison_resistance) {
2031. 		if(!strcmp(string, "blast")) shieldeff(u.ux, u.uy);
2032. 		pline_The("poison doesn't seem to affect you.");
2033. 		return;
2034. 	}
2035. 	/* suppress killer prefix if it already has one */
2036. 	if ((i = name_to_mon(pname)) >= LOW_PM && mons[i].geno & G_UNIQ) {
2037. 	    kprefix = KILLED_BY;
2038. 	    if (!type_is_pname(&mons[i])) pname = the(pname);
2039. 	} else if (!strncmpi(pname, "the ", 4) ||
2040. 	    !strncmpi(pname, "an ", 3) ||
2041. 	    !strncmpi(pname, "a ", 2)) {
2042. 	    /*[ does this need a plural check too? ]*/
2043. 	    kprefix = KILLED_BY;
2044. 	}
2045. 	i = rn2(fatal + 20*thrown_weapon);
2046. 	if(i == 0 && typ != A_CHA) {
2047. 		u.uhp = -1;
2048. 		pline_The("poison was deadly...");
2049. 	} else if(i <= 5) {
2050. 		/* Check that a stat change was made */
2051. 		if (adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), 1))
2052. 		    pline("You%s!", poiseff[typ]);
2053. 	} else {
2054. 		i = thrown_weapon ? rnd(6) : rn1(10,6);
2055. 		if(Half_physical_damage) i = (i+1) / 2;
2056. 		losehp(i, pname, kprefix);
2057. 	}
2058. 	if(u.uhp < 1) {
2059. 		killer_format = kprefix;
2060. 		killer = pname;
2061. 		/* "Poisoned by a poisoned ___" is redundant */
2062. 		done(strstri(pname, "poison") ? DIED : POISONING);
2063. 	}
2064. 	(void) encumber_msg();
2065. }
2066. 

m_respond Edit

2067. /* monster responds to player action; not the same as a passive attack */
2068. /* assumes reason for response has been tested, and response _must_ be made */
2069. void
2070. m_respond(mtmp)
2071. register struct monst *mtmp;
2072. {
2073.     if(mtmp->data->msound == MS_SHRIEK) {
2074. 	if(flags.soundok) {
2075. 	    pline("%s shrieks.", Monnam(mtmp));
2076. 	    stop_occupation();
2077. 	}
2078. 	if (!rn2(10)) {
2079. 	    if (!rn2(13))
2080. 		(void) makemon(&mons[PM_PURPLE_WORM], 0, 0, NO_MM_FLAGS);
2081. 	    else
2082. 		(void) makemon((struct permonst *)0, 0, 0, NO_MM_FLAGS);
2083. 
2084. 	}
2085. 	aggravate();
2086.     }
2087.     if(mtmp->data == &mons[PM_MEDUSA]) {
2088. 	register int i;
2089. 	for(i = 0; i < NATTK; i++)
2090. 	     if(mtmp->data->mattk[i].aatyp == AT_GAZE) {
2091. 		 (void) gazemu(mtmp, &mtmp->data->mattk[i]);
2092. 		 break;
2093. 	     }
2094.     }
2095. }
2096. 
2097. #endif /* OVLB */
2098. #ifdef OVL2
2099. 

setmangry Edit

2100. void
2101. setmangry(mtmp)
2102. register struct monst *mtmp;
2103. {
2104. 	mtmp->mstrategy &= ~STRAT_WAITMASK;
2105. 	if(!mtmp->mpeaceful) return;
2106. 	if(mtmp->mtame) return;
2107. 	mtmp->mpeaceful = 0;
2108. 	if(mtmp->ispriest) {
2109. 		if(p_coaligned(mtmp)) adjalign(-5); /* very bad */
2110. 		else adjalign(2);
2111. 	} else
2112. 		adjalign(-1);		/* attacking peaceful monsters is bad */
2113. 	if (couldsee(mtmp->mx, mtmp->my)) {
2114. 		if (humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd)
2115. 		    pline("%s gets angry!", Monnam(mtmp));
2116. 		else if (flags.verbose && flags.soundok) growl(mtmp);
2117. 	}
2118. 
2119. 	/* attacking your own quest leader will anger his or her guardians */
2120. 	if (!flags.mon_moving &&	/* should always be the case here */
2121. 		mtmp->data == &mons[quest_info(MS_LEADER)]) {
2122. 	    struct monst *mon;
2123. 	    struct permonst *q_guardian = &mons[quest_info(MS_GUARDIAN)];
2124. 	    int got_mad = 0;
2125. 
2126. 	    /* guardians will sense this attack even if they can't see it */
2127. 	    for (mon = fmon; mon; mon = mon->nmon)
2128. 		if (!DEADMONSTER(mon) && mon->data == q_guardian && mon->mpeaceful) {
2129. 		    mon->mpeaceful = 0;
2130. 		    if (canseemon(mon)) ++got_mad;
2131. 		}
2132. 	    if (got_mad && !Hallucination)
2133. 		pline_The("%s appear%s to be angry too...",
2134. 		      got_mad == 1 ? q_guardian->mname :
2135. 				    makeplural(q_guardian->mname),
2136. 		      got_mad == 1 ? "s" : "");
2137. 	}
2138. }
2139. 

wakeup Edit

2140. void
2141. wakeup(mtmp)
2142. register struct monst *mtmp;
2143. {
2144. 	mtmp->msleeping = 0;
2145. 	mtmp->meating = 0;	/* assume there's no salvagable food left */
2146. 	setmangry(mtmp);
2147. 	if(mtmp->m_ap_type) seemimic(mtmp);
2148. 	else if (flags.forcefight && !flags.mon_moving && mtmp->mundetected) {
2149. 	    mtmp->mundetected = 0;
2150. 	    newsym(mtmp->mx, mtmp->my);
2151. 	}
2152. }
2153. 

wake_nearby Edit

2154. /* Wake up nearby monsters. */
2155. void
2156. wake_nearby()
2157. {
2158. 	register struct monst *mtmp;
2159. 
2160. 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2161. 	    if (!DEADMONSTER(mtmp) && distu(mtmp->mx,mtmp->my) < u.ulevel*20) {
2162. 		mtmp->msleeping = 0;
2163. 		if (mtmp->mtame && !mtmp->isminion)
2164. 		    EDOG(mtmp)->whistletime = moves;
2165. 	    }
2166. 	}
2167. }
2168. 

wake_nearto Edit

2169. /* Wake up monsters near some particular location. */
2170. void
2171. wake_nearto(x, y, distance)
2172. register int x, y, distance;
2173. {
2174. 	register struct monst *mtmp;
2175. 
2176. 	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2177. 	    if (!DEADMONSTER(mtmp) && mtmp->msleeping && (distance == 0 ||
2178. 				 dist2(mtmp->mx, mtmp->my, x, y) < distance))
2179. 		mtmp->msleeping = 0;
2180. 	}
2181. }
2182. 

seemimic Edit

2183. /* NOTE: we must check for mimicry before calling this routine */
2184. void
2185. seemimic(mtmp)
2186. register struct monst *mtmp;
2187. {
2188. 	unsigned old_app = mtmp->mappearance;
2189. 	uchar old_ap_type = mtmp->m_ap_type;
2190. 
2191. 	mtmp->m_ap_type = M_AP_NOTHING;
2192. 	mtmp->mappearance = 0;
2193. 
2194. 	/*
2195. 	 *  Discovered mimics don't block light.
2196. 	 */
2197. 	if (((old_ap_type == M_AP_FURNITURE &&
2198. 	      (old_app == S_hcdoor || old_app == S_vcdoor)) ||
2199. 	     (old_ap_type == M_AP_OBJECT && old_app == BOULDER)) &&
2200. 	    !does_block(mtmp->mx, mtmp->my, &levl[mtmp->mx][mtmp->my]))
2201. 	    unblock_point(mtmp->mx, mtmp->my);
2202. 
2203. 	newsym(mtmp->mx,mtmp->my);
2204. }
2205. 

rescham Edit

2206. /* force all chameleons to become normal */
2207. void
2208. rescham()
2209. {
2210. 	register struct monst *mtmp;
2211. 	int mcham;
2212. 
2213. 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2214. 		if (DEADMONSTER(mtmp)) continue;
2215. 		mcham = (int) mtmp->cham;
2216. 		if (mcham) {
2217. 			mtmp->cham = CHAM_ORDINARY;
2218. 			(void) newcham(mtmp, &mons[cham_to_pm[mcham]],
2219. 				       FALSE, FALSE);
2220. 		}
2221. 		if(is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN)
2222. 			new_were(mtmp);
2223. 		if(mtmp->m_ap_type && cansee(mtmp->mx, mtmp->my)) {
2224. 			seemimic(mtmp);
2225. 			/* we pretend that the mimic doesn't */
2226. 			/* know that it has been unmasked.   */
2227. 			mtmp->msleeping = 1;
2228. 		}
2229. 	}
2230. }
2231. 

restartcham Edit

2232. /* Let the chameleons change again -dgk */
2233. void
2234. restartcham()
2235. {
2236. 	register struct monst *mtmp;
2237. 
2238. 	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2239. 		if (DEADMONSTER(mtmp)) continue;
2240. 		mtmp->cham = pm_to_cham(monsndx(mtmp->data));
2241. 		if (mtmp->data->mlet == S_MIMIC && mtmp->msleeping &&
2242. 				cansee(mtmp->mx, mtmp->my)) {
2243. 			set_mimic_sym(mtmp);
2244. 			newsym(mtmp->mx,mtmp->my);
2245. 		}
2246. 	}
2247. }
2248. 

restore_cham Edit

2249. /* called when restoring a monster from a saved level; protection
2250.    against shape-changing might be different now than it was at the
2251.    time the level was saved. */
2252. void
2253. restore_cham(mon)
2254. struct monst *mon;
2255. {
2256. 	int mcham;
2257. 
2258. 	if (Protection_from_shape_changers) {
2259. 	    mcham = (int) mon->cham;
2260. 	    if (mcham) {
2261. 		mon->cham = CHAM_ORDINARY;
2262. 		(void) newcham(mon, &mons[cham_to_pm[mcham]], FALSE, FALSE);
2263. 	    } else if (is_were(mon->data) && !is_human(mon->data)) {
2264. 		new_were(mon);
2265. 	    }
2266. 	} else if (mon->cham == CHAM_ORDINARY) {
2267. 	    mon->cham = pm_to_cham(monsndx(mon->data));
2268. 	}
2269. }
2270. 

restrap Edit

2271. /* unwatched hiders may hide again; if so, a 1 is returned.  */
2272. STATIC_OVL boolean
2273. restrap(mtmp)
2274. register struct monst *mtmp;
2275. {
2276. 	if(mtmp->cham || mtmp->mcan || mtmp->m_ap_type ||
2277. 	   cansee(mtmp->mx, mtmp->my) || rn2(3) || (mtmp == u.ustuck) ||
2278. 	   (sensemon(mtmp) && distu(mtmp->mx, mtmp->my) <= 2))
2279. 		return(FALSE);
2280. 
2281. 	if(mtmp->data->mlet == S_MIMIC) {
2282. 		set_mimic_sym(mtmp);
2283. 		return(TRUE);
2284. 	} else
2285. 	    if(levl[mtmp->mx][mtmp->my].typ == ROOM)  {
2286. 		mtmp->mundetected = 1;
2287. 		return(TRUE);
2288. 	    }
2289. 
2290. 	return(FALSE);
2291. }
2292. 
2293. short *animal_list = 0;		/* list of PM values for animal monsters */
2294. int animal_list_count;
2295. 

mon_animal_list Edit

2296. void
2297. mon_animal_list(construct)
2298. boolean construct;
2299. {
2300. 	if (construct) {
2301. 	    short animal_temp[SPECIAL_PM];
2302. 	    int i, n;
2303. 
2304. 	 /* if (animal_list) impossible("animal_list already exists"); */
2305. 
2306. 	    for (n = 0, i = LOW_PM; i < SPECIAL_PM; i++)
2307. 		if (is_animal(&mons[i])) animal_temp[n++] = i;
2308. 	 /* if (n == 0) animal_temp[n++] = NON_PM; */
2309. 
2310. 	    animal_list = (short *)alloc(n * sizeof *animal_list);
2311. 	    (void) memcpy((genericptr_t)animal_list,
2312. 			  (genericptr_t)animal_temp,
2313. 			  n * sizeof *animal_list);
2314. 	    animal_list_count = n;
2315. 	} else {	/* release */
2316. 	    if (animal_list) free((genericptr_t)animal_list), animal_list = 0;
2317. 	    animal_list_count = 0;
2318. 	}
2319. }
2320. 

pick_animal Edit

2321. STATIC_OVL int
2322. pick_animal()
2323. {
2324. 	if (!animal_list) mon_animal_list(TRUE);
2325. 
2326. 	return animal_list[rn2(animal_list_count)];
2327. }
2328. 

select_newcham_form Edit

2329. STATIC_OVL int
2330. select_newcham_form(mon)
2331. struct monst *mon;
2332. {
2333. 	int mndx = NON_PM;
2334. 
2335. 	switch (mon->cham) {
2336. 	    case CHAM_SANDESTIN:
2337. 		if (rn2(7)) mndx = pick_nasty();
2338. 		break;
2339. 	    case CHAM_DOPPELGANGER:
2340. 		if (!rn2(7)) mndx = pick_nasty();
2341. 		else if (rn2(3)) mndx = rn1(PM_WIZARD - PM_ARCHEOLOGIST + 1,
2342. 					    PM_ARCHEOLOGIST);
2343. 		break;
2344. 	    case CHAM_CHAMELEON:
2345. 		if (!rn2(3)) mndx = pick_animal();
2346. 		break;
2347. 	    case CHAM_ORDINARY:
2348. 	      {
2349. 		struct obj *m_armr = which_armor(mon, W_ARM);
2350. 
2351. 		if (m_armr && Is_dragon_scales(m_armr))
2352. 		    mndx = Dragon_scales_to_pm(m_armr) - mons;
2353. 		else if (m_armr && Is_dragon_mail(m_armr))
2354. 		    mndx = Dragon_mail_to_pm(m_armr) - mons;
2355. 	      }
2356. 		break;
2357. 	}
2358. #ifdef WIZARD
2359. 	/* For debugging only: allow control of polymorphed monster; not saved */
2360. 	if (wizard && iflags.mon_polycontrol) {
2361. 		char pprompt[BUFSZ], buf[BUFSZ];
2362. 		int tries = 0;
2363. 		do {
2364. 			Sprintf(pprompt,
2365. 				"Change %s into what kind of monster? [type the name]",
2366. 				mon_nam(mon));
2367. 			getlin(pprompt,buf);
2368. 			mndx = name_to_mon(buf);
2369. 			if (mndx < LOW_PM)
2370. 				You("cannot polymorph %s into that.", mon_nam(mon));
2371. 			else break;
2372. 		} while(++tries < 5);
2373. 		if (tries==5) pline(thats_enough_tries);
2374. 	}
2375. #endif /*WIZARD*/
2376. 	if (mndx == NON_PM) mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
2377. 	return mndx;
2378. }
2379. 

newcham Edit

2380. /* make a chameleon look like a new monster; returns 1 if it actually changed */
2381. int
2382. newcham(mtmp, mdat, polyspot, msg)
2383. struct monst *mtmp;
2384. struct permonst *mdat;
2385. boolean polyspot;	/* change is the result of wand or spell of polymorph */
2386. boolean msg;		/* "The oldmon turns into a newmon!" */
2387. {
2388. 	int mhp, hpn, hpd;
2389. 	int mndx, tryct;
2390. 	struct permonst *olddata = mtmp->data;
2391. 	char oldname[BUFSZ];
2392. 
2393. 	if (msg) {
2394. 	    /* like Monnam() but never mention saddle */
2395. 	    Strcpy(oldname, x_monnam(mtmp, ARTICLE_THE, (char *)0,
2396. 				     SUPPRESS_SADDLE, FALSE));
2397. 	    oldname[0] = highc(oldname[0]);
2398. 	}
2399. 
2400. 	/* mdat = 0 -> caller wants a random monster shape */
2401. 	tryct = 0;
2402. 	if (mdat == 0) {
2403. 	    while (++tryct <= 100) {
2404. 		mndx = select_newcham_form(mtmp);
2405. 		mdat = &mons[mndx];
2406. 		if ((mvitals[mndx].mvflags & G_GENOD) != 0 ||
2407. 			is_placeholder(mdat)) continue;
2408. 		/* polyok rules out all M2_PNAME and M2_WERE's;
2409. 		   select_newcham_form might deliberately pick a player
2410. 		   character type, so we can't arbitrarily rule out all
2411. 		   human forms any more */
2412. 		if (is_mplayer(mdat) || (!is_human(mdat) && polyok(mdat)))
2413. 		    break;
2414. 	    }
2415. 	    if (tryct > 100) return 0;	/* Should never happen */
2416. 	} else if (mvitals[monsndx(mdat)].mvflags & G_GENOD)
2417. 	    return(0);	/* passed in mdat is genocided */
2418. 
2419. 	if(is_male(mdat)) {
2420. 		if(mtmp->female) mtmp->female = FALSE;
2421. 	} else if (is_female(mdat)) {
2422. 		if(!mtmp->female) mtmp->female = TRUE;
2423. 	} else if (!is_neuter(mdat)) {
2424. 		if(!rn2(10)) mtmp->female = !mtmp->female;
2425. 	}
2426. 
2427. 	if (In_endgame(&u.uz) && is_mplayer(olddata)) {
2428. 		/* mplayers start out as "Foo the Bar", but some of the
2429. 		 * titles are inappropriate when polymorphed, particularly
2430. 		 * into the opposite sex.  players don't use ranks when
2431. 		 * polymorphed, so dropping the rank for mplayers seems
2432. 		 * reasonable.
2433. 		 */
2434. 		char *p = index(NAME(mtmp), ' ');
2435. 		if (p) {
2436. 			*p = '\0';
2437. 			mtmp->mnamelth = p - NAME(mtmp) + 1;
2438. 		}
2439. 	}
2440. 
2441. 	if(mdat == mtmp->data) return(0);	/* still the same monster */
2442. 
2443. 	if(mtmp->wormno) {			/* throw tail away */
2444. 		wormgone(mtmp);
2445. 		place_monster(mtmp, mtmp->mx, mtmp->my);
2446. 	}
2447. 
2448. 	hpn = mtmp->mhp;
2449. 	hpd = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel;
2450. 	if(!hpd) hpd = 4;
2451. 
2452. 	mtmp->m_lev = adj_lev(mdat);		/* new monster level */
2453. 
2454. 	mhp = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel;
2455. 	if(!mhp) mhp = 4;
2456. 
2457. 	/* new hp: same fraction of max as before */
2458. #ifndef LINT
2459. 	mtmp->mhp = (int)(((long)hpn*(long)mhp)/(long)hpd);
2460. #endif
2461. 	if(mtmp->mhp < 0) mtmp->mhp = hpn;	/* overflow */
2462. /* Unlikely but not impossible; a 1HD creature with 1HP that changes into a
2463.    0HD creature will require this statement */
2464. 	if (!mtmp->mhp) mtmp->mhp = 1;
2465. 
2466. /* and the same for maximum hit points */
2467. 	hpn = mtmp->mhpmax;
2468. #ifndef LINT
2469. 	mtmp->mhpmax = (int)(((long)hpn*(long)mhp)/(long)hpd);
2470. #endif
2471. 	if(mtmp->mhpmax < 0) mtmp->mhpmax = hpn;	/* overflow */
2472. 	if (!mtmp->mhpmax) mtmp->mhpmax = 1;
2473. 
2474. 	/* take on the new form... */
2475. 	set_mon_data(mtmp, mdat, 0);
2476. 
2477. 	if (emits_light(olddata) != emits_light(mtmp->data)) {
2478. 	    /* used to give light, now doesn't, or vice versa,
2479. 	       or light's range has changed */
2480. 	    if (emits_light(olddata))
2481. 		del_light_source(LS_MONSTER, (genericptr_t)mtmp);
2482. 	    if (emits_light(mtmp->data))
2483. 		new_light_source(mtmp->mx, mtmp->my, emits_light(mtmp->data),
2484. 				 LS_MONSTER, (genericptr_t)mtmp);
2485. 	}
2486. 	if (!mtmp->perminvis || pm_invisible(olddata))
2487. 	    mtmp->perminvis = pm_invisible(mdat);
2488. 	mtmp->minvis = mtmp->invis_blkd ? 0 : mtmp->perminvis;
2489. 	if (!(hides_under(mdat) && OBJ_AT(mtmp->mx, mtmp->my)) &&
2490. 			!(mdat->mlet == S_EEL && is_pool(mtmp->mx, mtmp->my)))
2491. 		mtmp->mundetected = 0;
2492. 	if (u.ustuck == mtmp) {
2493. 		if(u.uswallow) {
2494. 			if(!attacktype(mdat,AT_ENGL)) {
2495. 				/* Does mdat care? */
2496. 				if (!noncorporeal(mdat) && !amorphous(mdat) &&
2497. 				    !is_whirly(mdat) &&
2498. 				    (mdat != &mons[PM_YELLOW_LIGHT])) {
2499. 					You("break out of %s%s!", mon_nam(mtmp),
2500. 					    (is_animal(mdat)?
2501. 					    "'s stomach" : ""));
2502. 					mtmp->mhp = 1;  /* almost dead */
2503. 				}
2504. 				expels(mtmp, olddata, FALSE);
2505. 			} else {
2506. 				/* update swallow glyphs for new monster */
2507. 				swallowed(0);
2508. 			}
2509. 		} else if (!sticks(mdat) && !sticks(youmonst.data))
2510. 			unstuck(mtmp);
2511. 	}
2512. 
2513. #ifndef DCC30_BUG
2514. 	if (mdat == &mons[PM_LONG_WORM] && (mtmp->wormno = get_wormno()) != 0) {
2515. #else
2516. 	/* DICE 3.0 doesn't like assigning and comparing mtmp->wormno in the
2517. 	 * same expression.
2518. 	 */
2519. 	if (mdat == &mons[PM_LONG_WORM] &&
2520. 		(mtmp->wormno = get_wormno(), mtmp->wormno != 0)) {
2521. #endif
2522. 	    /* we can now create worms with tails - 11/91 */
2523. 	    initworm(mtmp, rn2(5));
2524. 	    if (count_wsegs(mtmp))
2525. 		place_worm_tail_randomly(mtmp, mtmp->mx, mtmp->my);
2526. 	}
2527. 
2528. 	newsym(mtmp->mx,mtmp->my);
2529. 
2530. 	if (msg) {
2531. 	    uchar save_mnamelth = mtmp->mnamelth;
2532. 	    mtmp->mnamelth = 0;
2533. 	    pline("%s turns into %s!", oldname,
2534. 		  mdat == &mons[PM_GREEN_SLIME] ? "slime" :
2535. 		  x_monnam(mtmp, ARTICLE_A, (char*)0, SUPPRESS_SADDLE, FALSE));
2536. 	    mtmp->mnamelth = save_mnamelth;
2537. 	}
2538. 
2539. 	possibly_unwield(mtmp, polyspot);	/* might lose use of weapon */
2540. 	mon_break_armor(mtmp, polyspot);
2541. 	if (!(mtmp->misc_worn_check & W_ARMG))
2542. 	    mselftouch(mtmp, "No longer petrify-resistant, ",
2543. 			!flags.mon_moving);
2544. 	m_dowear(mtmp, FALSE);
2545. 
2546. 	/* This ought to re-test can_carry() on each item in the inventory
2547. 	 * rather than just checking ex-giants & boulders, but that'd be
2548. 	 * pretty expensive to perform.  If implemented, then perhaps
2549. 	 * minvent should be sorted in order to drop heaviest items first.
2550. 	 */
2551. 	/* former giants can't continue carrying boulders */
2552. 	if (mtmp->minvent && !throws_rocks(mdat)) {
2553. 	    register struct obj *otmp, *otmp2;
2554. 
2555. 	    for (otmp = mtmp->minvent; otmp; otmp = otmp2) {
2556. 		otmp2 = otmp->nobj;
2557. 		if (otmp->otyp == BOULDER) {
2558. 		    /* this keeps otmp from being polymorphed in the
2559. 		       same zap that the monster that held it is polymorphed */
2560. 		    if (polyspot) bypass_obj(otmp);
2561. 		    obj_extract_self(otmp);
2562. 		    /* probably ought to give some "drop" message here */
2563. 		    if (flooreffects(otmp, mtmp->mx, mtmp->my, "")) continue;
2564. 		    place_object(otmp, mtmp->mx, mtmp->my);
2565. 		}
2566. 	    }
2567. 	}
2568. 
2569. 	return(1);
2570. }
2571. 
2572. /* sometimes an egg will be special */
2573. #define BREEDER_EGG (!rn2(77))
2574. 

can_be_hatched Edit

2575. /*
2576.  * Determine if the given monster number can be hatched from an egg.
2577.  * Return the monster number to use as the egg's corpsenm.  Return
2578.  * NON_PM if the given monster can't be hatched.
2579.  */
2580. int
2581. can_be_hatched(mnum)
2582. int mnum;
2583. {
2584.     /* ranger quest nemesis has the oviparous bit set, making it
2585.        be possible to wish for eggs of that unique monster; turn
2586.        such into ordinary eggs rather than forbidding them outright */
2587.     if (mnum == PM_SCORPIUS) mnum = PM_SCORPION;
2588. 
2589.     mnum = little_to_big(mnum);
2590.     /*
2591.      * Queen bees lay killer bee eggs (usually), but killer bees don't
2592.      * grow into queen bees.  Ditto for [winged-]gargoyles.
2593.      */
2594.     if (mnum == PM_KILLER_BEE || mnum == PM_GARGOYLE ||
2595. 	    (lays_eggs(&mons[mnum]) && (BREEDER_EGG ||
2596. 		(mnum != PM_QUEEN_BEE && mnum != PM_WINGED_GARGOYLE))))
2597. 	return mnum;
2598.     return NON_PM;
2599. }
2600. 

egg_type_from_parent Edit

2601. /* type of egg laid by #sit; usually matches parent */
2602. int
2603. egg_type_from_parent(mnum, force_ordinary)
2604. int mnum;	/* parent monster; caller must handle lays_eggs() check */
2605. boolean force_ordinary;
2606. {
2607.     if (force_ordinary || !BREEDER_EGG) {
2608. 	if (mnum == PM_QUEEN_BEE) mnum = PM_KILLER_BEE;
2609. 	else if (mnum == PM_WINGED_GARGOYLE) mnum = PM_GARGOYLE;
2610.     }
2611.     return mnum;
2612. }
2613. 

dead_species Edit

2614. /* decide whether an egg of the indicated monster type is viable; */
2615. /* also used to determine whether an egg or tin can be created... */
2616. boolean
2617. dead_species(m_idx, egg)
2618. int m_idx;
2619. boolean egg;
2620. {
2621. 	/*
2622. 	 * For monsters with both baby and adult forms, genociding either
2623. 	 * form kills all eggs of that monster.  Monsters with more than
2624. 	 * two forms (small->large->giant mimics) are more or less ignored;
2625. 	 * fortunately, none of them have eggs.  Species extinction due to
2626. 	 * overpopulation does not kill eggs.
2627. 	 */
2628. 	return (boolean)
2629. 		(m_idx >= LOW_PM &&
2630. 		 ((mvitals[m_idx].mvflags & G_GENOD) != 0 ||
2631. 		  (egg &&
2632. 		   (mvitals[big_to_little(m_idx)].mvflags & G_GENOD) != 0)));
2633. }
2634. 

kill_eggs Edit

2635. /* kill off any eggs of genocided monsters */
2636. STATIC_OVL void
2637. kill_eggs(obj_list)
2638. struct obj *obj_list;
2639. {
2640. 	struct obj *otmp;
2641. 
2642. 	for (otmp = obj_list; otmp; otmp = otmp->nobj)
2643. 	    if (otmp->otyp == EGG) {
2644. 		if (dead_species(otmp->corpsenm, TRUE)) {
2645. 		    /*
2646. 		     * It seems we could also just catch this when
2647. 		     * it attempted to hatch, so we wouldn't have to
2648. 		     * search all of the objlists.. or stop all
2649. 		     * hatch timers based on a corpsenm.
2650. 		     */
2651. 		    kill_egg(otmp);
2652. 		}
2653. #if 0	/* not used */
2654. 	    } else if (otmp->otyp == TIN) {
2655. 		if (dead_species(otmp->corpsenm, FALSE))
2656. 		    otmp->corpsenm = NON_PM;	/* empty tin */
2657. 	    } else if (otmp->otyp == CORPSE) {
2658. 		if (dead_species(otmp->corpsenm, FALSE))
2659. 		    ;		/* not yet implemented... */
2660. #endif
2661. 	    } else if (Has_contents(otmp)) {
2662. 		kill_eggs(otmp->cobj);
2663. 	    }
2664. }
2665. 

kill_genocided_monsters Edit

2666. /* kill all members of genocided species */
2667. void
2668. kill_genocided_monsters()
2669. {
2670. 	struct monst *mtmp, *mtmp2;
2671. 	boolean kill_cham[CHAM_MAX_INDX+1];
2672. 	int mndx;
2673. 
2674. 	kill_cham[CHAM_ORDINARY] = FALSE;	/* (this is mndx==0) */
2675. 	for (mndx = 1; mndx <= CHAM_MAX_INDX; mndx++)
2676. 	  kill_cham[mndx] = (mvitals[cham_to_pm[mndx]].mvflags & G_GENOD) != 0;
2677. 	/*
2678. 	 * Called during genocide, and again upon level change.  The latter
2679. 	 * catches up with any migrating monsters as they finally arrive at
2680. 	 * their intended destinations, so possessions get deposited there.
2681. 	 *
2682. 	 * Chameleon handling:
2683. 	 *	1) if chameleons have been genocided, destroy them
2684. 	 *	   regardless of current form;
2685. 	 *	2) otherwise, force every chameleon which is imitating
2686. 	 *	   any genocided species to take on a new form.
2687. 	 */
2688. 	for (mtmp = fmon; mtmp; mtmp = mtmp2) {
2689. 	    mtmp2 = mtmp->nmon;
2690. 	    if (DEADMONSTER(mtmp)) continue;
2691. 	    mndx = monsndx(mtmp->data);
2692. 	    if ((mvitals[mndx].mvflags & G_GENOD) || kill_cham[mtmp->cham]) {
2693. 		if (mtmp->cham && !kill_cham[mtmp->cham])
2694. 		    (void) newcham(mtmp, (struct permonst *)0, FALSE, FALSE);
2695. 		else
2696. 		    mondead(mtmp);
2697. 	    }
2698. 	    if (mtmp->minvent) kill_eggs(mtmp->minvent);
2699. 	}
2700. 
2701. 	kill_eggs(invent);
2702. 	kill_eggs(fobj);
2703. 	kill_eggs(level.buriedobjlist);
2704. }
2705. 
2706. #endif /* OVL2 */
2707. #ifdef OVLB
2708. 

golemeffects Edit

2709. void
2710. golemeffects(mon, damtype, dam)
2711. register struct monst *mon;
2712. int damtype, dam;
2713. {
2714.     int heal = 0, slow = 0;
2715. 
2716.     if (mon->data == &mons[PM_FLESH_GOLEM]) {
2717. 	if (damtype == AD_ELEC) heal = dam / 6;
2718. 	else if (damtype == AD_FIRE || damtype == AD_COLD) slow = 1;
2719.     } else if (mon->data == &mons[PM_IRON_GOLEM]) {
2720. 	if (damtype == AD_ELEC) slow = 1;
2721. 	else if (damtype == AD_FIRE) heal = dam;
2722.     } else {
2723. 	return;
2724.     }
2725.     if (slow) {
2726. 	if (mon->mspeed != MSLOW)
2727. 	    mon_adjust_speed(mon, -1, (struct obj *)0);
2728.     }
2729.     if (heal) {
2730. 	if (mon->mhp < mon->mhpmax) {
2731. 	    mon->mhp += dam;
2732. 	    if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax;
2733. 	    if (cansee(mon->mx, mon->my))
2734. 		pline("%s seems healthier.", Monnam(mon));
2735. 	}
2736.     }
2737. }
2738. 

angry_guards Edit

2739. boolean
2740. angry_guards(silent)
2741. register boolean silent;
2742. {
2743. 	register struct monst *mtmp;
2744. 	register int ct = 0, nct = 0, sct = 0, slct = 0;
2745. 
2746. 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2747. 		if (DEADMONSTER(mtmp)) continue;
2748. 		if((mtmp->data == &mons[PM_WATCHMAN] ||
2749. 			       mtmp->data == &mons[PM_WATCH_CAPTAIN])
2750. 					&& mtmp->mpeaceful) {
2751. 			ct++;
2752. 			if(cansee(mtmp->mx, mtmp->my) && mtmp->mcanmove) {
2753. 				if (distu(mtmp->mx, mtmp->my) == 2) nct++;
2754. 				else sct++;
2755. 			}
2756. 			if (mtmp->msleeping || mtmp->mfrozen) {
2757. 				slct++;
2758. 				mtmp->msleeping = mtmp->mfrozen = 0;
2759. 			}
2760. 			mtmp->mpeaceful = 0;
2761. 		}
2762. 	}
2763. 	if(ct) {
2764. 	    if(!silent) { /* do we want pline msgs? */
2765. 		if(slct) pline_The("guard%s wake%s up!",
2766. 				 slct > 1 ? "s" : "", slct == 1 ? "s" : "");
2767. 		if(nct || sct) {
2768. 			if(nct) pline_The("guard%s get%s angry!",
2769. 				nct == 1 ? "" : "s", nct == 1 ? "s" : "");
2770. 			else if(!Blind)
2771. 				You("see %sangry guard%s approaching!",
2772. 				  sct == 1 ? "an " : "", sct > 1 ? "s" : "");
2773. 		} else if(flags.soundok)
2774. 			You_hear("the shrill sound of a guard's whistle.");
2775. 	    }
2776. 	    return(TRUE);
2777. 	}
2778. 	return(FALSE);
2779. }
2780. 

pacify_guards Edit

2781. void
2782. pacify_guards()
2783. {
2784. 	register struct monst *mtmp;
2785. 
2786. 	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2787. 	    if (DEADMONSTER(mtmp)) continue;
2788. 	    if (mtmp->data == &mons[PM_WATCHMAN] ||
2789. 		mtmp->data == &mons[PM_WATCH_CAPTAIN])
2790. 	    mtmp->mpeaceful = 1;
2791. 	}
2792. }
2793. 

mimic_hit_msg Edit

2794. void
2795. mimic_hit_msg(mtmp, otyp)
2796. struct monst *mtmp;
2797. short otyp;
2798. {
2799. 	short ap = mtmp->mappearance;
2800. 
2801. 	switch(mtmp->m_ap_type) {
2802. 	    case M_AP_NOTHING:			
2803. 	    case M_AP_FURNITURE:
2804. 	    case M_AP_MONSTER:
2805. 		break;
2806. 	    case M_AP_OBJECT:
2807. 		if (otyp == SPE_HEALING || otyp == SPE_EXTRA_HEALING) {
2808. 		    pline("%s seems a more vivid %s than before.",
2809. 				The(simple_typename(ap)),
2810. 				c_obj_colors[objects[ap].oc_color]);
2811. 		}
2812. 		break;
2813. 	}
2814. }
2815. #endif /* OVLB */
2816. 
2817. /*mon.c*/

Also on Fandom

Random Wiki