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