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