Source:NetHack 2.2a/makemon.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to makemon.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/makemon.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: @(#)makemon.c	2.2	87/11/29
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    
4.    #include	"hack.h"
5.    extern char fut_geno[];
6.    extern char *index();
7.    extern struct obj *mkobj_at(), *mksobj(), *mkobj();
8.    struct monst zeromonst;
9.    extern boolean in_mklev;
10.   
11.   #ifdef HARD		/* used in hell for bigger, badder demons! */
12.   
13.   struct permonst d_lord   = { "demon lord",	'&',12,13,-5,50,1,5,0 },
14.   		d_prince = { "demon prince",	'&',14,14,-6,70,1,6,0 };
15.   #endif
16.   #ifdef KJSMODS
17.   # ifdef KOPS
18.   struct permonst kobold = { "kobold",'K',1,6,7,0,1,4,0 };
19.   # endif
20.   # ifdef ROCKMOLE
21.   struct permonst giant_rat = { "giant rat",'r',0,12,7,0,1,3,0 };
22.   # endif
23.   #endif /* KJSMODS /**/
24.   
25.   /*
26.    * called with [x,y] = coordinates;
27.    *	[0,0] means anyplace
28.    *	[u.ux,u.uy] means: call mnexto (if !in_mklev)
29.    *
30.    *	In case we make an Orc or killer bee, we make an entire horde
31.    *	(swarm); note that in this case we return only one of them
32.    *	(the one at [x,y]).
33.    */
34.   struct monst *
35.   makemon(ptr,x,y)
36.   register struct permonst *ptr;
37.   {
38.   	register struct monst *mtmp;
39.   	register nleft, deep, ct;
40.   	boolean anything = (!ptr);
41.   	int zlevel = dlevel;
42.   #ifdef BVH
43.   	if(has_amulet()) zlevel = 40;
44.   #endif
45.   	/* if a monster already exists at the position, return */
46.   	if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0);
47.   	if(ptr){
48.   		/* if you are to make a specific monster and it has 
49.   		   already been genocided, return */
50.   		if(index(fut_geno, ptr->mlet)) return((struct monst *) 0);
51.   	} else {
52.   		/* make a random (common) monster. */
53.   		nleft = CMNUM - strlen(fut_geno);
54.   		if(index(fut_geno, 'm')) nleft++;  /* only 1 minotaur */
55.   		if(index(fut_geno, '@')) nleft++;
56.   		if(nleft <= 0)
57.   		    return((struct monst *) 0);	/* no more monsters! */
58.   
59.   		/* determine the strongest monster to make. */
60.   #ifdef ROCKMOLE
61.   		deep = rn2(nleft*zlevel/24 + 6);
62.   #else
63.   		deep = rn2(nleft*zlevel/24 + 7);
64.   #endif
65.   		if(deep < zlevel - 4) deep = rn2(nleft*zlevel/24 + 12);
66.   		/* if deep is greater than the number of monsters left 
67.   		   to create, set deep to a random number between half 
68.   		   the number left and the number left. */
69.   		if(deep >= nleft) deep = rn1(nleft - nleft/2, nleft/2);
70.   
71.   		for(ct = 0 ; ct < CMNUM ; ct++){
72.   			ptr = &mons[ct];
73.   			if(index(fut_geno, ptr->mlet)) continue;
74.   #ifdef KOPS
75.   			if(ptr->mlet == 'K') {
76.   # ifdef KJSMODS
77.   				/* since this is a random monster, make 
78.   				   a Kobold instead of a Kop. */
79.   				ptr = &kobold;
80.   # else
81.   				deep--;
82.   # endif
83.   				continue;
84.   			}
85.   #endif /* KOPS /**/
86.   			if(deep-- <= 0) goto gotmon;
87.   		}
88.   		/* this can happen if you are deep in the dungeon and 
89.   		   mostly weak monsters have been genocided. */
90.   		return((struct monst *) 0);
91.   	}
92.   gotmon:
93.   #if defined(KJSMODS) && defined(ROCKMOLE)
94.   	/* make a giant rat */
95.   	if((zlevel < 4 && ptr->mlet == 'r')
96.   	   || (zlevel == 1 && (ptr->mlet == 'h' || ptr->mlet == 'i'))
97.   	   || (zlevel == 2 && (ptr->mlet == 'o' || ptr->mlet == 'y'))
98.   	) ptr = &giant_rat;
99.   #endif
100.  	mtmp = newmonst(ptr->pxlth);
101.  	*mtmp = zeromonst;	/* clear all entries in structure */
102.  	for(ct = 0; ct < ptr->pxlth; ct++)
103.  		((char *) &(mtmp->mextra[0]))[ct] = 0;
104.  	mtmp->nmon = fmon;
105.  	fmon = mtmp;
106.  	mtmp->m_id = flags.ident++;
107.  	mtmp->data = ptr;
108.  	mtmp->mxlth = ptr->pxlth;
109.  	if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80;
110.  	else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4);
111.  	else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
112.  	mtmp->mx = x;
113.  	mtmp->my = y;
114.  	mtmp->mcansee = 1;
115.  	if(ptr->mlet == 'M'){
116.  		mtmp->mimic = 1;
117.  		mtmp->mappearance = ']';
118.  	}
119.  	if(!in_mklev) {
120.  		if(x == u.ux && y == u.uy && ptr->mlet != ' ')
121.  			mnexto(mtmp);
122.  		if(x == 0 && y == 0)
123.  			rloc(mtmp);
124.  	}
125.  	if(ptr->mlet == 's' || ptr->mlet == 'S') {
126.  		mtmp->mhide = mtmp->mundetected = 1;
127.  		if(in_mklev)
128.  		if(mtmp->mx && mtmp->my)
129.  			(void) mkobj_at(0, mtmp->mx, mtmp->my);
130.  	}
131.  	if(ptr->mlet == ':') {
132.  #ifdef DGKMOD
133.  		/* If you're protected with a ring, don't create
134.  		 * any shape-changing chameleons -dgk
135.  		 */
136.  		if (Protection_from_shape_changers)
137.  			mtmp->cham = 0;
138.  		else {
139.  			mtmp->cham = 1;
140.  			(void) newcham(mtmp,
141.  				&mons[zlevel+14+rn2(CMNUM-14-zlevel)]);
142.  		}
143.  #else
144.  		mtmp->cham = 1;
145.  		(void) newcham(mtmp, &mons[zlevel+14+rn2(CMNUM-14-zlevel)]);
146.  #endif
147.  	}
148.  	if(ptr->mlet == 'I' || ptr->mlet == ';')
149.  		mtmp->minvis = 1;
150.  	if(ptr->mlet == 'L' || ptr->mlet == 'N'
151.  	    || (in_mklev && index("&w;", ptr->mlet) && rn2(5))
152.  	) mtmp->msleep = 1;
153.  #ifdef HARD
154.  	if(ptr->mlet == '&' && (Inhell || u.udemigod)) {
155.  
156.  		if(!rn2(3 + !Inhell + !u.udemigod)) {
157.  		    if (rn2(3 + Inhell)) mtmp->data = &d_lord;
158.  		    else  {
159.  			mtmp->data = &d_prince;
160.  			mtmp->mpeaceful = 1;
161.  			mtmp->minvis = 1;
162.  		    }
163.  		}
164.  #ifdef RPH
165.  		if(uwep)
166.  		    if(!strcmp(ONAME(uwep), "Excalibur"))
167.  			mtmp->mpeaceful = mtmp->mtame = 0;
168.  #endif
169.  	}
170.  #endif /* HARD /**/
171.  #ifndef NOWORM
172.  	if(ptr->mlet == 'w' && getwn(mtmp))  initworm(mtmp);
173.  #endif
174.  
175.  	if(anything)
176.  	    if(ptr->mlet == 'O' || ptr->mlet == 'k'
177.  #ifdef SAC
178.  	       || ptr->mlet == '3'
179.  #endif /* SAC /**/
180.  				  ) {
181.  
182.  		coord mm;
183.  		register int cnt = rnd(10);
184.  		mm.x = x;
185.  		mm.y = y;
186.  		while(cnt--) {
187.  			enexto(&mm, mm.x, mm.y);
188.  			(void) makemon(ptr, mm.x, mm.y);
189.  		}
190.  	}
191.  #ifdef DGKMOD
192.  	m_initinv(mtmp);
193.  #endif
194.  	return(mtmp);
195.  }
196.  
197.  #ifdef DGKMOD
198.  /* Give some monsters an initial inventory to use */
199.  m_initinv(mtmp)
200.  struct monst *mtmp;
201.  {
202.  	struct obj *otmp;
203.  
204.  	switch (mtmp->data->mlet) {
205.  # ifdef KAA
206.  	case '9':
207.  		if (rn2(2)) {
208.  			otmp = mksobj(ENORMOUS_ROCK);
209.  			mpickobj(mtmp, otmp);
210.  		}
211.  # endif
212.  # ifdef SAC
213.  	case '3':			/* Outfit the troops */
214.  		if (!rn2(4)) {
215.  			otmp = mksobj(HELMET);
216.  			mpickobj(mtmp, otmp); }
217.  		if (!rn2(4)) {
218.  			otmp = mksobj(CHAIN_MAIL);
219.  			mpickobj(mtmp, otmp); }
220.  		if (!rn2(3)) {
221.  			otmp = mksobj(DAGGER);
222.  			mpickobj(mtmp, otmp); }
223.  		if (!rn2(6)) {
224.  			otmp = mksobj(SPEAR);
225.  			mpickobj(mtmp, otmp); }
226.  		if (!rn2(2)) {
227.  			otmp = mksobj(TIN);
228.  			mpickobj(mtmp, otmp); }
229.  # endif /* SAC /**/
230.  # ifdef KOPS
231.  	case 'K':		/* create Keystone Kops with cream pies to
232.  				 * throw. As suggested by KAA.	   [MRS]
233.  				 */
234.  		if (!rn2(4)
235.  #  ifdef KJSMODS
236.    		    && !strcmp(mtmp->data->mname, "Keystone Kop")
237.  #  endif
238.  								) {
239.  			otmp = mksobj(CREAM_PIE);
240.  			otmp->quan = 2 + rnd(2);
241.  			otmp->owt = weight(otmp);
242.  			mpickobj(mtmp, otmp);
243.  		}
244.  		break;
245.  	case 'O':
246.  # else
247.  	case 'K':
248.  # endif
249.  		if (!rn2(4)) {
250.  			otmp = mksobj(DART);
251.  			otmp->quan = 2 + rnd(12);
252.  			otmp->owt = weight(otmp);
253.  			mpickobj(mtmp, otmp);
254.  		}
255.  		break;
256.  
257.  	case 'C':
258.  		if (rn2(2)) {
259.  			otmp = mksobj(CROSSBOW);
260.  			otmp->cursed = rn2(2);
261.  			mpickobj(mtmp, otmp);
262.  			otmp = mksobj(CROSSBOW_BOLT);
263.  			otmp->quan = 2 + rnd(12);
264.  			otmp->owt = weight(otmp);
265.  			mpickobj(mtmp, otmp);
266.  		}
267.  		break;
268.  	default:
269.  		break;
270.  	}
271.  }
272.  #endif
273.  
274.  enexto(cc, xx,yy)
275.  coord	*cc;
276.  register xchar xx,yy;
277.  {
278.  	register xchar x,y;
279.  	coord foo[15], *tfoo;
280.  	int range, i;
281.  
282.  	tfoo = foo;
283.  	range = 1;
284.  	do {	/* full kludge action. */
285.  		for(x = xx-range; x <= xx+range; x++)
286.  			if(goodpos(x, yy-range)) {
287.  				tfoo->x = x;
288.  				(tfoo++)->y = yy-range;
289.  				if(tfoo == &foo[15]) goto foofull;
290.  			}
291.  		for(x = xx-range; x <= xx+range; x++)
292.  			if(goodpos(x,yy+range)) {
293.  				tfoo->x = x;
294.  				(tfoo++)->y = yy+range;
295.  				if(tfoo == &foo[15]) goto foofull;
296.  			}
297.  		for(y = yy+1-range; y < yy+range; y++)
298.  			if(goodpos(xx-range,y)) {
299.  				tfoo->x = xx-range;
300.  				(tfoo++)->y = y;
301.  				if(tfoo == &foo[15]) goto foofull;
302.  			}
303.  		for(y = yy+1-range; y < yy+range; y++)
304.  			if(goodpos(xx+range,y)) {
305.  				tfoo->x = xx+range;
306.  				(tfoo++)->y = y;
307.  				if(tfoo == &foo[15]) goto foofull;
308.  			}
309.  		range++;
310.  	} while(tfoo == foo);
311.  foofull:
312.  	i = rn2(tfoo - foo);
313.  	cc->x = foo[i].x;
314.  	cc->y = foo[i].y;
315.  	return(0);
316.  }
317.  
318.  goodpos(x,y)	/* used only in mnexto and rloc */
319.  {
320.  	return(
321.  	! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
322.  	   m_at(x,y) || !ACCESSIBLE(levl[x][y].typ)
323.  	   || (x == u.ux && y == u.uy)
324.  	   || sobj_at(ENORMOUS_ROCK, x, y)
325.  	));
326.  }
327.  
328.  rloc(mtmp)
329.  struct monst *mtmp;
330.  {
331.  	register tx,ty;
332.  	register char ch = mtmp->data->mlet;
333.  
334.  #ifndef NOWORM
335.  	if(ch == 'w' && mtmp->mx) return;	/* do not relocate worms */
336.  #endif
337.  	do {
338.  		tx = rn1(COLNO-3,2);
339.  		ty = rn2(ROWNO);
340.  	} while(!goodpos(tx,ty));
341.  	mtmp->mx = tx;
342.  	mtmp->my = ty;
343.  	if(u.ustuck == mtmp){
344.  		if(u.uswallow) {
345.  			u.ux = tx;
346.  			u.uy = ty;
347.  			docrt();
348.  		} else	u.ustuck = 0;
349.  	}
350.  	pmon(mtmp);
351.  }
352.  
353.  struct monst *
354.  mkmon_at(let,x,y)
355.  char let;
356.  register int x,y;
357.  {
358.  	register int ct;
359.  	register struct permonst *ptr;
360.  
361.  	for(ct = 0; ct < CMNUM; ct++) {
362.  		ptr = &mons[ct];
363.  		if(ptr->mlet == let)
364.  			return(makemon(ptr,x,y));
365.  	}
366.  	return((struct monst *)0);
367.  }