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