Wikia

Wikihack

Source:NetHack 2.2a/monmove.c

2,032pages on
this wiki
Talk0

Below is the full text to monmove.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/monmove.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: @(#)monmove.c	2.1	87/10/18
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    
4.    #include "hack.h"
5.    #include "mfndpos.h"
6.    #define	NULL	(char *) 0
7.    
8.    extern int warnlevel;	/* defined in mon.c */
9.    
10.   dochugw(mtmp) register struct monst *mtmp; {
11.   register x = mtmp->mx;
12.   register y = mtmp->my;
13.   register d = dochug(mtmp);
14.   register dd;
15.   	if(!d)		/* monster still alive */
16.   	if(Warning)
17.   	if(!mtmp->mpeaceful)
18.   	if(mtmp->data->mlevel > warnlevel)
19.   	if((dd = dist(mtmp->mx,mtmp->my)) < dist(x,y))
20.   	if(dd < 100)
21.   	if(!canseemon(mtmp))
22.   		warnlevel = mtmp->data->mlevel;
23.   	return(d);
24.   }
25.   
26.   /* returns 1 if monster died moving, 0 otherwise */
27.   dochug(mtmp)
28.   register struct monst *mtmp;
29.   {
30.   	register struct permonst *mdat;
31.   	register tmp, nearby, scared, onscary;
32.   
33.   	if(mtmp->cham && !rn2(6))
34.   		(void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
35.   	mdat = mtmp->data;
36.   	if(mdat->mlevel < 0)
37.   		panic("bad monster %c (%d)",mdat->mlet,mdat->mlevel);
38.   
39.   	/* regenerate monsters */
40.   	if((!(moves%20) || index(MREGEN, mdat->mlet)) &&
41.   	    mtmp->mhp < mtmp->mhpmax)
42.   		mtmp->mhp++;
43.   
44.   	if(mtmp->mfroz) {
45.   		if (Hallucination) pmon(mtmp);
46.   		return(0);	/* frozen monsters don't do anything */
47.   	}
48.   
49.   	if(mtmp->msleep)	/* there is a chance we will wake it */
50.   		if(!disturb(mtmp)) return(0);
51.   
52.   	/* not frozen or sleeping: wipe out texts written in the dust */
53.   	wipe_engr_at(mtmp->mx, mtmp->my, 1);
54.   
55.   	/* confused monsters get unconfused with small probability */
56.   	if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0;
57.   
58.   	/* some monsters teleport */
59.   	if(mtmp->mflee && index("tNL", mdat->mlet) && !rn2(40)){
60.   		rloc(mtmp);
61.   		return(0);
62.   	}
63.   	if(mdat->mmove < rnd(6)) return(0);
64.   
65.   	/* fleeing monsters might regain courage */
66.   	if(mtmp->mflee && !mtmp->mfleetim
67.   	    && mtmp->mhp == mtmp->mhpmax && !rn2(25))
68.   		mtmp->mflee = 0;
69.   
70.   	nearby = (dist(mtmp->mx, mtmp->my) < 3);
71.   	onscary = (sengr_at("Elbereth", u.ux, u.uy) ||
72.   			sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy));
73.   	scared = (nearby && onscary && !mtmp->mtame && mtmp->mcansee)
74.   		 && (mdat->mlet != '1');  /* RPH: the wiz is never scared */
75.   	if(scared && !mtmp->mflee) {
76.   		mtmp->mflee = 1;
77.   		mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
78.   	}
79.   
80.   	if(!nearby ||
81.   		mtmp->mflee || scared ||
82.   		mtmp->mconf ||
83.   		(mtmp->minvis && !rn2(3)) ||
84.   #ifndef KOPS
85.   		(index("BIuy", mdat->mlet) && !rn2(4)) ||
86.   #else
87.   		(index("KBIuy", mdat->mlet) && !rn2(4)) ||
88.   #endif
89.   		(mdat->mlet == 'L' && !u.ugold && (mtmp->mgold || rn2(2))) ||
90.   		(!mtmp->mcansee && !rn2(4)) ||
91.   		mtmp->mpeaceful
92.   	   ) {
93.   		tmp = m_move(mtmp,0);	/* 2: monster died moving */
94.   		if(tmp == 2 || (tmp && mdat->mmove <= 12))
95.   			return(tmp == 2);
96.   
97.   		if(Hallucination && tmp==0) pmon(mtmp);
98.   /* If 0, this means the monster didn't move.  During hallucination, its
99.      appearance should still change. */
100.  
101.  #ifdef HARD
102.  		/* Without this line, fast monsters don't hit you when they've
103.  		 * caught up to you. -dgk
104.  		 */
105.  		nearby = (dist(mtmp->mx, mtmp->my) < 3);
106.  		scared = (nearby && onscary);
107.  		if(scared && !mtmp->mflee) {
108.  			mtmp->mflee = 1;
109.  			mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
110.  		}
111.  #endif
112.  	}
113.  #ifdef HARD	/* Demonic Blackmail!!! */
114.  	if(mdat->mlet == '&' && mtmp->mpeaceful && !mtmp->mtame)
115.  		if(demon_talk(mtmp))
116.  			 return(1);	/* you paid it off */
117.  #endif
118.  	if(!index("Ea", mdat->mlet) && nearby &&
119.  	 !mtmp->mpeaceful && u.uhp > 0 && !scared) {
120.  		if(mhitu(mtmp))
121.  			return(1);	/* monster died (e.g. 'y' or 'F') */
122.  	}
123.  	/* extra movement for fast monsters */
124.  	if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp,1);
125.  	return(tmp == 2);
126.  }
127.  
128.  m_move(mtmp,after)
129.  register struct monst *mtmp;
130.  {
131.  #ifndef REGBUG
132.  	register
133.  #endif
134.  		 struct monst *mtmp2;
135.  #ifndef REGBUG
136.  	register
137.  #endif
138.  		int nx,ny,omx,omy,appr,nearer,cnt,i,j;
139.  	xchar gx,gy,nix,niy,chcnt;
140.  	schar chi;
141.  	boolean likegold, likegems, likeobjs;
142.  #ifdef KAA
143.  	boolean likerock;
144.  #endif
145.  	char msym = mtmp->data->mlet;
146.  	schar mmoved = 0;	/* not strictly nec.: chi >= 0 will do */
147.  	coord poss[9];
148.  	long info[9];
149.  
150.  	if(mtmp->mfroz || mtmp->msleep)
151.  		return(0);
152.  	if(mtmp->mtrapped) {
153.  		i = mintrap(mtmp);
154.  		if(i == 2) return(2);	/* he died */
155.  		if(i == 1) return(0);	/* still in trap, so didnt move */
156.  	}
157.  	if(mtmp->mhide && o_at(mtmp->mx,mtmp->my) && rn2(10))
158.  		return(0);		/* do not leave hiding place */
159.  
160.  #ifndef NOWORM
161.  	if(mtmp->wormno)
162.  		goto not_special;
163.  #endif
164.  
165.  	/* my dog gets a special treatment */
166.  	if(mtmp->mtame) {
167.  		return( dog_move(mtmp, after) );
168.  	}
169.  
170.  	/* likewise for shopkeeper */
171.  	if(mtmp->isshk) {
172.  		mmoved = shk_move(mtmp);
173.  		if(mmoved >= 0)
174.  			goto postmov;
175.  		mmoved = 0;		/* follow player outside shop */
176.  	}
177.  
178.  	/* and for the guard */
179.  	if(mtmp->isgd) {
180.  		mmoved = gd_move();
181.  		goto postmov;
182.  	}
183.  
184.  /* teleport if that lies in our nature ('t') or when badly wounded ('1') */
185.  	if((msym == 't' && !rn2(5))
186.  	|| (msym == '1' && (mtmp->mhp < 7 || (!xdnstair && !rn2(5))
187.  		|| levl[u.ux][u.uy].typ == STAIRS))) {
188.  		if(mtmp->mhp < 7 || (msym == 't' && rn2(2)))
189.  			rloc(mtmp);
190.  		else
191.  			mnexto(mtmp);
192.  		mmoved = 1;
193.  		goto postmov;
194.  	}
195.  
196.  	/* spit fire ('D') or use a wand ('1') when appropriate */
197.  #ifdef DGKMOD
198.  	/* Add arrow and bolt throwing monsters */
199.  	if (index(
200.  # ifdef KAA
201.  #  ifdef KOPS
202.  		"D1OKC9",
203.  #  else
204.  		"D1KC9",
205.  #  endif
206.  # else
207.  #  ifdef KOPS
208.  		"D1OKC",
209.  #  else
210.  		"D1KC",
211.  #  endif
212.  # endif
213.  			  msym))	
214.  
215.  		if (!inrange(mtmp))	/* inrange returns 1 if OK for mon */
216.  			return(0);	/* to move after it zaps or throws */
217.  #else
218.  	if(index("D1", msym))
219.  		inrange(mtmp);
220.  #endif
221.  
222.  	if(msym == 'U' && !mtmp->mcan && canseemon(mtmp) &&
223.  	    mtmp->mcansee && rn2(5)) {
224.  		if(!Confusion)
225.  			pline("%s's gaze has confused you!", Monnam(mtmp));
226.  		else
227.  			pline("You are getting more and more confused.");
228.  		if(rn2(3)) mtmp->mcan = 1;
229.  		HConfusion += d(3,4);		/* timeout */
230.  	}
231.  #ifdef RPH
232.  	if (msym == '8' && canseemon(mtmp)) {
233.  	    if (mtmp->mcan)
234.  	        pline ("You notice that %s isn't all that ugly.",monnam(mtmp));
235.  	    else if (rn2(3)) 
236.  		pline ("You see the ugly back of %s.", monnam(mtmp));
237.    	    else {
238.  	        pline ("You look upon %s.", monnam(mtmp));
239.  		pline ("You turn to stone.");
240.  		done_in_by(mtmp);
241.  	    }
242.  	}
243.  #endif
244.  not_special:
245.  	if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1);
246.  	appr = 1;
247.  	if(mtmp->mflee) appr = -1;
248.  	if(mtmp->mconf || Invis ||  !mtmp->mcansee ||
249.  		(index("BIy", msym) && !rn2(3)))
250.  		appr = 0;
251.  	omx = mtmp->mx;
252.  	omy = mtmp->my;
253.  	gx = u.ux;
254.  	gy = u.uy;
255.  	if(msym == 'L' && appr == 1 && mtmp->mgold > u.ugold)
256.  		appr = -1;
257.  
258.  	/* random criterion for 'smell' or track finding ability
259.  	   should use mtmp->msmell or sth
260.  	 */
261.  	if(msym == '@' ||
262.  #ifdef RPH
263.  	  uwep && !strcmp(ONAME(uwep), "Excalibur") ||
264.  #endif
265.  	  ('a' <= msym && msym <= 'z')) {
266.  	extern coord *gettrack();
267.  	register coord *cp;
268.  	schar mroom;
269.  		mroom = inroom(omx,omy);
270.  		if(mroom < 0 || mroom != inroom(u.ux,u.uy)){
271.  		    cp = gettrack(omx,omy);
272.  		    if(cp){
273.  			gx = cp->x;
274.  			gy = cp->y;
275.  		    }
276.  		}
277.  	}
278.  
279.  	/* look for gold or jewels nearby */
280.  #ifdef ROCKMOLE
281.  	likegold = (index("LODr", msym) != NULL);
282.  	likegems = (index("ODu", msym) != NULL);
283.  # ifdef KJSMODS
284.  	likeobjs = (mtmp->mhide || (msym == 'r' && dlevel > 3));
285.  # else
286.  	likeobjs = (mtmp->mhide || msym == 'r');
287.  # endif
288.  #else
289.  	likegold = (index("LOD", msym) != NULL);
290.  	likegems = (index("ODu", msym) != NULL);
291.  	likeobjs = mtmp->mhide;
292.  #endif
293.  #ifdef KAA
294.  	likerock = (msym == '9');
295.  #endif
296.  #define	SRCHRADIUS	25
297.  	{ xchar mind = SRCHRADIUS;		/* not too far away */
298.  	  register int dd;
299.  	  if(likegold){
300.  		register struct gold *gold;
301.  		for(gold = fgold; gold; gold = gold->ngold)
302.  		  if((dd = DIST(omx,omy,gold->gx,gold->gy)) < mind){
303.  		    mind = dd;
304.  		    gx = gold->gx;
305.  		    gy = gold->gy;
306.  		}
307.  	  }
308.  	  if(likegems || likeobjs
309.  #ifdef KAA
310.  				  || likerock
311.  #endif
312.  	    )  {
313.  		register struct obj *otmp;
314.  		for(otmp = fobj; otmp; otmp = otmp->nobj)
315.  		if(likeobjs
316.  		   || (likegems && otmp->olet == GEM_SYM)
317.  #ifdef KAA
318.  		   || (likerock && otmp->olet == ROCK_SYM)
319.  #endif
320.  			)  {
321.  			if(msym != 'u' || objects[otmp->otyp].g_val != 0)
322.  			    if((dd = DIST(omx,omy,otmp->ox,otmp->oy)) < mind){
323.  				mind = dd;
324.  				gx = otmp->ox;
325.  				gy = otmp->oy;
326.  			    }
327.  			}
328.  	    }
329.  	  if(mind < SRCHRADIUS && appr == -1) {
330.  		if(dist(omx,omy) < 10) {
331.  		    gx = u.ux;
332.  		    gy = u.uy;
333.  		} else
334.  		    appr = 1;
335.  	  }
336.  	}
337.  	nix = omx;
338.  	niy = omy;
339.  	cnt = mfndpos(mtmp,poss,info,
340.  		msym == 'u' ? NOTONL :
341.  #ifdef ROCKMOLE
342.  # ifdef KJSMODS
343.  		(msym == 'r' && dlevel > 3) ? ALLOW_WALL :
344.  # else
345.  		msym == 'r' ? ALLOW_WALL :
346.  # endif
347.  #endif
348.  		(msym == '@' || msym == '1') ? (ALLOW_SSM | ALLOW_TRAPS) :
349.  		index(UNDEAD, msym) ? NOGARLIC :
350.  #ifdef KAA
351.  		    (msym == '9') ? (ALLOW_ROCK | ALLOW_TRAPS) : ALLOW_TRAPS);
352.  #else
353.  		     ALLOW_TRAPS);
354.  #endif
355.  	chcnt = 0;
356.  	chi = -1;
357.  	for(i=0; i<cnt; i++) {
358.  		nx = poss[i].x;
359.  		ny = poss[i].y;
360.  		for(j=0; j<MTSZ && j<cnt-1; j++)
361.  			if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
362.  				if(rn2(4*(cnt-j))) goto nxti;
363.  #ifdef STUPID
364.  		/* some stupid compilers think that this is too complicated */
365.  		{ int d1 = DIST(nx,ny,gx,gy);
366.  		  int d2 = DIST(nix,niy,gx,gy);
367.  		  nearer = (d1 < d2);
368.  		}
369.  #else
370.  		nearer = (DIST(nx,ny,gx,gy) < DIST(nix,niy,gx,gy));
371.  #endif
372.  		if((appr == 1 && nearer) || (appr == -1 && !nearer) ||
373.  			!mmoved ||
374.  			(!appr && !rn2(++chcnt))){
375.  			nix = nx;
376.  			niy = ny;
377.  			chi = i;
378.  			mmoved = 1;
379.  		}
380.  	nxti:	;
381.  	}
382.  	if(mmoved){
383.  		if(info[chi] & ALLOW_M){
384.  			mtmp2 = m_at(nix,niy);
385.  			if(hitmm(mtmp,mtmp2) == 1 && rn2(4) &&
386.  			  hitmm(mtmp2,mtmp) == 2) return(2);
387.  			return(0);
388.  		}
389.  		if(info[chi] & ALLOW_U){
390.  		  (void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd)+1);
391.  		  return(0);
392.  		}
393.  		mtmp->mx = nix;
394.  		mtmp->my = niy;
395.  		for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];
396.  		mtmp->mtrack[0].x = omx;
397.  		mtmp->mtrack[0].y = omy;
398.  #ifndef NOWORM
399.  		if(mtmp->wormno) worm_move(mtmp);
400.  #endif
401.  	} else {
402.  		if(msym == 'u' && rn2(2)){
403.  			rloc(mtmp);
404.  			return(0);
405.  		}
406.  #ifndef NOWORM
407.  		if(mtmp->wormno) worm_nomove(mtmp);
408.  #endif
409.  	}
410.  postmov:
411.  	if(mmoved == 1) {
412.  		if(mintrap(mtmp) == 2)	/* he died */
413.  			return(2);
414.  #ifdef ROCKMOLE
415.  	       /* Maybe a rock mole just ate something? */
416.  	       if(msym == 'r'
417.  # ifdef KJSMODS
418.  		  && dlevel > 3
419.  #endif
420.  		  && IS_ROCK(levl[mtmp->mx][mtmp->my].typ) &&
421.  		  levl[mtmp->mx][mtmp->my].typ != POOL){
422.  		   register int pile = rnd(25);
423.  		   /* Just ate something. */
424.  		   if(levl[mtmp->mx][mtmp->my].typ == 0)
425.  		     levl[mtmp->mx][mtmp->my].typ = CORR;
426.  		   else if(IS_WALL(levl[mtmp->mx][mtmp->my].typ))
427.  		     levl[mtmp->mx][mtmp->my].typ = DOOR;
428.  		   mnewsym(mtmp->mx,mtmp->my);
429.  		   /* Left behind a pile? */
430.  		   if(pile < 5) {
431.  		       if(pile == 1)
432.  			mksobj_at(ENORMOUS_ROCK, mtmp->mx, mtmp->my);
433.  		      else
434.  			mksobj_at(ROCK, mtmp->mx, mtmp->my);
435.  		   }
436.  		  if(cansee(mtmp->mx, mtmp->my))
437.  		    if(fobj)	atl(mtmp->mx,mtmp->my,fobj->olet);
438.  	       }
439.  	       /* Maybe a rock mole just ate some gold or armor? */
440.  	       if(msym == 'r') meatgold(mtmp);
441.  #endif /* ROCKMOLE /**/
442.  		if(likegold) mpickgold(mtmp);
443.  #ifdef KAA
444.  		if(likerock || likegems) mpickgems(mtmp);
445.  #else
446.  		if(likegems) mpickgems(mtmp);
447.  #endif
448.  		if(mtmp->mhide) mtmp->mundetected = 1;
449.  	}
450.  	pmon(mtmp);
451.  	return(mmoved);
452.  }
453.  

Around Wikia's network

Random Wiki