hack.makemon.c revision 1.2 1 1.2 mycroft /*
2 1.2 mycroft * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
3 1.2 mycroft */
4 1.2 mycroft
5 1.2 mycroft #ifndef lint
6 1.2 mycroft static char rcsid[] = "$Id: hack.makemon.c,v 1.2 1993/08/02 17:17:19 mycroft Exp $";
7 1.2 mycroft #endif /* not lint */
8 1.1 cgd
9 1.1 cgd #include "hack.h"
10 1.1 cgd extern char fut_geno[];
11 1.1 cgd extern char *index();
12 1.1 cgd extern struct obj *mkobj_at();
13 1.1 cgd struct monst zeromonst;
14 1.1 cgd
15 1.1 cgd /*
16 1.1 cgd * called with [x,y] = coordinates;
17 1.1 cgd * [0,0] means anyplace
18 1.1 cgd * [u.ux,u.uy] means: call mnexto (if !in_mklev)
19 1.1 cgd *
20 1.1 cgd * In case we make an Orc or killer bee, we make an entire horde (swarm);
21 1.1 cgd * note that in this case we return only one of them (the one at [x,y]).
22 1.1 cgd */
23 1.1 cgd struct monst *
24 1.1 cgd makemon(ptr,x,y)
25 1.1 cgd register struct permonst *ptr;
26 1.1 cgd {
27 1.1 cgd register struct monst *mtmp;
28 1.1 cgd register tmp, ct;
29 1.1 cgd boolean anything = (!ptr);
30 1.1 cgd extern boolean in_mklev;
31 1.1 cgd
32 1.1 cgd if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0);
33 1.1 cgd if(ptr){
34 1.1 cgd if(index(fut_geno, ptr->mlet)) return((struct monst *) 0);
35 1.1 cgd } else {
36 1.1 cgd ct = CMNUM - strlen(fut_geno);
37 1.1 cgd if(index(fut_geno, 'm')) ct++; /* make only 1 minotaur */
38 1.1 cgd if(index(fut_geno, '@')) ct++;
39 1.1 cgd if(ct <= 0) return(0); /* no more monsters! */
40 1.1 cgd tmp = rn2(ct*dlevel/24 + 7);
41 1.1 cgd if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12);
42 1.1 cgd if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2);
43 1.1 cgd for(ct = 0; ct < CMNUM; ct++){
44 1.1 cgd ptr = &mons[ct];
45 1.1 cgd if(index(fut_geno, ptr->mlet))
46 1.1 cgd continue;
47 1.1 cgd if(!tmp--) goto gotmon;
48 1.1 cgd }
49 1.1 cgd panic("makemon?");
50 1.1 cgd }
51 1.1 cgd gotmon:
52 1.1 cgd mtmp = newmonst(ptr->pxlth);
53 1.1 cgd *mtmp = zeromonst; /* clear all entries in structure */
54 1.1 cgd for(ct = 0; ct < ptr->pxlth; ct++)
55 1.1 cgd ((char *) &(mtmp->mextra[0]))[ct] = 0;
56 1.1 cgd mtmp->nmon = fmon;
57 1.1 cgd fmon = mtmp;
58 1.1 cgd mtmp->m_id = flags.ident++;
59 1.1 cgd mtmp->data = ptr;
60 1.1 cgd mtmp->mxlth = ptr->pxlth;
61 1.1 cgd if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80;
62 1.1 cgd else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4);
63 1.1 cgd else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
64 1.1 cgd mtmp->mx = x;
65 1.1 cgd mtmp->my = y;
66 1.1 cgd mtmp->mcansee = 1;
67 1.1 cgd if(ptr->mlet == 'M'){
68 1.1 cgd mtmp->mimic = 1;
69 1.1 cgd mtmp->mappearance = ']';
70 1.1 cgd }
71 1.1 cgd if(!in_mklev) {
72 1.1 cgd if(x == u.ux && y == u.uy && ptr->mlet != ' ')
73 1.1 cgd mnexto(mtmp);
74 1.1 cgd if(x == 0 && y == 0)
75 1.1 cgd rloc(mtmp);
76 1.1 cgd }
77 1.1 cgd if(ptr->mlet == 's' || ptr->mlet == 'S') {
78 1.1 cgd mtmp->mhide = mtmp->mundetected = 1;
79 1.1 cgd if(in_mklev)
80 1.1 cgd if(mtmp->mx && mtmp->my)
81 1.1 cgd (void) mkobj_at(0, mtmp->mx, mtmp->my);
82 1.1 cgd }
83 1.1 cgd if(ptr->mlet == ':') {
84 1.1 cgd mtmp->cham = 1;
85 1.1 cgd (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
86 1.1 cgd }
87 1.1 cgd if(ptr->mlet == 'I' || ptr->mlet == ';')
88 1.1 cgd mtmp->minvis = 1;
89 1.1 cgd if(ptr->mlet == 'L' || ptr->mlet == 'N'
90 1.1 cgd || (in_mklev && index("&w;", ptr->mlet) && rn2(5))
91 1.1 cgd ) mtmp->msleep = 1;
92 1.1 cgd
93 1.1 cgd #ifndef NOWORM
94 1.1 cgd if(ptr->mlet == 'w' && getwn(mtmp))
95 1.1 cgd initworm(mtmp);
96 1.1 cgd #endif NOWORM
97 1.1 cgd
98 1.1 cgd if(anything) if(ptr->mlet == 'O' || ptr->mlet == 'k') {
99 1.1 cgd coord enexto();
100 1.1 cgd coord mm;
101 1.1 cgd register int cnt = rnd(10);
102 1.1 cgd mm.x = x;
103 1.1 cgd mm.y = y;
104 1.1 cgd while(cnt--) {
105 1.1 cgd mm = enexto(mm.x, mm.y);
106 1.1 cgd (void) makemon(ptr, mm.x, mm.y);
107 1.1 cgd }
108 1.1 cgd }
109 1.1 cgd
110 1.1 cgd return(mtmp);
111 1.1 cgd }
112 1.1 cgd
113 1.1 cgd coord
114 1.1 cgd enexto(xx,yy)
115 1.1 cgd register xchar xx,yy;
116 1.1 cgd {
117 1.1 cgd register xchar x,y;
118 1.1 cgd coord foo[15], *tfoo;
119 1.1 cgd int range;
120 1.1 cgd
121 1.1 cgd tfoo = foo;
122 1.1 cgd range = 1;
123 1.1 cgd do { /* full kludge action. */
124 1.1 cgd for(x = xx-range; x <= xx+range; x++)
125 1.1 cgd if(goodpos(x, yy-range)) {
126 1.1 cgd tfoo->x = x;
127 1.1 cgd tfoo++->y = yy-range;
128 1.1 cgd if(tfoo == &foo[15]) goto foofull;
129 1.1 cgd }
130 1.1 cgd for(x = xx-range; x <= xx+range; x++)
131 1.1 cgd if(goodpos(x,yy+range)) {
132 1.1 cgd tfoo->x = x;
133 1.1 cgd tfoo++->y = yy+range;
134 1.1 cgd if(tfoo == &foo[15]) goto foofull;
135 1.1 cgd }
136 1.1 cgd for(y = yy+1-range; y < yy+range; y++)
137 1.1 cgd if(goodpos(xx-range,y)) {
138 1.1 cgd tfoo->x = xx-range;
139 1.1 cgd tfoo++->y = y;
140 1.1 cgd if(tfoo == &foo[15]) goto foofull;
141 1.1 cgd }
142 1.1 cgd for(y = yy+1-range; y < yy+range; y++)
143 1.1 cgd if(goodpos(xx+range,y)) {
144 1.1 cgd tfoo->x = xx+range;
145 1.1 cgd tfoo++->y = y;
146 1.1 cgd if(tfoo == &foo[15]) goto foofull;
147 1.1 cgd }
148 1.1 cgd range++;
149 1.1 cgd } while(tfoo == foo);
150 1.1 cgd foofull:
151 1.1 cgd return( foo[rn2(tfoo-foo)] );
152 1.1 cgd }
153 1.1 cgd
154 1.1 cgd goodpos(x,y) /* used only in mnexto and rloc */
155 1.1 cgd {
156 1.1 cgd return(
157 1.1 cgd ! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
158 1.1 cgd m_at(x,y) || !ACCESSIBLE(levl[x][y].typ)
159 1.1 cgd || (x == u.ux && y == u.uy)
160 1.1 cgd || sobj_at(ENORMOUS_ROCK, x, y)
161 1.1 cgd ));
162 1.1 cgd }
163 1.1 cgd
164 1.1 cgd rloc(mtmp)
165 1.1 cgd struct monst *mtmp;
166 1.1 cgd {
167 1.1 cgd register tx,ty;
168 1.1 cgd register char ch = mtmp->data->mlet;
169 1.1 cgd
170 1.1 cgd #ifndef NOWORM
171 1.1 cgd if(ch == 'w' && mtmp->mx) return; /* do not relocate worms */
172 1.1 cgd #endif NOWORM
173 1.1 cgd do {
174 1.1 cgd tx = rn1(COLNO-3,2);
175 1.1 cgd ty = rn2(ROWNO);
176 1.1 cgd } while(!goodpos(tx,ty));
177 1.1 cgd mtmp->mx = tx;
178 1.1 cgd mtmp->my = ty;
179 1.1 cgd if(u.ustuck == mtmp){
180 1.1 cgd if(u.uswallow) {
181 1.1 cgd u.ux = tx;
182 1.1 cgd u.uy = ty;
183 1.1 cgd docrt();
184 1.1 cgd } else u.ustuck = 0;
185 1.1 cgd }
186 1.1 cgd pmon(mtmp);
187 1.1 cgd }
188 1.1 cgd
189 1.1 cgd struct monst *
190 1.1 cgd mkmon_at(let,x,y)
191 1.1 cgd char let;
192 1.1 cgd register int x,y;
193 1.1 cgd {
194 1.1 cgd register int ct;
195 1.1 cgd register struct permonst *ptr;
196 1.1 cgd
197 1.1 cgd for(ct = 0; ct < CMNUM; ct++) {
198 1.1 cgd ptr = &mons[ct];
199 1.1 cgd if(ptr->mlet == let)
200 1.1 cgd return(makemon(ptr,x,y));
201 1.1 cgd }
202 1.1 cgd return(0);
203 1.1 cgd }
204