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