create.c revision 1.9 1 1.9 dholland /* $NetBSD: create.c,v 1.9 2008/01/28 05:38:53 dholland Exp $ */
2 1.6 christos
3 1.6 christos /* create.c Larn is copyrighted 1986 by Noah Morgan. */
4 1.6 christos
5 1.6 christos #include <sys/cdefs.h>
6 1.2 mycroft #ifndef lint
7 1.9 dholland __RCSID("$NetBSD: create.c,v 1.9 2008/01/28 05:38:53 dholland Exp $");
8 1.6 christos #endif /* not lint */
9 1.2 mycroft
10 1.1 cgd #include "header.h"
11 1.6 christos #include "extern.h"
12 1.6 christos #include <unistd.h>
13 1.7 jsm static void fillroom(int, int);
14 1.6 christos
15 1.1 cgd /*
16 1.1 cgd makeplayer()
17 1.1 cgd
18 1.1 cgd subroutine to create the player and the players attributes
19 1.1 cgd this is called at the beginning of a game and at no other time
20 1.1 cgd */
21 1.6 christos void
22 1.1 cgd makeplayer()
23 1.6 christos {
24 1.6 christos int i;
25 1.6 christos scbr();
26 1.6 christos clear();
27 1.6 christos c[HPMAX] = c[HP] = 10; /* start player off with 15 hit points */
28 1.6 christos c[LEVEL] = 1; /* player starts at level one */
29 1.6 christos c[SPELLMAX] = c[SPELLS] = 1; /* total # spells starts off as 3 */
30 1.6 christos c[REGENCOUNTER] = 16;
31 1.6 christos c[ECOUNTER] = 96; /* start regeneration correctly */
32 1.1 cgd c[SHIELD] = c[WEAR] = c[WIELD] = -1;
33 1.6 christos for (i = 0; i < 26; i++)
34 1.6 christos iven[i] = 0;
35 1.6 christos spelknow[0] = spelknow[1] = 1; /* he knows protection, magic missile */
36 1.6 christos if (c[HARDGAME] <= 0) {
37 1.6 christos iven[0] = OLEATHER;
38 1.6 christos iven[1] = ODAGGER;
39 1.6 christos ivenarg[1] = ivenarg[0] = c[WEAR] = 0;
40 1.6 christos c[WIELD] = 1;
41 1.6 christos }
42 1.6 christos playerx = rnd(MAXX - 2);
43 1.6 christos playery = rnd(MAXY - 2);
44 1.6 christos oldx = 0;
45 1.6 christos oldy = 25;
46 1.6 christos gltime = 0; /* time clock starts at zero */
47 1.1 cgd cbak[SPELLS] = -50;
48 1.6 christos for (i = 0; i < 6; i++)
49 1.6 christos c[i] = 12; /* make the attributes, ie str, int, etc. */
50 1.1 cgd recalc();
51 1.6 christos }
52 1.6 christos
53 1.6 christos
54 1.1 cgd /*
55 1.1 cgd newcavelevel(level)
56 1.1 cgd int level;
57 1.1 cgd
58 1.1 cgd function to enter a new level. This routine must be called anytime the
59 1.1 cgd player changes levels. If that level is unknown it will be created.
60 1.1 cgd A new set of monsters will be created for a new level, and existing
61 1.1 cgd levels will get a few more monsters.
62 1.1 cgd Note that it is here we remove genocided monsters from the present level.
63 1.1 cgd */
64 1.6 christos void
65 1.1 cgd newcavelevel(x)
66 1.6 christos int x;
67 1.6 christos {
68 1.6 christos int i, j;
69 1.6 christos if (beenhere[level])
70 1.6 christos savelevel(); /* put the level back into storage */
71 1.6 christos level = x; /* get the new level and put in working
72 1.6 christos * storage */
73 1.6 christos if (beenhere[x] == 0)
74 1.6 christos for (i = 0; i < MAXY; i++)
75 1.6 christos for (j = 0; j < MAXX; j++)
76 1.6 christos know[j][i] = mitem[j][i] = 0;
77 1.6 christos else {
78 1.6 christos getlevel();
79 1.6 christos sethp(0);
80 1.6 christos goto chgn;
81 1.6 christos }
82 1.6 christos makemaze(x);
83 1.6 christos makeobject(x);
84 1.6 christos beenhere[x] = 1;
85 1.6 christos sethp(1);
86 1.1 cgd
87 1.1 cgd #if WIZID
88 1.6 christos if (wizard || x == 0)
89 1.1 cgd #else
90 1.6 christos if (x == 0)
91 1.1 cgd #endif
92 1.1 cgd
93 1.6 christos for (j = 0; j < MAXY; j++)
94 1.6 christos for (i = 0; i < MAXX; i++)
95 1.6 christos know[i][j] = 1;
96 1.6 christos chgn: checkgen(); /* wipe out any genocided monsters */
97 1.6 christos }
98 1.1 cgd
99 1.1 cgd /*
100 1.1 cgd makemaze(level)
101 1.1 cgd int level;
102 1.1 cgd
103 1.1 cgd subroutine to make the caverns for a given level. only walls are made.
104 1.1 cgd */
105 1.6 christos static int mx, mxl, mxh, my, myl, myh, tmp2;
106 1.6 christos void
107 1.6 christos makemaze(k)
108 1.6 christos int k;
109 1.6 christos {
110 1.6 christos int i, j, tmp;
111 1.6 christos int z;
112 1.6 christos if (k > 1 && (rnd(17) <= 4 || k == MAXLEVEL - 1 || k == MAXLEVEL + MAXVLEVEL - 1)) {
113 1.8 simonb if (cannedlevel(k))
114 1.8 simonb return; /* read maze from data file */
115 1.6 christos }
116 1.6 christos if (k == 0)
117 1.6 christos tmp = 0;
118 1.6 christos else
119 1.6 christos tmp = OWALL;
120 1.6 christos for (i = 0; i < MAXY; i++)
121 1.6 christos for (j = 0; j < MAXX; j++)
122 1.6 christos item[j][i] = tmp;
123 1.6 christos if (k == 0)
124 1.6 christos return;
125 1.6 christos eat(1, 1);
126 1.6 christos if (k == 1)
127 1.6 christos item[33][MAXY - 1] = 0; /* exit from dungeon */
128 1.6 christos
129 1.6 christos /* now for open spaces -- not on level 10 */
130 1.6 christos if (k != MAXLEVEL - 1) {
131 1.6 christos tmp2 = rnd(3) + 3;
132 1.6 christos for (tmp = 0; tmp < tmp2; tmp++) {
133 1.6 christos my = rnd(11) + 2;
134 1.6 christos myl = my - rnd(2);
135 1.6 christos myh = my + rnd(2);
136 1.6 christos if (k < MAXLEVEL) {
137 1.6 christos mx = rnd(44) + 5;
138 1.6 christos mxl = mx - rnd(4);
139 1.6 christos mxh = mx + rnd(12) + 3;
140 1.6 christos z = 0;
141 1.6 christos } else {
142 1.6 christos mx = rnd(60) + 3;
143 1.6 christos mxl = mx - rnd(2);
144 1.6 christos mxh = mx + rnd(2);
145 1.1 cgd z = makemonst(k);
146 1.6 christos }
147 1.6 christos for (i = mxl; i < mxh; i++)
148 1.6 christos for (j = myl; j < myh; j++) {
149 1.6 christos item[i][j] = 0;
150 1.6 christos if ((mitem[i][j] = z))
151 1.6 christos hitp[i][j] = monster[z].hitpoints;
152 1.1 cgd }
153 1.1 cgd }
154 1.1 cgd }
155 1.6 christos if (k != MAXLEVEL - 1) {
156 1.6 christos my = rnd(MAXY - 2);
157 1.6 christos for (i = 1; i < MAXX - 1; i++)
158 1.6 christos item[i][my] = 0;
159 1.6 christos }
160 1.6 christos if (k > 1)
161 1.6 christos treasureroom(k);
162 1.6 christos }
163 1.1 cgd
164 1.1 cgd /*
165 1.1 cgd function to eat away a filled in maze
166 1.1 cgd */
167 1.6 christos void
168 1.6 christos eat(xx, yy)
169 1.6 christos int xx, yy;
170 1.6 christos {
171 1.6 christos int dir, try;
172 1.6 christos dir = rnd(4);
173 1.6 christos try = 2;
174 1.6 christos while (try) {
175 1.6 christos switch (dir) {
176 1.6 christos case 1:
177 1.6 christos if (xx <= 2)
178 1.6 christos break; /* west */
179 1.6 christos if ((item[xx - 1][yy] != OWALL) || (item[xx - 2][yy] != OWALL))
180 1.6 christos break;
181 1.6 christos item[xx - 1][yy] = item[xx - 2][yy] = 0;
182 1.6 christos eat(xx - 2, yy);
183 1.6 christos break;
184 1.6 christos
185 1.6 christos case 2:
186 1.6 christos if (xx >= MAXX - 3)
187 1.6 christos break; /* east */
188 1.6 christos if ((item[xx + 1][yy] != OWALL) || (item[xx + 2][yy] != OWALL))
189 1.6 christos break;
190 1.6 christos item[xx + 1][yy] = item[xx + 2][yy] = 0;
191 1.6 christos eat(xx + 2, yy);
192 1.6 christos break;
193 1.6 christos
194 1.6 christos case 3:
195 1.6 christos if (yy <= 2)
196 1.6 christos break; /* south */
197 1.6 christos if ((item[xx][yy - 1] != OWALL) || (item[xx][yy - 2] != OWALL))
198 1.6 christos break;
199 1.6 christos item[xx][yy - 1] = item[xx][yy - 2] = 0;
200 1.6 christos eat(xx, yy - 2);
201 1.6 christos break;
202 1.6 christos
203 1.6 christos case 4:
204 1.6 christos if (yy >= MAXY - 3)
205 1.6 christos break; /* north */
206 1.6 christos if ((item[xx][yy + 1] != OWALL) || (item[xx][yy + 2] != OWALL))
207 1.6 christos break;
208 1.6 christos item[xx][yy + 1] = item[xx][yy + 2] = 0;
209 1.6 christos eat(xx, yy + 2);
210 1.6 christos break;
211 1.6 christos };
212 1.6 christos if (++dir > 4) {
213 1.6 christos dir = 1;
214 1.6 christos --try;
215 1.1 cgd }
216 1.1 cgd }
217 1.6 christos }
218 1.1 cgd
219 1.1 cgd /*
220 1.1 cgd * function to read in a maze from a data file
221 1.1 cgd *
222 1.1 cgd * Format of maze data file: 1st character = # of mazes in file (ascii digit)
223 1.1 cgd * For each maze: 18 lines (1st 17 used) 67 characters per line
224 1.1 cgd *
225 1.1 cgd * Special characters in maze data file:
226 1.1 cgd *
227 1.1 cgd * # wall D door . random monster
228 1.1 cgd * ~ eye of larn ! cure dianthroritis
229 1.1 cgd * - random object
230 1.1 cgd */
231 1.6 christos int
232 1.1 cgd cannedlevel(k)
233 1.6 christos int k;
234 1.6 christos {
235 1.6 christos char *row;
236 1.6 christos int i, j;
237 1.6 christos int it, arg, mit, marg;
238 1.6 christos if (lopen(larnlevels) < 0) {
239 1.6 christos write(1, "Can't open the maze data file\n", 30);
240 1.6 christos died(-282);
241 1.6 christos return (0);
242 1.6 christos }
243 1.6 christos i = lgetc();
244 1.6 christos if (i <= '0') {
245 1.6 christos died(-282);
246 1.6 christos return (0);
247 1.6 christos }
248 1.6 christos for (i = 18 * rund(i - '0'); i > 0; i--)
249 1.6 christos lgetl(); /* advance to desired maze */
250 1.6 christos for (i = 0; i < MAXY; i++) {
251 1.1 cgd row = lgetl();
252 1.6 christos for (j = 0; j < MAXX; j++) {
253 1.1 cgd it = mit = arg = marg = 0;
254 1.6 christos switch (*row++) {
255 1.6 christos case '#':
256 1.6 christos it = OWALL;
257 1.6 christos break;
258 1.6 christos case 'D':
259 1.6 christos it = OCLOSEDDOOR;
260 1.6 christos arg = rnd(30);
261 1.6 christos break;
262 1.6 christos case '~':
263 1.6 christos if (k != MAXLEVEL - 1)
264 1.6 christos break;
265 1.6 christos it = OLARNEYE;
266 1.6 christos mit = rund(8) + DEMONLORD;
267 1.6 christos marg = monster[mit].hitpoints;
268 1.6 christos break;
269 1.6 christos case '!':
270 1.6 christos if (k != MAXLEVEL + MAXVLEVEL - 1)
271 1.6 christos break;
272 1.6 christos it = OPOTION;
273 1.6 christos arg = 21;
274 1.6 christos mit = DEMONLORD + 7;
275 1.6 christos marg = monster[mit].hitpoints;
276 1.6 christos break;
277 1.6 christos case '.':
278 1.6 christos if (k < MAXLEVEL)
279 1.6 christos break;
280 1.6 christos mit = makemonst(k + 1);
281 1.6 christos marg = monster[mit].hitpoints;
282 1.6 christos break;
283 1.6 christos case '-':
284 1.6 christos it = newobject(k + 1, &arg);
285 1.6 christos break;
286 1.6 christos };
287 1.6 christos item[j][i] = it;
288 1.6 christos iarg[j][i] = arg;
289 1.6 christos mitem[j][i] = mit;
290 1.6 christos hitp[j][i] = marg;
291 1.1 cgd
292 1.1 cgd #if WIZID
293 1.1 cgd know[j][i] = (wizard) ? 1 : 0;
294 1.1 cgd #else
295 1.1 cgd know[j][i] = 0;
296 1.1 cgd #endif
297 1.1 cgd }
298 1.6 christos }
299 1.1 cgd lrclose();
300 1.6 christos return (1);
301 1.6 christos }
302 1.1 cgd
303 1.1 cgd /*
304 1.1 cgd function to make a treasure room on a level
305 1.1 cgd level 10's treasure room has the eye in it and demon lords
306 1.1 cgd level V3 has potion of cure dianthroritis and demon prince
307 1.1 cgd */
308 1.6 christos void
309 1.1 cgd treasureroom(lv)
310 1.6 christos int lv;
311 1.6 christos {
312 1.6 christos int tx, ty, xsize, ysize;
313 1.6 christos
314 1.6 christos for (tx = 1 + rnd(10); tx < MAXX - 10; tx += 10)
315 1.6 christos if ((lv == MAXLEVEL - 1) || (lv == MAXLEVEL + MAXVLEVEL - 1) || rnd(13) == 2) {
316 1.6 christos xsize = rnd(6) + 3;
317 1.6 christos ysize = rnd(3) + 3;
318 1.6 christos ty = rnd(MAXY - 9) + 1; /* upper left corner of room */
319 1.6 christos if (lv == MAXLEVEL - 1 || lv == MAXLEVEL + MAXVLEVEL - 1)
320 1.6 christos troom(lv, xsize, ysize, tx = tx + rnd(MAXX - 24), ty, rnd(3) + 6);
321 1.6 christos else
322 1.6 christos troom(lv, xsize, ysize, tx, ty, rnd(9));
323 1.1 cgd }
324 1.6 christos }
325 1.1 cgd
326 1.1 cgd /*
327 1.6 christos * subroutine to create a treasure room of any size at a given location
328 1.6 christos * room is filled with objects and monsters
329 1.1 cgd * the coordinate given is that of the upper left corner of the room
330 1.1 cgd */
331 1.6 christos void
332 1.6 christos troom(lv, xsize, ysize, tx, ty, glyph)
333 1.6 christos int lv, xsize, ysize, tx, ty, glyph;
334 1.6 christos {
335 1.6 christos int i, j;
336 1.6 christos int tp1, tp2;
337 1.6 christos for (j = ty - 1; j <= ty + ysize; j++)
338 1.6 christos for (i = tx - 1; i <= tx + xsize; i++) /* clear out space for
339 1.6 christos * room */
340 1.6 christos item[i][j] = 0;
341 1.6 christos for (j = ty; j < ty + ysize; j++)
342 1.6 christos for (i = tx; i < tx + xsize; i++) { /* now put in the walls */
343 1.6 christos item[i][j] = OWALL;
344 1.6 christos mitem[i][j] = 0;
345 1.6 christos }
346 1.6 christos for (j = ty + 1; j < ty + ysize - 1; j++)
347 1.6 christos for (i = tx + 1; i < tx + xsize - 1; i++) /* now clear out
348 1.6 christos * interior */
349 1.6 christos item[i][j] = 0;
350 1.6 christos
351 1.6 christos switch (rnd(2)) { /* locate the door on the treasure room */
352 1.6 christos case 1:
353 1.6 christos item[i = tx + rund(xsize)][j = ty + (ysize - 1) * rund(2)] = OCLOSEDDOOR;
354 1.6 christos iarg[i][j] = glyph; /* on horizontal walls */
355 1.6 christos break;
356 1.6 christos case 2:
357 1.6 christos item[i = tx + (xsize - 1) * rund(2)][j = ty + rund(ysize)] = OCLOSEDDOOR;
358 1.6 christos iarg[i][j] = glyph; /* on vertical walls */
359 1.6 christos break;
360 1.6 christos };
361 1.6 christos
362 1.6 christos tp1 = playerx;
363 1.6 christos tp2 = playery;
364 1.6 christos playery = ty + (ysize >> 1);
365 1.6 christos if (c[HARDGAME] < 2)
366 1.6 christos for (playerx = tx + 1; playerx <= tx + xsize - 2; playerx += 2)
367 1.6 christos for (i = 0, j = rnd(6); i <= j; i++) {
368 1.6 christos something(lv + 2);
369 1.6 christos createmonster(makemonst(lv + 1));
370 1.6 christos }
371 1.6 christos else
372 1.6 christos for (playerx = tx + 1; playerx <= tx + xsize - 2; playerx += 2)
373 1.6 christos for (i = 0, j = rnd(4); i <= j; i++) {
374 1.6 christos something(lv + 2);
375 1.6 christos createmonster(makemonst(lv + 3));
376 1.1 cgd }
377 1.1 cgd
378 1.6 christos playerx = tp1;
379 1.6 christos playery = tp2;
380 1.6 christos }
381 1.1 cgd
382 1.1 cgd
383 1.1 cgd /*
384 1.1 cgd ***********
385 1.1 cgd MAKE_OBJECT
386 1.1 cgd ***********
387 1.1 cgd subroutine to create the objects in the maze for the given level
388 1.1 cgd */
389 1.6 christos void
390 1.1 cgd makeobject(j)
391 1.6 christos int j;
392 1.6 christos {
393 1.6 christos int i;
394 1.6 christos if (j == 0) {
395 1.6 christos fillroom(OENTRANCE, 0); /* entrance to dungeon */
396 1.6 christos fillroom(ODNDSTORE, 0); /* the DND STORE */
397 1.6 christos fillroom(OSCHOOL, 0); /* college of Larn */
398 1.6 christos fillroom(OBANK, 0); /* 1st national bank of larn */
399 1.6 christos fillroom(OVOLDOWN, 0); /* volcano shaft to temple */
400 1.6 christos fillroom(OHOME, 0); /* the players home & family */
401 1.6 christos fillroom(OTRADEPOST, 0); /* the trading post */
402 1.6 christos fillroom(OLRS, 0); /* the larn revenue service */
403 1.1 cgd return;
404 1.6 christos }
405 1.6 christos if (j == MAXLEVEL)
406 1.6 christos fillroom(OVOLUP, 0); /* volcano shaft up from the temple */
407 1.1 cgd
408 1.6 christos /* make the fixed objects in the maze STAIRS */
409 1.6 christos if ((j > 0) && (j != MAXLEVEL - 1) && (j != MAXLEVEL + MAXVLEVEL - 1))
410 1.6 christos fillroom(OSTAIRSDOWN, 0);
411 1.6 christos if ((j > 1) && (j != MAXLEVEL))
412 1.6 christos fillroom(OSTAIRSUP, 0);
413 1.6 christos
414 1.6 christos /* make the random objects in the maze */
415 1.6 christos
416 1.6 christos fillmroom(rund(3), OBOOK, j);
417 1.6 christos fillmroom(rund(3), OALTAR, 0);
418 1.6 christos fillmroom(rund(3), OSTATUE, 0);
419 1.6 christos fillmroom(rund(3), OPIT, 0);
420 1.6 christos fillmroom(rund(3), OFOUNTAIN, 0);
421 1.6 christos fillmroom(rnd(3) - 2, OIVTELETRAP, 0);
422 1.6 christos fillmroom(rund(2), OTHRONE, 0);
423 1.6 christos fillmroom(rund(2), OMIRROR, 0);
424 1.6 christos fillmroom(rund(2), OTRAPARROWIV, 0);
425 1.6 christos fillmroom(rnd(3) - 2, OIVDARTRAP, 0);
426 1.6 christos fillmroom(rund(3), OCOOKIE, 0);
427 1.6 christos if (j == 1)
428 1.6 christos fillmroom(1, OCHEST, j);
429 1.6 christos else
430 1.6 christos fillmroom(rund(2), OCHEST, j);
431 1.6 christos if ((j != MAXLEVEL - 1) && (j != MAXLEVEL + MAXVLEVEL - 1))
432 1.6 christos fillmroom(rund(2), OIVTRAPDOOR, 0);
433 1.6 christos if (j <= 10) {
434 1.6 christos fillmroom((rund(2)), ODIAMOND, rnd(10 * j + 1) + 10);
435 1.6 christos fillmroom(rund(2), ORUBY, rnd(6 * j + 1) + 6);
436 1.6 christos fillmroom(rund(2), OEMERALD, rnd(4 * j + 1) + 4);
437 1.6 christos fillmroom(rund(2), OSAPPHIRE, rnd(3 * j + 1) + 2);
438 1.6 christos }
439 1.6 christos for (i = 0; i < rnd(4) + 3; i++)
440 1.6 christos fillroom(OPOTION, newpotion()); /* make a POTION */
441 1.6 christos for (i = 0; i < rnd(5) + 3; i++)
442 1.6 christos fillroom(OSCROLL, newscroll()); /* make a SCROLL */
443 1.6 christos for (i = 0; i < rnd(12) + 11; i++)
444 1.6 christos fillroom(OGOLDPILE, 12 * rnd(j + 1) + (j << 3) + 10); /* make GOLD */
445 1.6 christos if (j == 5)
446 1.6 christos fillroom(OBANK2, 0); /* branch office of the bank */
447 1.6 christos froom(2, ORING, 0); /* a ring mail */
448 1.6 christos froom(1, OSTUDLEATHER, 0); /* a studded leather */
449 1.6 christos froom(3, OSPLINT, 0); /* a splint mail */
450 1.6 christos froom(5, OSHIELD, rund(3)); /* a shield */
451 1.6 christos froom(2, OBATTLEAXE, rund(3)); /* a battle axe */
452 1.6 christos froom(5, OLONGSWORD, rund(3)); /* a long sword */
453 1.6 christos froom(5, OFLAIL, rund(3)); /* a flail */
454 1.6 christos froom(4, OREGENRING, rund(3)); /* ring of regeneration */
455 1.6 christos froom(1, OPROTRING, rund(3)); /* ring of protection */
456 1.6 christos froom(2, OSTRRING, 4); /* ring of strength + 4 */
457 1.6 christos froom(7, OSPEAR, rnd(5)); /* a spear */
458 1.6 christos froom(3, OORBOFDRAGON, 0); /* orb of dragon slaying */
459 1.6 christos froom(4, OSPIRITSCARAB, 0); /* scarab of negate spirit */
460 1.6 christos froom(4, OCUBEofUNDEAD, 0); /* cube of undead control */
461 1.6 christos froom(2, ORINGOFEXTRA, 0); /* ring of extra regen */
462 1.6 christos froom(3, ONOTHEFT, 0); /* device of antitheft */
463 1.6 christos froom(2, OSWORDofSLASHING, 0); /* sword of slashing */
464 1.6 christos if (c[BESSMANN] == 0) {
465 1.6 christos froom(4, OHAMMER, 0); /* Bessman's flailing hammer */
466 1.6 christos c[BESSMANN] = 1;
467 1.6 christos }
468 1.6 christos if (c[HARDGAME] < 3 || (rnd(4) == 3)) {
469 1.6 christos if (j > 3) {
470 1.6 christos froom(3, OSWORD, 3); /* sunsword + 3 */
471 1.6 christos froom(5, O2SWORD, rnd(4)); /* a two handed sword */
472 1.6 christos froom(3, OBELT, 4); /* belt of striking */
473 1.6 christos froom(3, OENERGYRING, 3); /* energy ring */
474 1.6 christos froom(4, OPLATE, 5); /* platemail + 5 */
475 1.1 cgd }
476 1.1 cgd }
477 1.6 christos }
478 1.1 cgd
479 1.1 cgd /*
480 1.1 cgd subroutine to fill in a number of objects of the same kind
481 1.1 cgd */
482 1.1 cgd
483 1.6 christos void
484 1.6 christos fillmroom(n, what, arg)
485 1.6 christos int n, arg;
486 1.6 christos char what;
487 1.6 christos {
488 1.6 christos int i;
489 1.6 christos for (i = 0; i < n; i++)
490 1.6 christos fillroom(what, arg);
491 1.6 christos }
492 1.6 christos void
493 1.9 dholland froom(int n, int theitem, int arg)
494 1.6 christos {
495 1.6 christos if (rnd(151) < n)
496 1.9 dholland fillroom(theitem, arg);
497 1.6 christos }
498 1.1 cgd
499 1.1 cgd /*
500 1.1 cgd subroutine to put an object into an empty room
501 1.1 cgd * uses a random walk
502 1.1 cgd */
503 1.1 cgd static void
504 1.6 christos fillroom(what, arg)
505 1.6 christos int arg;
506 1.6 christos char what;
507 1.6 christos {
508 1.6 christos int x, y;
509 1.1 cgd
510 1.1 cgd #ifdef EXTRA
511 1.1 cgd c[FILLROOM]++;
512 1.1 cgd #endif
513 1.1 cgd
514 1.6 christos x = rnd(MAXX - 2);
515 1.6 christos y = rnd(MAXY - 2);
516 1.6 christos while (item[x][y]) {
517 1.1 cgd
518 1.1 cgd #ifdef EXTRA
519 1.6 christos c[RANDOMWALK]++;/* count up these random walks */
520 1.1 cgd #endif
521 1.1 cgd
522 1.6 christos x += rnd(3) - 2;
523 1.6 christos y += rnd(3) - 2;
524 1.6 christos if (x > MAXX - 2)
525 1.6 christos x = 1;
526 1.6 christos if (x < 1)
527 1.6 christos x = MAXX - 2;
528 1.6 christos if (y > MAXY - 2)
529 1.6 christos y = 1;
530 1.6 christos if (y < 1)
531 1.6 christos y = MAXY - 2;
532 1.6 christos }
533 1.6 christos item[x][y] = what;
534 1.6 christos iarg[x][y] = arg;
535 1.6 christos }
536 1.1 cgd
537 1.1 cgd /*
538 1.1 cgd subroutine to put monsters into an empty room without walls or other
539 1.1 cgd monsters
540 1.1 cgd */
541 1.6 christos int
542 1.1 cgd fillmonst(what)
543 1.6 christos int what;
544 1.6 christos {
545 1.6 christos int x, y, trys;
546 1.6 christos for (trys = 5; trys > 0; --trys) { /* max # of creation attempts */
547 1.6 christos x = rnd(MAXX - 2);
548 1.6 christos y = rnd(MAXY - 2);
549 1.6 christos if ((item[x][y] == 0) && (mitem[x][y] == 0) && ((playerx != x) || (playery != y))) {
550 1.6 christos mitem[x][y] = what;
551 1.6 christos know[x][y] = 0;
552 1.6 christos hitp[x][y] = monster[what].hitpoints;
553 1.6 christos return (0);
554 1.1 cgd }
555 1.1 cgd }
556 1.6 christos return (-1); /* creation failure */
557 1.6 christos }
558 1.1 cgd
559 1.1 cgd /*
560 1.1 cgd creates an entire set of monsters for a level
561 1.1 cgd must be done when entering a new level
562 1.1 cgd if sethp(1) then wipe out old monsters else leave them there
563 1.1 cgd */
564 1.6 christos void
565 1.1 cgd sethp(flg)
566 1.6 christos int flg;
567 1.6 christos {
568 1.6 christos int i, j;
569 1.6 christos if (flg)
570 1.6 christos for (i = 0; i < MAXY; i++)
571 1.6 christos for (j = 0; j < MAXX; j++)
572 1.6 christos stealth[j][i] = 0;
573 1.6 christos if (level == 0) {
574 1.6 christos c[TELEFLAG] = 0;
575 1.6 christos return;
576 1.6 christos } /* if teleported and found level 1 then know
577 1.6 christos * level we are on */
578 1.6 christos if (flg)
579 1.6 christos j = rnd(12) + 2 + (level >> 1);
580 1.6 christos else
581 1.6 christos j = (level >> 1) + 1;
582 1.6 christos for (i = 0; i < j; i++)
583 1.6 christos fillmonst(makemonst(level));
584 1.1 cgd positionplayer();
585 1.6 christos }
586 1.1 cgd
587 1.1 cgd /*
588 1.1 cgd * Function to destroy all genocided monsters on the present level
589 1.1 cgd */
590 1.6 christos void
591 1.1 cgd checkgen()
592 1.6 christos {
593 1.6 christos int x, y;
594 1.6 christos for (y = 0; y < MAXY; y++)
595 1.6 christos for (x = 0; x < MAXX; x++)
596 1.1 cgd if (monster[mitem[x][y]].genocided)
597 1.6 christos mitem[x][y] = 0; /* no more monster */
598 1.6 christos }
599