1 /* create.c Larn is copyrighted 1986 by Noah Morgan. */
2 /* $FreeBSD: src/games/larn/create.c,v 1.4 1999/11/16 02:57:20 billf Exp $ */
3 /* $DragonFly: src/games/larn/create.c,v 1.3 2006/08/26 17:05:05 pavalos Exp $ */
6 static void makemaze(int);
7 static int cannedlevel(int);
8 static void treasureroom(int);
9 static void troom(int, int, int, int, int, int);
10 static void makeobject(int);
11 static void fillmroom(int, char, int);
12 static void froom(int, char, int);
13 static void fillroom(char, int);
14 static void sethp(int);
15 static void checkgen(void);
20 subroutine to create the player and the players attributes
21 this is called at the beginning of a game and at no other time
29 c[HPMAX] = c[HP] = 10; /* start player off with 15 hit points */
30 c[LEVEL] = 1; /* player starts at level one */
31 c[SPELLMAX] = c[SPELLS] = 1; /* total # spells starts off as 3 */
32 c[REGENCOUNTER] = 16; /* start regeneration correctly */
34 c[SHIELD] = c[WEAR] = c[WIELD] = -1;
35 for (i = 0; i < 26; i++)
37 spelknow[0] = spelknow[1] = 1; /* he knows protection, magic missile */
38 if (c[HARDGAME] <= 0) {
41 ivenarg[1] = ivenarg[0] = c[WEAR] = 0;
44 playerx = rnd(MAXX - 2);
45 playery = rnd(MAXY - 2);
48 gtime = 0; /* time clock starts at zero */
50 for (i = 0; i < 6; i++) /* make the attributes, ie str, int, etc. */
59 function to enter a new level. This routine must be called anytime the
60 player changes levels. If that level is unknown it will be created.
61 A new set of monsters will be created for a new level, and existing
62 levels will get a few more monsters.
63 Note that it is here we remove genocided monsters from the present level.
69 if (beenhere[(int)level]) /* put the level back into storage */
71 level = x; /* get the new level and put in working storage */
73 for (i = 0; i < MAXY; i++)
74 for (j = 0; j < MAXX; j++)
75 know[j][i] = mitem[j][i] = 0;
91 for (j = 0; j < MAXY; j++)
92 for (i = 0; i < MAXX; i++)
95 checkgen(); /* wipe out any genocided monsters */
102 subroutine to make the caverns for a given level. only walls are made.
104 static int mx, mxl, mxh, my, myl, myh, tmp2;
111 if (k > 1 && (rnd(17) <= 4 || k == MAXLEVEL - 1 || k == MAXLEVEL + MAXVLEVEL - 1))
112 if (cannedlevel(k)) /* read maze from data file */
118 for (i = 0; i < MAXY; i++)
119 for (j = 0; j < MAXX; j++)
124 if (k == 1) /* exit from dungeon */
125 item[33][MAXY - 1] = 0;
127 /* now for open spaces -- not on level 10 */
128 if (k != MAXLEVEL - 1) {
130 for (tmp = 0; tmp < tmp2; tmp++) {
137 mxh = mx + rnd(12) + 3;
145 for (i = mxl; i < mxh; i++)
146 for (j = myl; j < myh; j++) {
148 if ((mitem[i][j] = z))
149 hitp[i][j] = monster[z].hitpoints;
153 if (k != MAXLEVEL - 1) {
155 for (i = 1; i < MAXX - 1; i++)
163 function to eat away a filled in maze
174 if (xx <= 2) /* west */
176 if ((item[xx - 1][yy] != OWALL) || (item[xx - 2][yy] != OWALL))
178 item[xx - 1][yy] = item[xx - 2][yy] = 0;
183 if (xx >= MAXX - 3) /* east */
185 if ((item[xx + 1][yy] != OWALL) || (item[xx + 2][yy] != OWALL))
187 item[xx + 1][yy] = item[xx + 2][yy] = 0;
192 if (yy <= 2) /* south */
194 if ((item[xx][yy - 1] != OWALL) || (item[xx][yy - 2] != OWALL))
196 item[xx][yy - 1] = item[xx][yy - 2] = 0;
201 if (yy >= MAXY - 3) /* north */
203 if ((item[xx][yy + 1] != OWALL) || (item[xx][yy + 2] != OWALL))
205 item[xx][yy + 1] = item[xx][yy + 2] = 0;
217 * function to read in a maze from a data file
219 * Format of maze data file: 1st character = # of mazes in file (ascii digit)
220 * For each maze: 18 lines (1st 17 used) 67 characters per line
222 * Special characters in maze data file:
224 * # wall D door . random monster
225 * ~ eye of larn ! cure dianthroritis
233 int it, arg, mit, marg;
234 if (lopen(larnlevels) < 0) {
235 write(1, "Can't open the maze data file\n", 30);
244 for (i = 18 * rund(i - '0'); i > 0; i--)
245 lgetl(); /* advance to desired maze */
246 for (i = 0; i < MAXY; i++) {
248 for (j = 0; j < MAXX; j++) {
249 it = mit = arg = marg = 0;
259 if (k != MAXLEVEL - 1)
262 mit = rund(8) + DEMONLORD;
263 marg = monster[mit].hitpoints;
266 if (k != MAXLEVEL + MAXVLEVEL - 1)
271 marg = monster[mit].hitpoints;
276 mit = makemonst(k + 1);
277 marg = monster[mit].hitpoints;
280 it = newobject(k + 1, &arg);
289 know[j][i] = (wizard) ? 1 : 0;
300 function to make a treasure room on a level
301 level 10's treasure room has the eye in it and demon lords
302 level V3 has potion of cure dianthroritis and demon prince
307 int tx, ty, xsize, ysize;
309 for (tx = 1 + rnd(10); tx < MAXX - 10; tx += 10)
310 if ((lv == MAXLEVEL - 1) || (lv == MAXLEVEL + MAXVLEVEL - 1) || rnd(13) == 2) {
313 ty = rnd(MAXY - 9) + 1; /* upper left corner of room */
314 if (lv == MAXLEVEL - 1 || lv == MAXLEVEL + MAXVLEVEL - 1)
315 troom(lv, xsize, ysize, tx = tx + rnd(MAXX - 24), ty, rnd(3) + 6);
317 troom(lv, xsize, ysize, tx, ty, rnd(9));
322 * subroutine to create a treasure room of any size at a given location
323 * room is filled with objects and monsters
324 * the coordinate given is that of the upper left corner of the room
327 troom(int lv, int xsize, int ysize, int tx, int ty, int glyph)
331 for (j = ty - 1; j <= ty + ysize; j++)
332 for (i = tx - 1; i <= tx + xsize; i++) /* clear out space for room */
334 for (j = ty; j < ty + ysize; j++)
335 for (i = tx; i < tx + xsize; i++) { /* now put in the walls */
339 for (j = ty + 1; j < ty + ysize - 1; j++)
340 for (i = tx + 1; i < tx + xsize - 1; i++) /* now clear out interior */
343 switch (rnd(2)) { /* locate the door on the treasure room */
345 item[i = tx + rund(xsize)][j = ty + (ysize - 1) * rund(2)] = OCLOSEDDOOR;
346 iarg[i][j] = glyph; /* on horizontal walls */
349 item[i = tx + (xsize - 1) * rund(2)][j = ty + rund(ysize)] = OCLOSEDDOOR;
350 iarg[i][j] = glyph; /* on vertical walls */
356 playery = ty + (ysize >> 1);
358 for (playerx = tx + 1; playerx <= tx + xsize - 2; playerx += 2)
359 for (i = 0, j = rnd(6); i <= j; i++) {
361 createmonster(makemonst(lv + 1));
364 for (playerx = tx + 1; playerx <= tx + xsize - 2; playerx += 2)
365 for (i = 0, j = rnd(4); i <= j; i++) {
367 createmonster(makemonst(lv + 3));
378 subroutine to create the objects in the maze for the given level
385 fillroom(OENTRANCE, 0); /* entrance to dungeon */
386 fillroom(ODNDSTORE, 0); /* the DND STORE */
387 fillroom(OSCHOOL, 0); /* college of Larn */
388 fillroom(OBANK, 0); /* 1st national bank of larn */
389 fillroom(OVOLDOWN, 0); /* volcano shaft to temple */
390 fillroom(OHOME, 0); /* the players home & family */
391 fillroom(OTRADEPOST, 0);/* the trading post */
392 fillroom(OLRS, 0); /* the larn revenue service */
395 if (j == MAXLEVEL) /* volcano shaft up from the temple */
398 /* make the fixed objects in the maze STAIRS */
399 if ((j > 0) && (j != MAXLEVEL - 1) && (j != MAXLEVEL + MAXVLEVEL - 1))
400 fillroom(OSTAIRSDOWN, 0);
401 if ((j > 1) && (j != MAXLEVEL))
402 fillroom(OSTAIRSUP, 0);
404 /* make the random objects in the maze */
406 fillmroom(rund(3), OBOOK, j);
407 fillmroom(rund(3), OALTAR, 0);
408 fillmroom(rund(3), OSTATUE, 0);
409 fillmroom(rund(3), OPIT, 0);
410 fillmroom(rund(3), OFOUNTAIN, 0);
411 fillmroom(rnd(3) - 2, OIVTELETRAP, 0);
412 fillmroom(rund(2), OTHRONE, 0);
413 fillmroom(rund(2), OMIRROR, 0);
414 fillmroom(rund(2), OTRAPARROWIV, 0);
415 fillmroom(rnd(3) - 2, OIVDARTRAP, 0);
416 fillmroom(rund(3), OCOOKIE, 0);
418 fillmroom(1, OCHEST, j);
420 fillmroom(rund(2), OCHEST, j);
421 if ((j != MAXLEVEL - 1) && (j != MAXLEVEL + MAXVLEVEL - 1))
422 fillmroom(rund(2), OIVTRAPDOOR, 0);
424 fillmroom((rund(2)), ODIAMOND, rnd(10 * j + 1) + 10);
425 fillmroom(rund(2), ORUBY, rnd(6 * j + 1) + 6);
426 fillmroom(rund(2), OEMERALD, rnd(4 * j + 1) + 4);
427 fillmroom(rund(2), OSAPPHIRE, rnd(3 * j + 1) + 2);
429 for (i = 0; i < rnd(4) + 3; i++)
430 fillroom(OPOTION, newpotion()); /* make a POTION */
431 for (i = 0; i < rnd(5) + 3; i++)
432 fillroom(OSCROLL, newscroll()); /* make a SCROLL */
433 for (i = 0; i < rnd(12) + 11; i++)
434 fillroom(OGOLDPILE, 12 * rnd(j + 1) + (j << 3) + 10); /* make GOLD */
436 fillroom(OBANK2, 0); /* branch office of the bank */
437 froom(2, ORING, 0); /* a ring mail */
438 froom(1, OSTUDLEATHER, 0); /* a studded leather */
439 froom(3, OSPLINT, 0); /* a splint mail */
440 froom(5, OSHIELD, rund(3)); /* a shield */
441 froom(2, OBATTLEAXE, rund(3)); /* a battle axe */
442 froom(5, OLONGSWORD, rund(3)); /* a long sword */
443 froom(5, OFLAIL, rund(3)); /* a flail */
444 froom(4, OREGENRING, rund(3)); /* ring of regeneration */
445 froom(1, OPROTRING, rund(3)); /* ring of protection */
446 froom(2, OSTRRING, 4); /* ring of strength + 4 */
447 froom(7, OSPEAR, rnd(5)); /* a spear */
448 froom(3, OORBOFDRAGON, 0); /* orb of dragon slaying */
449 froom(4, OSPIRITSCARAB, 0); /* scarab of negate spirit */
450 froom(4, OCUBEofUNDEAD, 0); /* cube of undead control */
451 froom(2, ORINGOFEXTRA, 0); /* ring of extra regen */
452 froom(3, ONOTHEFT, 0); /* device of antitheft */
453 froom(2, OSWORDofSLASHING, 0); /* sword of slashing */
454 if (c[BESSMANN] == 0) {
455 froom(4, OHAMMER, 0); /* Bessman's flailing hammer */
458 if (c[HARDGAME] < 3 || (rnd(4) == 3)) {
460 froom(3, OSWORD, 3); /* sunsword + 3 */
461 froom(5, O2SWORD, rnd(4)); /* a two handed sword */
462 froom(3, OBELT, 4); /* belt of striking */
463 froom(3, OENERGYRING, 3); /* energy ring */
464 froom(4, OPLATE, 5); /* platemail + 5 */
470 subroutine to fill in a number of objects of the same kind
473 fillmroom(int n, char what, int arg)
476 for (i = 0; i < n; i++)
481 froom(int n, char itm, int arg)
488 subroutine to put an object into an empty room
492 fillroom(char what, int arg)
504 c[RANDOMWALK]++;/* count up these random walks */
523 subroutine to put monsters into an empty room without walls or other
530 for (trys = 5; trys > 0; --trys) { /* max # of creation attempts */
533 if ((item[x][y] == 0) && (mitem[x][y] == 0) &&
534 ((playerx != x) || (playery != y))) {
537 hitp[x][y] = monster[(int)what].hitpoints;
541 return (-1); /* creation failure */
545 creates an entire set of monsters for a level
546 must be done when entering a new level
547 if sethp(1) then wipe out old monsters else leave them there
554 for (i = 0; i < MAXY; i++)
555 for (j = 0; j < MAXX; j++)
561 /* if teleported and found level 1 then know level we are on */
563 j = rnd(12) + 2 + (level >> 1);
565 j = (level >> 1) + 1;
566 for (i = 0; i < j; i++)
567 fillmonst(makemonst(level));
572 * Function to destroy all genocided monsters on the present level
578 for (y = 0; y < MAXY; y++)
579 for (x = 0; x < MAXX; x++)
580 if (monster[(int)mitem[x][y]].genocided)
581 mitem[x][y] = 0; /* no more monster */