1 /* $NetBSD: create.c,v 1.10 2008/02/03 19:20:40 dholland Exp $ */
3 /* create.c Larn is copyrighted 1986 by Noah Morgan. */
7 __RCSID("$NetBSD: create.c,v 1.10 2008/02/03 19:20:40 dholland Exp $");
14 static void makemaze(int);
15 static int cannedlevel(int);
16 static void treasureroom(int);
17 static void troom(int, int, int, int, int, int);
18 static void makeobject(int);
19 static void fillmroom(int, int, int);
20 static void froom(int, int, int);
21 static void fillroom(int, int);
22 static void sethp(int);
23 static void checkgen(void);
28 subroutine to create the player and the players attributes
29 this is called at the beginning of a game and at no other time
37 c
[HPMAX
] = c
[HP
] = 10; /* start player off with 15 hit points */
38 c
[LEVEL
] = 1; /* player starts at level one */
39 c
[SPELLMAX
] = c
[SPELLS
] = 1; /* total # spells starts off as 3 */
41 c
[ECOUNTER
] = 96; /* start regeneration correctly */
42 c
[SHIELD
] = c
[WEAR
] = c
[WIELD
] = -1;
43 for (i
= 0; i
< 26; i
++)
45 spelknow
[0] = spelknow
[1] = 1; /* he knows protection, magic missile */
46 if (c
[HARDGAME
] <= 0) {
49 ivenarg
[1] = ivenarg
[0] = c
[WEAR
] = 0;
52 playerx
= rnd(MAXX
- 2);
53 playery
= rnd(MAXY
- 2);
56 gltime
= 0; /* time clock starts at zero */
58 for (i
= 0; i
< 6; i
++)
59 c
[i
] = 12; /* make the attributes, ie str, int, etc. */
68 function to enter a new level. This routine must be called anytime the
69 player changes levels. If that level is unknown it will be created.
70 A new set of monsters will be created for a new level, and existing
71 levels will get a few more monsters.
72 Note that it is here we remove genocided monsters from the present level.
80 savelevel(); /* put the level back into storage */
81 level
= x
; /* get the new level and put in working
90 /* fill in new level */
91 for (i
= 0; i
< MAXY
; i
++)
92 for (j
= 0; j
< MAXX
; j
++)
93 know
[j
][i
] = mitem
[j
][i
] = 0;
98 checkgen(); /* wipe out any genocided monsters */
101 if (wizard
|| x
== 0)
105 for (j
= 0; j
< MAXY
; j
++)
106 for (i
= 0; i
< MAXX
; i
++)
114 subroutine to make the caverns for a given level. only walls are made.
116 static int mx
, mxl
, mxh
, my
, myl
, myh
, tmp2
;
124 if (k
> 1 && (rnd(17) <= 4 || k
== MAXLEVEL
- 1 || k
== MAXLEVEL
+ MAXVLEVEL
- 1)) {
126 return; /* read maze from data file */
132 for (i
= 0; i
< MAXY
; i
++)
133 for (j
= 0; j
< MAXX
; j
++)
139 item
[33][MAXY
- 1] = 0; /* exit from dungeon */
141 /* now for open spaces -- not on level 10 */
142 if (k
!= MAXLEVEL
- 1) {
144 for (tmp
= 0; tmp
< tmp2
; tmp
++) {
151 mxh
= mx
+ rnd(12) + 3;
159 for (i
= mxl
; i
< mxh
; i
++)
160 for (j
= myl
; j
< myh
; j
++) {
162 if ((mitem
[i
][j
] = z
))
163 hitp
[i
][j
] = monster
[z
].hitpoints
;
167 if (k
!= MAXLEVEL
- 1) {
169 for (i
= 1; i
< MAXX
- 1; i
++)
177 function to eat away a filled in maze
191 if ((item
[xx
- 1][yy
] != OWALL
) || (item
[xx
- 2][yy
] != OWALL
))
193 item
[xx
- 1][yy
] = item
[xx
- 2][yy
] = 0;
200 if ((item
[xx
+ 1][yy
] != OWALL
) || (item
[xx
+ 2][yy
] != OWALL
))
202 item
[xx
+ 1][yy
] = item
[xx
+ 2][yy
] = 0;
209 if ((item
[xx
][yy
- 1] != OWALL
) || (item
[xx
][yy
- 2] != OWALL
))
211 item
[xx
][yy
- 1] = item
[xx
][yy
- 2] = 0;
218 if ((item
[xx
][yy
+ 1] != OWALL
) || (item
[xx
][yy
+ 2] != OWALL
))
220 item
[xx
][yy
+ 1] = item
[xx
][yy
+ 2] = 0;
232 * function to read in a maze from a data file
234 * Format of maze data file: 1st character = # of mazes in file (ascii digit)
235 * For each maze: 18 lines (1st 17 used) 67 characters per line
237 * Special characters in maze data file:
239 * # wall D door . random monster
240 * ~ eye of larn ! cure dianthroritis
249 int it
, arg
, mit
, marg
;
250 if (lopen(larnlevels
) < 0) {
251 write(1, "Can't open the maze data file\n", 30);
260 for (i
= 18 * rund(i
- '0'); i
> 0; i
--)
261 lgetl(); /* advance to desired maze */
262 for (i
= 0; i
< MAXY
; i
++) {
264 for (j
= 0; j
< MAXX
; j
++) {
265 it
= mit
= arg
= marg
= 0;
275 if (k
!= MAXLEVEL
- 1)
278 mit
= rund(8) + DEMONLORD
;
279 marg
= monster
[mit
].hitpoints
;
282 if (k
!= MAXLEVEL
+ MAXVLEVEL
- 1)
287 marg
= monster
[mit
].hitpoints
;
292 mit
= makemonst(k
+ 1);
293 marg
= monster
[mit
].hitpoints
;
296 it
= newobject(k
+ 1, &arg
);
305 know
[j
][i
] = (wizard
) ? 1 : 0;
316 function to make a treasure room on a level
317 level 10's treasure room has the eye in it and demon lords
318 level V3 has potion of cure dianthroritis and demon prince
324 int tx
, ty
, xsize
, ysize
;
326 for (tx
= 1 + rnd(10); tx
< MAXX
- 10; tx
+= 10)
327 if ((lv
== MAXLEVEL
- 1) || (lv
== MAXLEVEL
+ MAXVLEVEL
- 1) || rnd(13) == 2) {
330 ty
= rnd(MAXY
- 9) + 1; /* upper left corner of room */
331 if (lv
== MAXLEVEL
- 1 || lv
== MAXLEVEL
+ MAXVLEVEL
- 1)
332 troom(lv
, xsize
, ysize
, tx
= tx
+ rnd(MAXX
- 24), ty
, rnd(3) + 6);
334 troom(lv
, xsize
, ysize
, tx
, ty
, rnd(9));
339 * subroutine to create a treasure room of any size at a given location
340 * room is filled with objects and monsters
341 * the coordinate given is that of the upper left corner of the room
344 troom(lv
, xsize
, ysize
, tx
, ty
, glyph
)
345 int lv
, xsize
, ysize
, tx
, ty
, glyph
;
349 for (j
= ty
- 1; j
<= ty
+ ysize
; j
++)
350 for (i
= tx
- 1; i
<= tx
+ xsize
; i
++) /* clear out space for
353 for (j
= ty
; j
< ty
+ ysize
; j
++)
354 for (i
= tx
; i
< tx
+ xsize
; i
++) { /* now put in the walls */
358 for (j
= ty
+ 1; j
< ty
+ ysize
- 1; j
++)
359 for (i
= tx
+ 1; i
< tx
+ xsize
- 1; i
++) /* now clear out
363 switch (rnd(2)) { /* locate the door on the treasure room */
365 item
[i
= tx
+ rund(xsize
)][j
= ty
+ (ysize
- 1) * rund(2)] = OCLOSEDDOOR
;
366 iarg
[i
][j
] = glyph
; /* on horizontal walls */
369 item
[i
= tx
+ (xsize
- 1) * rund(2)][j
= ty
+ rund(ysize
)] = OCLOSEDDOOR
;
370 iarg
[i
][j
] = glyph
; /* on vertical walls */
376 playery
= ty
+ (ysize
>> 1);
378 for (playerx
= tx
+ 1; playerx
<= tx
+ xsize
- 2; playerx
+= 2)
379 for (i
= 0, j
= rnd(6); i
<= j
; i
++) {
381 createmonster(makemonst(lv
+ 1));
384 for (playerx
= tx
+ 1; playerx
<= tx
+ xsize
- 2; playerx
+= 2)
385 for (i
= 0, j
= rnd(4); i
<= j
; i
++) {
387 createmonster(makemonst(lv
+ 3));
399 subroutine to create the objects in the maze for the given level
407 fillroom(OENTRANCE
, 0); /* entrance to dungeon */
408 fillroom(ODNDSTORE
, 0); /* the DND STORE */
409 fillroom(OSCHOOL
, 0); /* college of Larn */
410 fillroom(OBANK
, 0); /* 1st national bank of larn */
411 fillroom(OVOLDOWN
, 0); /* volcano shaft to temple */
412 fillroom(OHOME
, 0); /* the players home & family */
413 fillroom(OTRADEPOST
, 0); /* the trading post */
414 fillroom(OLRS
, 0); /* the larn revenue service */
418 fillroom(OVOLUP
, 0); /* volcano shaft up from the temple */
420 /* make the fixed objects in the maze STAIRS */
421 if ((j
> 0) && (j
!= MAXLEVEL
- 1) && (j
!= MAXLEVEL
+ MAXVLEVEL
- 1))
422 fillroom(OSTAIRSDOWN
, 0);
423 if ((j
> 1) && (j
!= MAXLEVEL
))
424 fillroom(OSTAIRSUP
, 0);
426 /* make the random objects in the maze */
428 fillmroom(rund(3), OBOOK
, j
);
429 fillmroom(rund(3), OALTAR
, 0);
430 fillmroom(rund(3), OSTATUE
, 0);
431 fillmroom(rund(3), OPIT
, 0);
432 fillmroom(rund(3), OFOUNTAIN
, 0);
433 fillmroom(rnd(3) - 2, OIVTELETRAP
, 0);
434 fillmroom(rund(2), OTHRONE
, 0);
435 fillmroom(rund(2), OMIRROR
, 0);
436 fillmroom(rund(2), OTRAPARROWIV
, 0);
437 fillmroom(rnd(3) - 2, OIVDARTRAP
, 0);
438 fillmroom(rund(3), OCOOKIE
, 0);
440 fillmroom(1, OCHEST
, j
);
442 fillmroom(rund(2), OCHEST
, j
);
443 if ((j
!= MAXLEVEL
- 1) && (j
!= MAXLEVEL
+ MAXVLEVEL
- 1))
444 fillmroom(rund(2), OIVTRAPDOOR
, 0);
446 fillmroom((rund(2)), ODIAMOND
, rnd(10 * j
+ 1) + 10);
447 fillmroom(rund(2), ORUBY
, rnd(6 * j
+ 1) + 6);
448 fillmroom(rund(2), OEMERALD
, rnd(4 * j
+ 1) + 4);
449 fillmroom(rund(2), OSAPPHIRE
, rnd(3 * j
+ 1) + 2);
451 for (i
= 0; i
< rnd(4) + 3; i
++)
452 fillroom(OPOTION
, newpotion()); /* make a POTION */
453 for (i
= 0; i
< rnd(5) + 3; i
++)
454 fillroom(OSCROLL
, newscroll()); /* make a SCROLL */
455 for (i
= 0; i
< rnd(12) + 11; i
++)
456 fillroom(OGOLDPILE
, 12 * rnd(j
+ 1) + (j
<< 3) + 10); /* make GOLD */
458 fillroom(OBANK2
, 0); /* branch office of the bank */
459 froom(2, ORING
, 0); /* a ring mail */
460 froom(1, OSTUDLEATHER
, 0); /* a studded leather */
461 froom(3, OSPLINT
, 0); /* a splint mail */
462 froom(5, OSHIELD
, rund(3)); /* a shield */
463 froom(2, OBATTLEAXE
, rund(3)); /* a battle axe */
464 froom(5, OLONGSWORD
, rund(3)); /* a long sword */
465 froom(5, OFLAIL
, rund(3)); /* a flail */
466 froom(4, OREGENRING
, rund(3)); /* ring of regeneration */
467 froom(1, OPROTRING
, rund(3)); /* ring of protection */
468 froom(2, OSTRRING
, 4); /* ring of strength + 4 */
469 froom(7, OSPEAR
, rnd(5)); /* a spear */
470 froom(3, OORBOFDRAGON
, 0); /* orb of dragon slaying */
471 froom(4, OSPIRITSCARAB
, 0); /* scarab of negate spirit */
472 froom(4, OCUBEofUNDEAD
, 0); /* cube of undead control */
473 froom(2, ORINGOFEXTRA
, 0); /* ring of extra regen */
474 froom(3, ONOTHEFT
, 0); /* device of antitheft */
475 froom(2, OSWORDofSLASHING
, 0); /* sword of slashing */
476 if (c
[BESSMANN
] == 0) {
477 froom(4, OHAMMER
, 0); /* Bessman's flailing hammer */
480 if (c
[HARDGAME
] < 3 || (rnd(4) == 3)) {
482 froom(3, OSWORD
, 3); /* sunsword + 3 */
483 froom(5, O2SWORD
, rnd(4)); /* a two handed sword */
484 froom(3, OBELT
, 4); /* belt of striking */
485 froom(3, OENERGYRING
, 3); /* energy ring */
486 froom(4, OPLATE
, 5); /* platemail + 5 */
492 subroutine to fill in a number of objects of the same kind
496 fillmroom(n
, what
, arg
)
501 for (i
= 0; i
< n
; i
++)
506 froom(int n
, int theitem
, int arg
)
509 fillroom(theitem
, arg
);
513 subroutine to put an object into an empty room
532 c
[RANDOMWALK
]++;/* count up these random walks */
551 subroutine to put monsters into an empty room without walls or other
559 for (trys
= 5; trys
> 0; --trys
) { /* max # of creation attempts */
562 if ((item
[x
][y
] == 0) && (mitem
[x
][y
] == 0) && ((playerx
!= x
) || (playery
!= y
))) {
565 hitp
[x
][y
] = monster
[what
].hitpoints
;
569 return (-1); /* creation failure */
573 creates an entire set of monsters for a level
574 must be done when entering a new level
575 if sethp(1) then wipe out old monsters else leave them there
583 for (i
= 0; i
< MAXY
; i
++)
584 for (j
= 0; j
< MAXX
; j
++)
589 } /* if teleported and found level 1 then know
592 j
= rnd(12) + 2 + (level
>> 1);
594 j
= (level
>> 1) + 1;
595 for (i
= 0; i
< j
; i
++)
596 fillmonst(makemonst(level
));
601 * Function to destroy all genocided monsters on the present level
607 for (y
= 0; y
< MAXY
; y
++)
608 for (x
= 0; x
< MAXX
; x
++)
609 if (monster
[mitem
[x
][y
]].genocided
)
610 mitem
[x
][y
] = 0; /* no more monster */