]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - larn/create.c
1 /* $NetBSD: create.c,v 1.8 2005/02/25 15:04:43 simonb Exp $ */
3 /* create.c Larn is copyrighted 1986 by Noah Morgan. */
7 __RCSID("$NetBSD: create.c,v 1.8 2005/02/25 15:04:43 simonb Exp $");
13 static void fillroom(int, int);
18 subroutine to create the player and the players attributes
19 this is called at the beginning of a game and at no other time
27 c
[HPMAX
] = c
[HP
] = 10; /* start player off with 15 hit points */
28 c
[LEVEL
] = 1; /* player starts at level one */
29 c
[SPELLMAX
] = c
[SPELLS
] = 1; /* total # spells starts off as 3 */
31 c
[ECOUNTER
] = 96; /* start regeneration correctly */
32 c
[SHIELD
] = c
[WEAR
] = c
[WIELD
] = -1;
33 for (i
= 0; i
< 26; i
++)
35 spelknow
[0] = spelknow
[1] = 1; /* he knows protection, magic missile */
36 if (c
[HARDGAME
] <= 0) {
39 ivenarg
[1] = ivenarg
[0] = c
[WEAR
] = 0;
42 playerx
= rnd(MAXX
- 2);
43 playery
= rnd(MAXY
- 2);
46 gltime
= 0; /* time clock starts at zero */
48 for (i
= 0; i
< 6; i
++)
49 c
[i
] = 12; /* make the attributes, ie str, int, etc. */
58 function to enter a new level. This routine must be called anytime the
59 player changes levels. If that level is unknown it will be created.
60 A new set of monsters will be created for a new level, and existing
61 levels will get a few more monsters.
62 Note that it is here we remove genocided monsters from the present level.
70 savelevel(); /* put the level back into storage */
71 level
= x
; /* get the new level and put in working
74 for (i
= 0; i
< MAXY
; i
++)
75 for (j
= 0; j
< MAXX
; j
++)
76 know
[j
][i
] = mitem
[j
][i
] = 0;
93 for (j
= 0; j
< MAXY
; j
++)
94 for (i
= 0; i
< MAXX
; i
++)
96 chgn
: checkgen(); /* wipe out any genocided monsters */
103 subroutine to make the caverns for a given level. only walls are made.
105 static int mx
, mxl
, mxh
, my
, myl
, myh
, tmp2
;
112 if (k
> 1 && (rnd(17) <= 4 || k
== MAXLEVEL
- 1 || k
== MAXLEVEL
+ MAXVLEVEL
- 1)) {
114 return; /* read maze from data file */
120 for (i
= 0; i
< MAXY
; i
++)
121 for (j
= 0; j
< MAXX
; j
++)
127 item
[33][MAXY
- 1] = 0; /* exit from dungeon */
129 /* now for open spaces -- not on level 10 */
130 if (k
!= MAXLEVEL
- 1) {
132 for (tmp
= 0; tmp
< tmp2
; tmp
++) {
139 mxh
= mx
+ rnd(12) + 3;
147 for (i
= mxl
; i
< mxh
; i
++)
148 for (j
= myl
; j
< myh
; j
++) {
150 if ((mitem
[i
][j
] = z
))
151 hitp
[i
][j
] = monster
[z
].hitpoints
;
155 if (k
!= MAXLEVEL
- 1) {
157 for (i
= 1; i
< MAXX
- 1; i
++)
165 function to eat away a filled in maze
179 if ((item
[xx
- 1][yy
] != OWALL
) || (item
[xx
- 2][yy
] != OWALL
))
181 item
[xx
- 1][yy
] = item
[xx
- 2][yy
] = 0;
188 if ((item
[xx
+ 1][yy
] != OWALL
) || (item
[xx
+ 2][yy
] != OWALL
))
190 item
[xx
+ 1][yy
] = item
[xx
+ 2][yy
] = 0;
197 if ((item
[xx
][yy
- 1] != OWALL
) || (item
[xx
][yy
- 2] != OWALL
))
199 item
[xx
][yy
- 1] = item
[xx
][yy
- 2] = 0;
206 if ((item
[xx
][yy
+ 1] != OWALL
) || (item
[xx
][yy
+ 2] != OWALL
))
208 item
[xx
][yy
+ 1] = item
[xx
][yy
+ 2] = 0;
220 * function to read in a maze from a data file
222 * Format of maze data file: 1st character = # of mazes in file (ascii digit)
223 * For each maze: 18 lines (1st 17 used) 67 characters per line
225 * Special characters in maze data file:
227 * # wall D door . random monster
228 * ~ eye of larn ! cure dianthroritis
237 int it
, arg
, mit
, marg
;
238 if (lopen(larnlevels
) < 0) {
239 write(1, "Can't open the maze data file\n", 30);
248 for (i
= 18 * rund(i
- '0'); i
> 0; i
--)
249 lgetl(); /* advance to desired maze */
250 for (i
= 0; i
< MAXY
; i
++) {
252 for (j
= 0; j
< MAXX
; j
++) {
253 it
= mit
= arg
= marg
= 0;
263 if (k
!= MAXLEVEL
- 1)
266 mit
= rund(8) + DEMONLORD
;
267 marg
= monster
[mit
].hitpoints
;
270 if (k
!= MAXLEVEL
+ MAXVLEVEL
- 1)
275 marg
= monster
[mit
].hitpoints
;
280 mit
= makemonst(k
+ 1);
281 marg
= monster
[mit
].hitpoints
;
284 it
= newobject(k
+ 1, &arg
);
293 know
[j
][i
] = (wizard
) ? 1 : 0;
304 function to make a treasure room on a level
305 level 10's treasure room has the eye in it and demon lords
306 level V3 has potion of cure dianthroritis and demon prince
312 int tx
, ty
, xsize
, ysize
;
314 for (tx
= 1 + rnd(10); tx
< MAXX
- 10; tx
+= 10)
315 if ((lv
== MAXLEVEL
- 1) || (lv
== MAXLEVEL
+ MAXVLEVEL
- 1) || rnd(13) == 2) {
318 ty
= rnd(MAXY
- 9) + 1; /* upper left corner of room */
319 if (lv
== MAXLEVEL
- 1 || lv
== MAXLEVEL
+ MAXVLEVEL
- 1)
320 troom(lv
, xsize
, ysize
, tx
= tx
+ rnd(MAXX
- 24), ty
, rnd(3) + 6);
322 troom(lv
, xsize
, ysize
, tx
, ty
, rnd(9));
327 * subroutine to create a treasure room of any size at a given location
328 * room is filled with objects and monsters
329 * the coordinate given is that of the upper left corner of the room
332 troom(lv
, xsize
, ysize
, tx
, ty
, glyph
)
333 int lv
, xsize
, ysize
, tx
, ty
, glyph
;
337 for (j
= ty
- 1; j
<= ty
+ ysize
; j
++)
338 for (i
= tx
- 1; i
<= tx
+ xsize
; i
++) /* clear out space for
341 for (j
= ty
; j
< ty
+ ysize
; j
++)
342 for (i
= tx
; i
< tx
+ xsize
; i
++) { /* now put in the walls */
346 for (j
= ty
+ 1; j
< ty
+ ysize
- 1; j
++)
347 for (i
= tx
+ 1; i
< tx
+ xsize
- 1; i
++) /* now clear out
351 switch (rnd(2)) { /* locate the door on the treasure room */
353 item
[i
= tx
+ rund(xsize
)][j
= ty
+ (ysize
- 1) * rund(2)] = OCLOSEDDOOR
;
354 iarg
[i
][j
] = glyph
; /* on horizontal walls */
357 item
[i
= tx
+ (xsize
- 1) * rund(2)][j
= ty
+ rund(ysize
)] = OCLOSEDDOOR
;
358 iarg
[i
][j
] = glyph
; /* on vertical walls */
364 playery
= ty
+ (ysize
>> 1);
366 for (playerx
= tx
+ 1; playerx
<= tx
+ xsize
- 2; playerx
+= 2)
367 for (i
= 0, j
= rnd(6); i
<= j
; i
++) {
369 createmonster(makemonst(lv
+ 1));
372 for (playerx
= tx
+ 1; playerx
<= tx
+ xsize
- 2; playerx
+= 2)
373 for (i
= 0, j
= rnd(4); i
<= j
; i
++) {
375 createmonster(makemonst(lv
+ 3));
387 subroutine to create the objects in the maze for the given level
395 fillroom(OENTRANCE
, 0); /* entrance to dungeon */
396 fillroom(ODNDSTORE
, 0); /* the DND STORE */
397 fillroom(OSCHOOL
, 0); /* college of Larn */
398 fillroom(OBANK
, 0); /* 1st national bank of larn */
399 fillroom(OVOLDOWN
, 0); /* volcano shaft to temple */
400 fillroom(OHOME
, 0); /* the players home & family */
401 fillroom(OTRADEPOST
, 0); /* the trading post */
402 fillroom(OLRS
, 0); /* the larn revenue service */
406 fillroom(OVOLUP
, 0); /* volcano shaft up from the temple */
408 /* make the fixed objects in the maze STAIRS */
409 if ((j
> 0) && (j
!= MAXLEVEL
- 1) && (j
!= MAXLEVEL
+ MAXVLEVEL
- 1))
410 fillroom(OSTAIRSDOWN
, 0);
411 if ((j
> 1) && (j
!= MAXLEVEL
))
412 fillroom(OSTAIRSUP
, 0);
414 /* make the random objects in the maze */
416 fillmroom(rund(3), OBOOK
, j
);
417 fillmroom(rund(3), OALTAR
, 0);
418 fillmroom(rund(3), OSTATUE
, 0);
419 fillmroom(rund(3), OPIT
, 0);
420 fillmroom(rund(3), OFOUNTAIN
, 0);
421 fillmroom(rnd(3) - 2, OIVTELETRAP
, 0);
422 fillmroom(rund(2), OTHRONE
, 0);
423 fillmroom(rund(2), OMIRROR
, 0);
424 fillmroom(rund(2), OTRAPARROWIV
, 0);
425 fillmroom(rnd(3) - 2, OIVDARTRAP
, 0);
426 fillmroom(rund(3), OCOOKIE
, 0);
428 fillmroom(1, OCHEST
, j
);
430 fillmroom(rund(2), OCHEST
, j
);
431 if ((j
!= MAXLEVEL
- 1) && (j
!= MAXLEVEL
+ MAXVLEVEL
- 1))
432 fillmroom(rund(2), OIVTRAPDOOR
, 0);
434 fillmroom((rund(2)), ODIAMOND
, rnd(10 * j
+ 1) + 10);
435 fillmroom(rund(2), ORUBY
, rnd(6 * j
+ 1) + 6);
436 fillmroom(rund(2), OEMERALD
, rnd(4 * j
+ 1) + 4);
437 fillmroom(rund(2), OSAPPHIRE
, rnd(3 * j
+ 1) + 2);
439 for (i
= 0; i
< rnd(4) + 3; i
++)
440 fillroom(OPOTION
, newpotion()); /* make a POTION */
441 for (i
= 0; i
< rnd(5) + 3; i
++)
442 fillroom(OSCROLL
, newscroll()); /* make a SCROLL */
443 for (i
= 0; i
< rnd(12) + 11; i
++)
444 fillroom(OGOLDPILE
, 12 * rnd(j
+ 1) + (j
<< 3) + 10); /* make GOLD */
446 fillroom(OBANK2
, 0); /* branch office of the bank */
447 froom(2, ORING
, 0); /* a ring mail */
448 froom(1, OSTUDLEATHER
, 0); /* a studded leather */
449 froom(3, OSPLINT
, 0); /* a splint mail */
450 froom(5, OSHIELD
, rund(3)); /* a shield */
451 froom(2, OBATTLEAXE
, rund(3)); /* a battle axe */
452 froom(5, OLONGSWORD
, rund(3)); /* a long sword */
453 froom(5, OFLAIL
, rund(3)); /* a flail */
454 froom(4, OREGENRING
, rund(3)); /* ring of regeneration */
455 froom(1, OPROTRING
, rund(3)); /* ring of protection */
456 froom(2, OSTRRING
, 4); /* ring of strength + 4 */
457 froom(7, OSPEAR
, rnd(5)); /* a spear */
458 froom(3, OORBOFDRAGON
, 0); /* orb of dragon slaying */
459 froom(4, OSPIRITSCARAB
, 0); /* scarab of negate spirit */
460 froom(4, OCUBEofUNDEAD
, 0); /* cube of undead control */
461 froom(2, ORINGOFEXTRA
, 0); /* ring of extra regen */
462 froom(3, ONOTHEFT
, 0); /* device of antitheft */
463 froom(2, OSWORDofSLASHING
, 0); /* sword of slashing */
464 if (c
[BESSMANN
] == 0) {
465 froom(4, OHAMMER
, 0); /* Bessman's flailing hammer */
468 if (c
[HARDGAME
] < 3 || (rnd(4) == 3)) {
470 froom(3, OSWORD
, 3); /* sunsword + 3 */
471 froom(5, O2SWORD
, rnd(4)); /* a two handed sword */
472 froom(3, OBELT
, 4); /* belt of striking */
473 froom(3, OENERGYRING
, 3); /* energy ring */
474 froom(4, OPLATE
, 5); /* platemail + 5 */
480 subroutine to fill in a number of objects of the same kind
484 fillmroom(n
, what
, arg
)
489 for (i
= 0; i
< n
; i
++)
502 subroutine to put an object into an empty room
521 c
[RANDOMWALK
]++;/* count up these random walks */
540 subroutine to put monsters into an empty room without walls or other
548 for (trys
= 5; trys
> 0; --trys
) { /* max # of creation attempts */
551 if ((item
[x
][y
] == 0) && (mitem
[x
][y
] == 0) && ((playerx
!= x
) || (playery
!= y
))) {
554 hitp
[x
][y
] = monster
[what
].hitpoints
;
558 return (-1); /* creation failure */
562 creates an entire set of monsters for a level
563 must be done when entering a new level
564 if sethp(1) then wipe out old monsters else leave them there
572 for (i
= 0; i
< MAXY
; i
++)
573 for (j
= 0; j
< MAXX
; j
++)
578 } /* if teleported and found level 1 then know
581 j
= rnd(12) + 2 + (level
>> 1);
583 j
= (level
>> 1) + 1;
584 for (i
= 0; i
< j
; i
++)
585 fillmonst(makemonst(level
));
590 * Function to destroy all genocided monsters on the present level
596 for (y
= 0; y
< MAXY
; y
++)
597 for (x
= 0; x
< MAXX
; x
++)
598 if (monster
[mitem
[x
][y
]].genocided
)
599 mitem
[x
][y
] = 0; /* no more monster */