Wikihack
Register
Advertisement

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