Source:NetHack 2.2a/mon.c

From NetHackWiki
Jump to navigation Jump to search

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

Warning! This is the source code from an old release. For the latest release, see Source code

Screenshots and source code from Hack are used under the CWI license.

1.    /*	SCCS Id: @(#)mon.c	2.1	87/10/17
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    
4.    #include "hack.h"
5.    #include "mfndpos.h"
6.    extern struct monst *mkmon_at();
7.    extern struct trap *maketrap();
8.    extern struct obj *mkobj_at(), *mksobj_at();
9.    extern char *hcolor();
10.   #ifdef KAA
11.   extern boolean	stoned;
12.   extern char mlarge[];
13.   #endif
14.   #ifdef RPH
15.   extern struct obj *mk_named_obj_at();
16.   #endif
17.   
18.   int warnlevel;		/* used by movemon and dochugw */
19.   long lastwarntime;
20.   int lastwarnlev;
21.   char	*warnings[] = {	"white", "pink", "red", "ruby", "purple", "black"  };
22.   
23.   movemon()
24.   {
25.   	register struct monst *mtmp;
26.   	register int fr;
27.   
28.   	warnlevel = 0;
29.   
30.   	while(1) {
31.   		/* find a monster that we haven't treated yet */
32.   		/* note that mtmp or mtmp->nmon might get killed
33.   		   while mtmp moves, so we cannot just walk down the
34.   		   chain (even new monsters might get created!) */
35.   		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
36.   			if(mtmp->mlstmv < moves) goto next_mon;
37.   		/* treated all monsters */
38.   		break;
39.   
40.   	next_mon:
41.   		mtmp->mlstmv = moves;
42.   
43.   		/* most monsters drown in pools */
44.   		{ boolean inpool, iseel;
45.   
46.   		  inpool = (levl[mtmp->mx][mtmp->my].typ == POOL);
47.   		  iseel = (mtmp->data->mlet == ';');
48.   		  if(inpool && !iseel) {
49.   			if(cansee(mtmp->mx,mtmp->my))
50.   			    pline("%s drowns.", Monnam(mtmp));
51.   			mondead(mtmp);
52.   			continue;
53.   		  }
54.   		/* but eels have a difficult time outside */
55.   		  if(iseel && !inpool) {
56.   			if(mtmp->mhp > 1) mtmp->mhp--;
57.   			mtmp->mflee = 1;
58.   			mtmp->mfleetim += 2;
59.   		  }
60.   		}
61.   		if(mtmp->mblinded && !--mtmp->mblinded)
62.   			mtmp->mcansee = 1;
63.   		if(mtmp->mfleetim && !--mtmp->mfleetim)
64.   			mtmp->mflee = 0;
65.   #ifdef HARD
66.   		/* unwatched mimics and piercers may hide again  [MRS] */
67.   		if(restrap(mtmp))	continue;
68.   #endif
69.   		if(mtmp->mimic) continue;
70.   		if(mtmp->mspeed != MSLOW || !(moves%2)){
71.   			/* continue if the monster died fighting */
72.   			fr = -1;
73.   			if(Conflict && cansee(mtmp->mx,mtmp->my)
74.   				&& (fr = fightm(mtmp)) == 2)
75.   				continue;
76.   			if(fr<0 && dochugw(mtmp))
77.   				continue;
78.   		}
79.   		if(mtmp->mspeed == MFAST && dochugw(mtmp))
80.   			continue;
81.   	}
82.   
83.   	warnlevel -= u.ulevel;
84.   	if(warnlevel >= SIZE(warnings))
85.   		warnlevel = SIZE(warnings)-1;
86.   	if(warnlevel >= 0)
87.   	if(warnlevel > lastwarnlev || moves > lastwarntime + 5){
88.   	    register char *rr;
89.   	    switch((int) (Warning & (LEFT_RING | RIGHT_RING))){
90.   	    case LEFT_RING:
91.   		rr = "Your left ring glows";
92.   		break;
93.   	    case RIGHT_RING:
94.   		rr = "Your right ring glows";
95.   		break;
96.   	    case LEFT_RING | RIGHT_RING:
97.   		rr = "Both your rings glow";
98.   		break;
99.   	    default:
100.  		rr = "Your fingertips glow";
101.  		break;
102.  	    }
103.  	    pline("%s %s!", rr, Hallucination ? hcolor() : warnings[warnlevel]);
104.  	    lastwarntime = moves;
105.  	    lastwarnlev = warnlevel;
106.  	}
107.  
108.  	dmonsfree();	/* remove all dead monsters */
109.  }
110.  
111.  justswld(mtmp,name)
112.  register struct monst *mtmp;
113.  char *name;
114.  {
115.  
116.  	mtmp->mx = u.ux;
117.  	mtmp->my = u.uy;
118.  	u.ustuck = mtmp;
119.  	pmon(mtmp);
120.  	kludge("%s swallows you!",name);
121.  	more();
122.  	seeoff(1);
123.  	u.uswallow = 1;
124.  	u.uswldtim = 0;
125.  	swallowed();
126.  }
127.  
128.  youswld(mtmp,dam,die,name)
129.  register struct monst *mtmp;
130.  register dam,die;
131.  char *name;
132.  {
133.  	if(mtmp != u.ustuck) return;
134.  	kludge("%s digests you!",name);
135.  	u.uhp -= dam;
136.  	if(u.uswldtim++ >= die){	/* a3 */
137.  		pline("It totally digests you!");
138.  		u.uhp = -1;
139.  	}
140.  	if(u.uhp < 1) done_in_by(mtmp);
141.  	/* flags.botlx = 1;		/* should we show status line ? */
142.  }
143.  
144.  #ifdef ROCKMOLE
145.  meatgold(mtmp) register struct monst *mtmp; {
146.  register struct gold *gold;
147.  register int pile;
148.  register struct obj *otmp;
149.  #ifdef KJSMODS
150.  	if(dlevel < 4) return;
151.  #endif
152.  	/* Eats gold if it is there */
153.  	while(gold = g_at(mtmp->mx, mtmp->my)){
154.  		freegold(gold);
155.  		/* Left behind a pile? */
156.  		pile = rnd(25);
157.  		if(pile < 3) mksobj_at(ROCK, mtmp->mx, mtmp->my);
158.  		newsym(mtmp->mx, mtmp->my);
159.  	}
160.  	/* Eats armor if it is there */
161.  	otmp = o_at(mtmp->mx,mtmp->my);
162.  	if((otmp) && (otmp->otyp >= PLATE_MAIL) && (otmp->otyp <= RING_MAIL)){
163.  		freeobj(otmp);
164.  		/* Left behind a pile? */
165.  		pile = rnd(25);
166.  		if(pile < 3)  mksobj_at(ROCK, mtmp->mx, mtmp->my);
167.  		newsym(mtmp->mx, mtmp->my);
168.  	}
169.  }
170.  #endif /* ROCKMOLE /**/
171.  
172.  mpickgold(mtmp) register struct monst *mtmp; {
173.  register struct gold *gold;
174.  	while(gold = g_at(mtmp->mx, mtmp->my)){
175.  		mtmp->mgold += gold->amount;
176.  		freegold(gold);
177.  		if(levl[mtmp->mx][mtmp->my].scrsym == GOLD_SYM)
178.  			newsym(mtmp->mx, mtmp->my);
179.  	}
180.  }
181.  
182.  /* Now includes giants which pick up enormous rocks.  KAA */
183.  mpickgems(mtmp) register struct monst *mtmp; {
184.  register struct obj *otmp;
185.  	for(otmp = fobj; otmp; otmp = otmp->nobj)
186.  	  if(otmp->olet ==
187.  #ifdef KAA
188.  			   (mtmp->data->mlet=='9' ? ROCK_SYM : GEM_SYM))
189.  #else
190.  			   GEM_SYM)
191.  #endif
192.  	    if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my)
193.  	      if(mtmp->data->mlet != 'u' || objects[otmp->otyp].g_val != 0){
194.  		freeobj(otmp);
195.  		mpickobj(mtmp, otmp);
196.  #ifndef KAA
197.  		if(levl[mtmp->mx][mtmp->my].scrsym == GEM_SYM)
198.  #endif
199.  			newsym(mtmp->mx, mtmp->my);	/* %% */
200.  		return;	/* pick only one object */
201.  	      }
202.  }
203.  
204.  /* return number of acceptable neighbour positions */
205.  mfndpos(mon,poss,info,flag)
206.  register struct monst *mon;
207.  coord poss[9];
208.  long info[9], flag;
209.  {
210.  	register int x,y,nx,ny,cnt = 0,ntyp;
211.  	register struct monst *mtmp;
212.  	int nowtyp;
213.  	boolean pool;
214.  
215.  	x = mon->mx;
216.  	y = mon->my;
217.  	nowtyp = levl[x][y].typ;
218.  
219.  	pool = (mon->data->mlet == ';');
220.  nexttry:	/* eels prefer the water, but if there is no water nearby,
221.  		   they will crawl over land */
222.  	if(mon->mconf) {
223.  		flag |= ALLOW_ALL;
224.  		flag &= ~NOTONL;
225.  	}
226.  	for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++)
227.  	if(nx != x || ny != y) if(isok(nx,ny))
228.  #ifdef ROCKMOLE
229.  	if(!IS_ROCK(ntyp = levl[nx][ny].typ) || (flag & ALLOW_WALL))
230.  #else
231.  	if(!IS_ROCK(ntyp = levl[nx][ny].typ))
232.  #endif
233.  	if(!(nx != x && ny != y && (nowtyp == DOOR || ntyp == DOOR)))
234.  	if((ntyp == POOL) == pool) {
235.  		info[cnt] = 0;
236.  		if(nx == u.ux && ny == u.uy){
237.  			if(!(flag & ALLOW_U)) continue;
238.  			info[cnt] = ALLOW_U;
239.  		} else if(mtmp = m_at(nx,ny)){
240.  			if(!(flag & ALLOW_M)) continue;
241.  			info[cnt] = ALLOW_M;
242.  			if(mtmp->mtame){
243.  				if(!(flag & ALLOW_TM)) continue;
244.  				info[cnt] |= ALLOW_TM;
245.  			}
246.  		}
247.  		if(sobj_at(CLOVE_OF_GARLIC, nx, ny)) {
248.  			if(flag & NOGARLIC) continue;
249.  			info[cnt] |= NOGARLIC;
250.  		}
251.  		if(sobj_at(SCR_SCARE_MONSTER, nx, ny) ||
252.  		   (!mon->mpeaceful && sengr_at("Elbereth", nx, ny))) {
253.  			if(!(flag & ALLOW_SSM)) continue;
254.  			info[cnt] |= ALLOW_SSM;
255.  		}
256.  		if(sobj_at(ENORMOUS_ROCK, nx, ny)) {
257.  			if(!(flag & ALLOW_ROCK)) continue;
258.  			info[cnt] |= ALLOW_ROCK;
259.  		}
260.  		if(!Invis && online(nx,ny)){
261.  			if(flag & NOTONL) continue;
262.  			info[cnt] |= NOTONL;
263.  		}
264.  		/* we cannot avoid traps of an unknown kind */
265.  		{ register struct trap *ttmp = t_at(nx, ny);
266.  		  register long tt;
267.  			if(ttmp) {
268.  				tt = 1L << ttmp->ttyp;
269.  				/* below if added by GAN 02/06/87 to avoid
270.  				 * traps out of range
271.  				 */
272.  				if(!(tt & ALLOW_TRAPS))  {
273.  					impossible("A monster looked at a very strange trap");
274.  					continue;
275.  				}
276.  				if(mon->mtrapseen & tt){
277.  					if(!(flag & tt)) continue;
278.  					info[cnt] |= tt;
279.  				}
280.  			}
281.  		}
282.  		poss[cnt].x = nx;
283.  		poss[cnt].y = ny;
284.  		cnt++;
285.  	}
286.  	if(!cnt && pool && nowtyp != POOL) {
287.  		pool = FALSE;
288.  		goto nexttry;
289.  	}
290.  	return(cnt);
291.  }
292.  
293.  dist(x,y) int x,y; {
294.  	return((x-u.ux)*(x-u.ux) + (y-u.uy)*(y-u.uy));
295.  }
296.  
297.  poisoned(string, pname)
298.  register char *string, *pname;
299.  {
300.  	register i, plural;
301.  
302.  	plural = (string[strlen(string) - 1] == 's')? 1 : 0;
303.  	if(Blind) {
304.  		if (plural)	pline("They were poisoned.");
305.  		else		pline("It was poisoned.");
306.  	} else	{
307.  		if (plural)	pline("The %s were poisoned!", string);
308.  		else		pline("The %s was poisoned!", string);
309.  	}
310.  
311.  	if(Poison_resistance) {
312.  		pline("The poison doesn't seem to affect you.");
313.  		return;
314.  	}
315.  	i = rn2(10);
316.  	if(i == 0) {
317.  		u.uhp = -1;
318.  		pline("I am afraid the poison was deadly ...");
319.  	} else if(i <= 5) {
320.  		losestr(rn1(3,3));
321.  	} else {
322.  		losehp(rn1(10,6), pname);
323.  	}
324.  	if(u.uhp < 1) {
325.  		killer = pname;
326.  		done("died");
327.  	}
328.  }
329.  
330.  mondead(mtmp)
331.  register struct monst *mtmp;
332.  {
333.  	relobj(mtmp,1);
334.  	unpmon(mtmp);
335.  	relmon(mtmp);
336.  	unstuck(mtmp);
337.  #ifdef KOPS
338.         if(mtmp->data->mlet == 'K' &&
339.            !strcmp(mtmp->data->mname,"Keystone Kop")) {
340.  	   /* When a Kop dies, he probably comes back. */
341.  	   switch(rnd(3)) {
342.  
343.  		case 1:	     /* returns near the stairs */
344.  			mkmon_at('K',xdnstair,ydnstair);
345.  			break;
346.  		case 2:	     /* randomly */
347.  			mkmon_at('K',0,0);
348.  			break;
349.  		default:
350.  			break;
351.  	   }
352.  	  }
353.  #endif
354.  	if(mtmp->isshk) shkdead(mtmp);
355.  	if(mtmp->isgd) gddead();
356.  #ifndef NOWORM
357.  	if(mtmp->wormno) wormdead(mtmp);
358.  #endif
359.  #ifdef HARD
360.  	if(mtmp->data->mlet == '1') wizdead(mtmp);
361.  #endif
362.  	monfree(mtmp);
363.  }
364.  
365.  /* called when monster is moved to larger structure */
366.  replmon(mtmp,mtmp2)
367.  register struct monst *mtmp, *mtmp2;
368.  {
369.  	relmon(mtmp);
370.  	monfree(mtmp);
371.  	mtmp2->nmon = fmon;
372.  	fmon = mtmp2;
373.  	if(u.ustuck == mtmp) u.ustuck = mtmp2;
374.  	if(mtmp2->isshk) replshk(mtmp,mtmp2);
375.  	if(mtmp2->isgd) replgd(mtmp,mtmp2);
376.  }
377.  
378.  relmon(mon)
379.  register struct monst *mon;
380.  {
381.  	register struct monst *mtmp;
382.  
383.  	if (fmon == 0)  panic ("relmon: no fmon available.");
384.  
385.  	if(mon == fmon) fmon = fmon->nmon;
386.  	else {
387.  		for(mtmp = fmon; mtmp->nmon != mon; mtmp = mtmp->nmon) ;
388.  		mtmp->nmon = mon->nmon;
389.  	}
390.  }
391.  
392.  /* we do not free monsters immediately, in order to have their name
393.     available shortly after their demise */
394.  struct monst *fdmon;	/* chain of dead monsters, need not to be saved */
395.  
396.  monfree(mtmp) register struct monst *mtmp; {
397.  	mtmp->nmon = fdmon;
398.  	fdmon = mtmp;
399.  }
400.  
401.  dmonsfree(){
402.  register struct monst *mtmp;
403.  	while(mtmp = fdmon){
404.  		fdmon = mtmp->nmon;
405.  		free((char *) mtmp);
406.  	}
407.  }
408.  
409.  unstuck(mtmp)
410.  register struct monst *mtmp;
411.  {
412.  	if(u.ustuck == mtmp) {
413.  		if(u.uswallow){
414.  			u.ux = mtmp->mx;
415.  			u.uy = mtmp->my;
416.  			u.uswallow = 0;
417.  			setsee();
418.  			docrt();
419.  		}
420.  		u.ustuck = 0;
421.  	}
422.  }
423.  
424.  killed(mtmp)
425.  register struct monst *mtmp;
426.  {
427.  	xkilled(mtmp, 1);
428.  }
429.  
430.  xkilled(mtmp, dest)
431.  register struct monst *mtmp;
432.  int	dest;
433.  /* Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse
434.     either; dest=3, message but no corpse */
435.  {
436.  #ifdef LINT
437.  #define	NEW_SCORING
438.  #endif
439.  	register int tmp,tmp2,nk,x,y;
440.  	register struct permonst *mdat = mtmp->data;
441.  	extern long newuexp();
442.  #ifdef RPH
443.  	int old_nlth;
444.  	char old_name[BUFSZ];
445.  #endif
446.  
447.  	if(mtmp->cham) mdat = PM_CHAMELEON;
448.  	if (dest & 1) {
449.  	    if(Blind) pline("You destroy it!");
450.  	    else {
451.  		pline("You destroy %s!",
452.  			mtmp->mtame ? amonnam(mtmp, "poor") : monnam(mtmp));
453.  	    }
454.  	}
455.  	if(u.umconf) {
456.  		if(!Blind)
457.  		{
458.  			pline("Your hands stop glowing %s.",
459.  			Hallucination ? hcolor() : "blue");
460.  		}
461.  		u.umconf = 0;
462.  	}
463.  
464.  	/* count killed monsters */
465.  #define	MAXMONNO	100
466.  	nk = 1;		      /* in case we cannot find it in mons */
467.  	tmp = mdat - mons;    /* index in mons array (if not 'd', '@', ...) */
468.  	if(tmp >= 0 && tmp < CMNUM+2) {
469.  	    extern char fut_geno[];
470.  	    u.nr_killed[tmp]++;
471.  	    if((nk = u.nr_killed[tmp]) > MAXMONNO &&
472.  #ifdef HARD
473.  # ifdef KOPS
474.  		!index("KkO&", mdat->mlet) &&
475.  # else
476.  		!index("kO&", mdat->mlet) &&
477.  # endif
478.  #endif
479.  		!index(fut_geno, mdat->mlet))
480.  		    charcat(fut_geno,  mdat->mlet);
481.  	}
482.  
483.  	/* punish bad behaviour */
484.  	if(mdat->mlet == '@') {
485.  		HTelepat = 0;
486.  		u.uluck -= 2;
487.  	}
488.  	if(mtmp->mpeaceful || mtmp->mtame) u.uluck--;
489.  	if(mdat->mlet == 'u') u.uluck -= 5;
490.  	if((int)u.uluck < LUCKMIN) u.uluck = LUCKMIN;
491.  
492.  	/* give experience points */
493.  	tmp = 1 + mdat->mlevel * mdat->mlevel;
494.  	if(mdat->ac < 3) tmp += 2*(7 - mdat->ac);
495.  	if(index(
496.  #ifdef RPH
497.  # ifdef KAA
498.  		 "AcsSDXaeRTVWU&In:P89",
499.  # else
500.  		 "AcsSDXaeRTVWU&In:P8",
501.  # endif
502.  #else
503.  # ifdef KAA
504.  		 "AcsSDXaeRTVWU&In:P9",
505.  # else
506.  		 "AcsSDXaeRTVWU&In:P",
507.  # endif
508.  #endif
509.  					 mdat->mlet)) tmp += 2*mdat->mlevel;
510.  
511.  	if(index("DeV&P",mdat->mlet)) tmp += (7*mdat->mlevel);
512.  	if(mdat->mlevel > 6) tmp += 50;
513.  	if(mdat->mlet == ';') tmp += 1000;
514.  
515.  #ifdef NEW_SCORING
516.  	/* ------- recent addition: make nr of points decrease
517.  		   when this is not the first of this kind */
518.  	{ int ul = u.ulevel;
519.  	  int ml = mdat->mlevel;
520.  
521.  	if(ul < 14)    /* points are given based on present and future level */
522.  	    for(tmp2 = 0; !tmp2 || ul + tmp2 <= ml; tmp2++)
523.  		if(u.uexp + 1 + (tmp + ((tmp2 <= 0) ? 0 : 4<<(tmp2-1)))/nk
524.  		    >= 10*pow((unsigned)(ul-1)))
525.  			if(++ul == 14) break;
526.  
527.  	tmp2 = ml - ul -1;
528.  	tmp = (tmp + ((tmp2 < 0) ? 0 : 4<<tmp2))/nk;
529.  	if(!tmp) tmp = 1;
530.  	}
531.  	/* note: ul is not necessarily the future value of u.ulevel */
532.  	/* ------- end of recent valuation change ------- */
533.  #endif /* NEW_SCORING /**/
534.  
535.  	more_experienced(tmp,0);
536.  	flags.botl = 1;
537.  	while(u.ulevel < 14 && u.uexp >= newuexp()){
538.  #ifdef RPH
539.  		/* make experience gaining simiar to d&d, whereby you */
540.  		/* can at most go up by one level at a time, extra expr */
541.  		/* possibly helping you along. Afterall, how much real */
542.  		/* experience does one get shooting a wand of death at */
543.  		/* a dragon created w/ a poymorph?? */
544.  		u.ulevel++;
545.  		if (u.uexp >= newuexp())
546.  		    u.uexp = newuexp() - 1;
547.  		pline("Welcome to experience level %u.", u.ulevel);
548.  #else
549.  		pline("Welcome to experience level %u.", ++u.ulevel);
550.  #endif
551.  		tmp = rnd(10);
552.  		if(tmp < 3) tmp = rnd(10);
553.  		u.uhpmax += tmp;
554.  		u.uhp += tmp;
555.  #ifdef SPELLS
556.  		tmp = rnd(u.ulevel/2+1) + 1;	/* M. Stephenson */
557.  		u.uenmax += tmp;
558.  		u.uen += tmp;
559.  #endif
560.  		flags.botl = 1;
561.  	}
562.  
563.  	/* dispose of monster and make cadaver */
564.  	x = mtmp->mx;	y = mtmp->my;
565.  #ifdef RPH
566.  	old_nlth = mtmp->mnamelth;
567.  	if (old_nlth > 0)  (void) strcpy (old_name, NAME(mtmp));
568.  #endif	    
569.  	mondead(mtmp);
570.  	tmp = mdat->mlet;
571.  	if(tmp == 'm') { /* he killed a minotaur, give him a wand of digging */
572.  			/* note: the dead minotaur will be on top of it! */
573.  		mksobj_at(WAN_DIGGING, x, y);
574.  		/* if(cansee(x,y)) atl(x,y,fobj->olet); */
575.  		stackobj(fobj);
576.  	} else
577.  #ifndef NOWORM
578.  	if(tmp == 'w') {
579.  		mksobj_at(WORM_TOOTH, x, y);
580.  		stackobj(fobj);
581.  	} else
582.  #endif
583.  #ifdef KJSMODS
584.  	if(tmp == 'N') { 
585.  		mksobj_at(POT_OBJECT_DETECTION, x, y);
586.  		stackobj(fobj);
587.  	} else
588.  #endif
589.  #ifdef KAA
590.  	if(tmp == '&') (void) mkobj_at(0, x, y);
591.  	else
592.  	if(stoned == FALSE && (!letter(tmp) || (!index("9&1", tmp) && !rn2(3)))) tmp = 0;
593.  	    if(dest & 2) {
594.  		newsym(x,y);
595.  		return;
596.  	    }
597.  #else
598.  	if(!letter(tmp) || (!index("mw", tmp) && !rn2(3))) tmp = 0;
599.  #endif
600.  	tmp2 = rn2(5);
601.  #ifdef KJSMODS
602.  	/* if a kobold or a giant rat does not become treasure, do
603.  	 *  not make a corpse. */
604.  # ifdef KOPS
605.  	if(mdat->mlet == 'K'
606.  	   && !strcmp(mdat->mname,"kobold") && tmp) tmp2 = 0;
607.  # endif
608.  # ifdef ROCKMOLE
609.  	if((mdat->mlet == 'r' && dlevel < 4) && tmp) tmp2 = 0;
610.  # endif
611.  #endif
612.  	if(!ACCESSIBLE(levl[x][y].typ)) {
613.  	    /* might be mimic in wall or dead eel*/
614.   	    newsym(x,y);
615.  	} else if(x != u.ux || y != u.uy) {
616.  		/* might be here after swallowed */
617.  #ifdef KAA
618.  		if(stoned) {
619.  			register int typetmp;
620.  			if(index(mlarge, tmp))	typetmp = ENORMOUS_ROCK;
621.  			else			typetmp = ROCK;
622.  			mksobj_at(typetmp, x, y);
623.  			if(cansee(x,y))
624.  			    atl(x, y, Hallucination ? rndobjsym() :
625.  				      objects[typetmp].oc_olet);
626.  		} else
627.  #endif
628.  		if(index("NTVm&w",mdat->mlet) || tmp2) {
629.  #ifndef RPH
630.  			register struct obj *obj2 = mkobj_at(tmp,x,y);
631.  #else
632.  			register struct obj *obj2;
633.  			if (letter(tmp))
634.  			    obj2 = mk_named_obj_at(tmp, x, y,
635.  						   old_name, old_nlth);
636.  # ifdef KOPS
637.  			else if (mdat->mlet == 'K')
638.  			    obj2 = mksobj_at((rn2(4) ? CLUB : WHISTLE), x, y);
639.  # endif
640.  			else
641.  			    obj2 = mkobj_at(tmp,x,y);
642.  #endif   /* RPH /**/
643.  			if(cansee(x,y))
644.  			    atl(x, y, Hallucination ? rndobjsym() : obj2->olet);
645.  			stackobj(obj2);
646.  		}
647.  	}
648.  }
649.  
650.  kludge(str,arg)
651.  register char *str,*arg;
652.  {
653.  	if(Blind) {
654.  		if(*str == '%') pline(str,"It");
655.  		else pline(str,"it");
656.  	} else pline(str,arg);
657.  }
658.  
659.  rescham()	/* force all chameleons to become normal */
660.  {
661.  	register struct monst *mtmp;
662.  
663.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
664.  		if(mtmp->cham) {
665.  			mtmp->cham = 0;
666.  			(void) newcham(mtmp, PM_CHAMELEON);
667.  		}
668.  }
669.  
670.  #ifdef DGKMOD
671.  /* Let the chameleons change again -dgk */
672.  restartcham()
673.  {
674.  	register struct monst *mtmp;
675.  
676.  	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
677.  		if (mtmp->data->mlet == ':') 
678.  			mtmp->cham = 1;
679.  }
680.  #endif
681.  
682.  newcham(mtmp,mdat)	/* make a chameleon look like a new monster */
683.  			/* returns 1 if the monster actually changed */
684.  register struct monst *mtmp;
685.  register struct permonst *mdat;
686.  {
687.  	register mhp, hpn, hpd;
688.  
689.  	if(mdat == mtmp->data) return(0);	/* still the same monster */
690.  #ifndef NOWORM
691.  	if(mtmp->wormno) wormdead(mtmp);	/* throw tail away */
692.  #endif
693.  	hpn = mtmp->mhp;
694.  	hpd = (mtmp->data->mlevel)*8;	if(!hpd) hpd = 4;
695.  	mhp = (mdat->mlevel)*8;		if(!mhp) mhp = 4;
696.  
697.  	/* new hp: same fraction of max as before */
698.  	mtmp->mhp = (hpn*mhp)/hpd;
699.  	if (mhp > hpd && mtmp->mhp < hpn) mtmp->mhp = 127;
700.  /* Not totally foolproof.  A 2HD monster with 80 HP that changes into a 6HD
701.     monster that really should have 240 and actually should have 127, the
702.     maximum possible, will wind up having 113.  */
703.  	if (!mtmp->mhp) mtmp->mhp = 1;
704.  /* Unlikely but not impossible; a 1HD creature with 1HP that changes into a
705.     0HD creature will require this statement */
706.  	mtmp->data = mdat;
707.  /* and the same for maximum hit points */
708.  	hpn = mtmp->mhpmax;
709.  	mtmp->mhpmax = (hpn*mhp)/hpd;
710.  	if (mhp > hpd && mtmp->mhpmax < hpn) mtmp->mhp = 127;
711.  	if (!mtmp->mhp) mtmp->mhp = 1;
712.  
713.  	mtmp->minvis = (mdat->mlet == 'I') ? 1 : 0;
714.  	/* only snakes and scorpions can hide under things -dgk */
715.  	/* also generated by GAN */
716.  	mtmp->mhide = (mdat->mlet == 'S' || mdat->mlet == 's') ? 1 : 0;
717.  	if (!mtmp->mhide) mtmp->mundetected = 0;
718.  #ifndef NOWORM
719.  	if(mdat->mlet == 'w' && getwn(mtmp)) initworm(mtmp);
720.  			/* perhaps we should clear mtmp->mtame here? */
721.  #endif
722.  	unpmon(mtmp);	/* necessary for 'I' and to force pmon */
723.  	pmon(mtmp);
724.  	return(1);
725.  }
726.  
727.  mnexto(mtmp)	/* Make monster mtmp next to you (if possible) */
728.  struct monst *mtmp;
729.  {
730.  	coord mm;
731.  	enexto(&mm, u.ux, u.uy);
732.  	mtmp->mx = mm.x;
733.  	mtmp->my = mm.y;
734.  	pmon(mtmp);
735.  }
736.  
737.  ishuman(mtmp) register struct monst *mtmp; {
738.  	return(mtmp->data->mlet == '@');
739.  }
740.  
741.  setmangry(mtmp) register struct monst *mtmp; {
742.  	if(!mtmp->mpeaceful) return;
743.  	if(mtmp->mtame) return;
744.  	mtmp->mpeaceful = 0;
745.  	if(ishuman(mtmp)) pline("%s gets angry!", Monnam(mtmp));
746.  }
747.  
748.  /* not one hundred procent correct: now a snake may hide under an
749.     invisible object */
750.  canseemon(mtmp)
751.  register struct monst *mtmp;
752.  {
753.  	return((!mtmp->minvis || See_invisible)
754.  		&& (!mtmp->mhide || !o_at(mtmp->mx,mtmp->my))
755.  		&& cansee(mtmp->mx, mtmp->my));
756.  }
757.  
758.  disturb(mtmp)		/* awaken monsters while in the same room.
759.  			 * return a 1 if they have been woken.
760.  			 */
761.  register struct monst *mtmp;
762.  {
763.  	/* wake up, or get out of here. */
764.  	/* ettins are hard to surprise */
765.  	/* Nymphs and Leprechauns do not easily wake up */
766.  	if(cansee(mtmp->mx,mtmp->my) &&
767.  		(!Stealth || (mtmp->data->mlet == 'e' && rn2(10))) &&
768.  		(!index("NL",mtmp->data->mlet) || !rn2(50)) &&
769.  #ifdef RPH
770.  		(Aggravate_monster || index("8d1", mtmp->data->mlet)
771.  #else
772.  		(Aggravate_monster || index("d1", mtmp->data->mlet)
773.  #endif
774.  			|| (!rn2(7) && !mtmp->mimic))) {
775.  		mtmp->msleep = 0;
776.  		return(1);
777.  	}
778.  	if(Hallucination) pmon(mtmp);
779.  	return(0);
780.  }
781.  
782.  #ifdef HARD
783.  restrap(mtmp)		/* unwatched mimics and piercers may hide again,
784.  			 * if so, a 1 is returned.
785.  			 */
786.  register struct monst *mtmp;
787.  {
788.  	if(mtmp->data->mlet == 'M' && !mtmp->mimic && !mtmp->cham
789.  	   && !mtmp->mcan && !cansee(mtmp->mx, mtmp->my)
790.  	   && !rn2(3)) {
791.  		mtmp->mimic = 1;
792.  		mtmp->mappearance = (levl[mtmp->mx][mtmp->my].typ == DOOR) ? DOOR_SYM : GOLD_SYM;
793.  		return(1);
794.  	   }
795.  
796.  	if(mtmp->data->mlet == 'p' && !mtmp->cham
797.  	   && !mtmp->mcan && !cansee(mtmp->mx, mtmp->my)
798.  	   && !rn2(3))  {
799.  
800.  		if(levl[mtmp->mx][mtmp->my].typ == ROOM)  {
801.  
802.  			maketrap(mtmp->mx, mtmp->my, PIERC);
803.  			mondead(mtmp);
804.  			return(1);
805.  		}
806.  	   }
807.  	return(0);
808.  }
809.  #endif