Source:Hack 1.0/hack.makemon.c

From NetHackWiki
Jump to: navigation, search

Below is the full text to hack.makemon.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.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.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
2.    
3.    #ifdef MKLEV
4.    #include	"mklev.h"
5.    extern char *fut_geno;
6.    #else MKLEV
7.    #include	"hack.h"
8.    extern char fut_geno[];
9.    #endif MKLEV
10.   
11.   
12.   extern char *index();
13.   
14.   struct monst zeromonst;
15.   
16.   /*
17.    * called with [x,y] = coordinates;
18.    *	[0,0] means anyplace
19.    *	[u.ux,u.uy] means: call mnexto (not in MKLEV)
20.    *
21.    *	In case we make an Orc or killer bee, we make an entire horde (swarm);
22.    *	note that in this case we return only one of them (the one at [x,y]).
23.    */
24.   struct monst *
25.   makemon(ptr,x,y)
26.   register struct permonst *ptr;
27.   {
28.   	register struct monst *mtmp;
29.   	register tmp, ct;
30.   	boolean anything = (!ptr);
31.   
32.   	if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0);
33.   	if(ptr){
34.   		if(index(fut_geno, ptr->mlet)) return((struct monst *) 0);
35.   	} else {
36.   		ct = CMNUM - strlen(fut_geno);
37.   		if(index(fut_geno, 'm')) ct++;  /* make only 1 minotaur */
38.   		if(index(fut_geno, '@')) ct++;
39.   		if(ct <= 0) return(0); 		  /* no more monsters! */
40.   		tmp = rn2(ct*dlevel/24 + 7);
41.   		if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12);
42.   		if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2);
43.   		for(ct = 0; ct < CMNUM; ct++){
44.   			ptr = &mons[ct];
45.   			if(index(fut_geno, ptr->mlet))
46.   				continue;
47.   			if(!tmp--) goto gotmon;
48.   		}
49.    panic("makemon?");
50.   	}
51.   gotmon:
52.   	mtmp = newmonst(ptr->pxlth);
53.   	*mtmp = zeromonst;	/* clear all entries in structure */
54.   	for(ct = 0; ct < ptr->pxlth; ct++)
55.   		((char *) &(mtmp->mextra[0]))[ct] = 0;
56.   	mtmp->nmon = fmon;
57.   	fmon = mtmp;
58.   #ifndef MKLEV
59.   	mtmp->m_id = flags.ident++;
60.   #endif MKLEV
61.   	mtmp->data = ptr;
62.   	mtmp->mxlth = ptr->pxlth;
63.   	if(ptr->mlet == 'D') mtmp->orig_hp = mtmp->mhp = 80;
64.   	else if(!ptr->mlevel) mtmp->orig_hp = mtmp->mhp = rnd(4);
65.   	else mtmp->orig_hp = mtmp->mhp = d(ptr->mlevel, 8);
66.   	mtmp->mx = x;
67.   	mtmp->my = y;
68.   	mtmp->mcansee = 1;
69.   	if(ptr->mlet == 'M')
70.   		mtmp->mimic = ']';
71.   #ifndef MKLEV
72.   	if(x == u.ux && y == u.uy)
73.   		mnexto(mtmp);
74.   	if(x == 0 && y == 0)
75.   		rloc(mtmp);
76.   #endif MKLEV
77.   	if(ptr->mlet == 's' || ptr->mlet == 'S') {
78.   		mtmp->mhide = mtmp->mundetected = 1;
79.   #ifdef MKLEV
80.   		if(mtmp->mx && mtmp->my)
81.   			mkobj_at(0, mtmp->mx, mtmp->my);
82.   #endif MKLEV
83.   	}
84.   	if(ptr->mlet == ':') {
85.   		mtmp->cham = 1;
86.   #ifndef MKLEV
87.   		(void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
88.   #endif MKLEV
89.   	}
90.   	if(ptr->mlet == 'I') mtmp->minvis = 1;
91.   	if(ptr->mlet == 'L' || ptr->mlet == 'N'
92.   #ifdef MKLEV
93.   		|| rn2(5)
94.   #endif MKLEV
95.   	) mtmp->msleep = 1;
96.   
97.   #ifndef NOWORM
98.   #ifndef MKLEV
99.   	if(ptr->mlet == 'w' && getwn(mtmp))
100.  		initworm(mtmp);
101.  #endif MKLEV
102.  #endif NOWORM
103.  
104.  	if(anything) if(ptr->mlet == 'O' || ptr->mlet == 'k') {
105.  		coord enexto();
106.  		coord mm;
107.  		register int cnt = rnd(10);
108.  		mm.x = x;
109.  		mm.y = y;
110.  		while(cnt--) {
111.  			mm = enexto(mm.x, mm.y);
112.  			(void) makemon(ptr, mm.x, mm.y);
113.  		}
114.  	}
115.  
116.  	return(mtmp);
117.  }
118.  
119.  coord
120.  enexto(xx,yy)
121.  register xchar xx,yy;
122.  {
123.  	register xchar x,y;
124.  	coord foo[15], *tfoo;
125.  	int range;
126.  
127.  	tfoo = foo;
128.  	range = 1;
129.  	do {	/* full kludge action. */
130.  		for(x = xx-range; x <= xx+range; x++)
131.  			if(goodpos(x, yy-range)) {
132.  				tfoo->x = x;
133.  				tfoo++->y = yy-range;
134.  				if(tfoo == &foo[15]) goto foofull;
135.  			}
136.  		for(x = xx-range; x <= xx+range; x++)
137.  			if(goodpos(x,yy+range)) {
138.  				tfoo->x = x;
139.  				tfoo++->y = yy+range;
140.  				if(tfoo == &foo[15]) goto foofull;
141.  			}
142.  		for(y = yy+1-range; y < yy+range; y++)
143.  			if(goodpos(xx-range,y)) {
144.  				tfoo->x = xx-range;
145.  				tfoo++->y = y;
146.  				if(tfoo == &foo[15]) goto foofull;
147.  			}
148.  		for(y = yy+1-range; y < yy+range; y++)
149.  			if(goodpos(xx+range,y)) {
150.  				tfoo->x = xx+range;
151.  				tfoo++->y = y;
152.  				if(tfoo == &foo[15]) goto foofull;
153.  			}
154.   range++;
155.  	} while(tfoo == foo);
156.  foofull:
157.  	return( foo[rn2(tfoo-foo)] );
158.  }
159.  
160.  goodpos(x,y)	/* used only in mnexto and rloc */
161.  {
162.  	return(
163.  	! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
164.  	   m_at(x,y) || levl[x][y].typ < DOOR
165.  #ifndef MKLEV
166.  	   || (x == u.ux && y == u.uy)
167.  	   || sobj_at(ENORMOUS_ROCK, x, y)
168.  #endif MKLEV
169.  	));
170.  }