Source:NetHack 1.3d/makemon.c

From NetHackWiki
Jump to: navigation, search

Below is the full text to makemon.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/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.3	87/07/14
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 enexto();
144.  		coord mm;
145.  		register int cnt = rnd(10);
146.  		mm.x = x;
147.  		mm.y = y;
148.  		while(cnt--) {
149.  			mm = enexto(mm.x, mm.y);
150.  			(void) makemon(ptr, mm.x, mm.y);
151.  		}
152.  	}
153.  #ifdef DGKMOD
154.  	m_initinv(mtmp);
155.  #endif
156.  	return(mtmp);
157.  }
158.  
159.  #ifdef DGKMOD
160.  /* Give some monsters an initial inventory to use */
161.  m_initinv(mtmp)
162.  struct monst *mtmp;
163.  {
164.  	struct obj *otmp;
165.  
166.  	switch (mtmp->data->mlet) {
167.  # ifdef KAA
168.  	case '9':
169.  		if (rn2(2)) {
170.  			otmp = mksobj(ENORMOUS_ROCK);
171.  			mpickobj(mtmp, otmp);
172.  		}
173.  # endif
174.  # ifdef KOPS
175.  	case 'K':		/* create Keystone Kops with cream pies to
176.  				 * throw. As suggested by KAA.	   [MRS]
177.  				 */
178.  		if (!rn2(4)) {
179.  			otmp = mksobj(CREAM_PIE);
180.  			otmp->quan = 2 + rnd(2);
181.  			mpickobj(mtmp, otmp);
182.  		}
183.  		break;
184.  	case 'O':
185.  # else
186.  	case 'K':
187.  # endif
188.  		if (!rn2(4)) {
189.  			otmp = mksobj(DART);
190.  			otmp->quan = 2 + rnd(12);
191.  			mpickobj(mtmp, otmp);
192.  		}
193.  		break;
194.  	case 'C':
195.  		if (rn2(2)) {
196.  			otmp = mksobj(CROSSBOW);
197.  			otmp->cursed = rn2(2);
198.  			mpickobj(mtmp, otmp);
199.  			otmp = mksobj(CROSSBOW_BOLT);
200.  			otmp->quan = 2 + rnd(12);
201.  			mpickobj(mtmp, otmp);
202.  		}
203.  		break;
204.  	default:
205.  		break;
206.  	}
207.  }
208.  #endif
209.  
210.  coord
211.  enexto(xx,yy)
212.  register xchar xx,yy;
213.  {
214.  	register xchar x,y;
215.  	coord foo[15], *tfoo;
216.  	int range;
217.  
218.  	tfoo = foo;
219.  	range = 1;
220.  	do {	/* full kludge action. */
221.  		for(x = xx-range; x <= xx+range; x++)
222.  			if(goodpos(x, yy-range)) {
223.  				tfoo->x = x;
224.  				(tfoo++)->y = yy-range;
225.  				if(tfoo == &foo[15]) goto foofull;
226.  			}
227.  		for(x = xx-range; x <= xx+range; x++)
228.  			if(goodpos(x,yy+range)) {
229.  				tfoo->x = x;
230.  				(tfoo++)->y = yy+range;
231.  				if(tfoo == &foo[15]) goto foofull;
232.  			}
233.  		for(y = yy+1-range; y < yy+range; y++)
234.  			if(goodpos(xx-range,y)) {
235.  				tfoo->x = xx-range;
236.  				(tfoo++)->y = y;
237.  				if(tfoo == &foo[15]) goto foofull;
238.  			}
239.  		for(y = yy+1-range; y < yy+range; y++)
240.  			if(goodpos(xx+range,y)) {
241.  				tfoo->x = xx+range;
242.  				(tfoo++)->y = y;
243.  				if(tfoo == &foo[15]) goto foofull;
244.  			}
245.  		range++;
246.  	} while(tfoo == foo);
247.  foofull:
248.  	return( foo[rn2(tfoo-foo)] );
249.  }
250.  
251.  goodpos(x,y)	/* used only in mnexto and rloc */
252.  {
253.  	return(
254.  	! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
255.  	   m_at(x,y) || !ACCESSIBLE(levl[x][y].typ)
256.  	   || (x == u.ux && y == u.uy)
257.  	   || sobj_at(ENORMOUS_ROCK, x, y)
258.  	));
259.  }
260.  
261.  rloc(mtmp)
262.  struct monst *mtmp;
263.  {
264.  	register tx,ty;
265.  	register char ch = mtmp->data->mlet;
266.  
267.  #ifndef NOWORM
268.  	if(ch == 'w' && mtmp->mx) return;	/* do not relocate worms */
269.  #endif
270.  	do {
271.  		tx = rn1(COLNO-3,2);
272.  		ty = rn2(ROWNO);
273.  	} while(!goodpos(tx,ty));
274.  	mtmp->mx = tx;
275.  	mtmp->my = ty;
276.  	if(u.ustuck == mtmp){
277.  		if(u.uswallow) {
278.  			u.ux = tx;
279.  			u.uy = ty;
280.  			docrt();
281.  		} else	u.ustuck = 0;
282.  	}
283.  	pmon(mtmp);
284.  }
285.  
286.  struct monst *
287.  mkmon_at(let,x,y)
288.  char let;
289.  register int x,y;
290.  {
291.  	register int ct;
292.  	register struct permonst *ptr;
293.  
294.  	for(ct = 0; ct < CMNUM; ct++) {
295.  		ptr = &mons[ct];
296.  		if(ptr->mlet == let)
297.  			return(makemon(ptr,x,y));
298.  	}
299.  	return(0);
300.  }