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