]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - larn/create.c
1 /* $NetBSD: create.c,v 1.12 2012/06/19 05:30:43 dholland Exp $ */
3 /* create.c Larn is copyrighted 1986 by Noah Morgan. */
7 __RCSID("$NetBSD: create.c,v 1.12 2012/06/19 05:30:43 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.
79 savelevel(); /* put the level back into storage */
80 level
= x
; /* get the new level and put in working
89 /* fill in new level */
90 for (i
= 0; i
< MAXY
; i
++)
91 for (j
= 0; j
< MAXX
; j
++)
92 know
[j
][i
] = mitem
[j
][i
] = 0;
97 checkgen(); /* wipe out any genocided monsters */
100 if (wizard
|| x
== 0)
104 for (j
= 0; j
< MAXY
; j
++)
105 for (i
= 0; i
< MAXX
; i
++)
113 subroutine to make the caverns for a given level. only walls are made.
115 static int mx
, mxl
, mxh
, my
, myl
, myh
, tmp2
;
122 if (k
> 1 && (rnd(17) <= 4 || k
== MAXLEVEL
- 1 || k
== MAXLEVEL
+ MAXVLEVEL
- 1)) {
124 return; /* read maze from data file */
130 for (i
= 0; i
< MAXY
; i
++)
131 for (j
= 0; j
< MAXX
; j
++)
137 item
[33][MAXY
- 1] = 0; /* exit from dungeon */
139 /* now for open spaces -- not on level 10 */
140 if (k
!= MAXLEVEL
- 1) {
142 for (tmp
= 0; tmp
< tmp2
; tmp
++) {
149 mxh
= mx
+ rnd(12) + 3;
157 for (i
= mxl
; i
< mxh
; i
++)
158 for (j
= myl
; j
< myh
; j
++) {
160 if ((mitem
[i
][j
] = z
))
161 hitp
[i
][j
] = monster
[z
].hitpoints
;
165 if (k
!= MAXLEVEL
- 1) {
167 for (i
= 1; i
< MAXX
- 1; i
++)
175 function to eat away a filled in maze
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
+ 1][yy
] != OWALL
) || (item
[xx
+ 2][yy
] != OWALL
))
199 item
[xx
+ 1][yy
] = item
[xx
+ 2][yy
] = 0;
206 if ((item
[xx
][yy
- 1] != OWALL
) || (item
[xx
][yy
- 2] != OWALL
))
208 item
[xx
][yy
- 1] = item
[xx
][yy
- 2] = 0;
215 if ((item
[xx
][yy
+ 1] != OWALL
) || (item
[xx
][yy
+ 2] != OWALL
))
217 item
[xx
][yy
+ 1] = item
[xx
][yy
+ 2] = 0;
229 * function to read in a maze from a data file
231 * Format of maze data file: 1st character = # of mazes in file (ascii digit)
232 * For each maze: 18 lines (1st 17 used) 67 characters per line
234 * Special characters in maze data file:
236 * # wall D door . random monster
237 * ~ eye of larn ! cure dianthroritis
245 int it
, arg
, mit
, marg
;
246 if (lopen(larnlevels
) < 0) {
247 write(1, "Can't open the maze data file\n", 30);
256 for (i
= 18 * rund(i
- '0'); i
> 0; i
--)
257 lgetl(); /* advance to desired maze */
258 for (i
= 0; i
< MAXY
; i
++) {
260 for (j
= 0; j
< MAXX
; j
++) {
261 it
= mit
= arg
= marg
= 0;
271 if (k
!= MAXLEVEL
- 1)
274 mit
= rund(8) + DEMONLORD
;
275 marg
= monster
[mit
].hitpoints
;
278 if (k
!= MAXLEVEL
+ MAXVLEVEL
- 1)
283 marg
= monster
[mit
].hitpoints
;
288 mit
= makemonst(k
+ 1);
289 marg
= monster
[mit
].hitpoints
;
292 it
= newobject(k
+ 1, &arg
);
301 know
[j
][i
] = (wizard
) ? 1 : 0;
312 function to make a treasure room on a level
313 level 10's treasure room has the eye in it and demon lords
314 level V3 has potion of cure dianthroritis and demon prince
319 int tx
, ty
, xsize
, ysize
;
321 for (tx
= 1 + rnd(10); tx
< MAXX
- 10; tx
+= 10)
322 if ((lv
== MAXLEVEL
- 1) || (lv
== MAXLEVEL
+ MAXVLEVEL
- 1) || rnd(13) == 2) {
325 ty
= rnd(MAXY
- 9) + 1; /* upper left corner of room */
326 if (lv
== MAXLEVEL
- 1 || lv
== MAXLEVEL
+ MAXVLEVEL
- 1)
327 troom(lv
, xsize
, ysize
, tx
= tx
+ rnd(MAXX
- 24), ty
, rnd(3) + 6);
329 troom(lv
, xsize
, ysize
, tx
, ty
, rnd(9));
334 * subroutine to create a treasure room of any size at a given location
335 * room is filled with objects and monsters
336 * the coordinate given is that of the upper left corner of the room
339 troom(int lv
, int xsize
, int ysize
, int tx
, int ty
, int glyph
)
343 for (j
= ty
- 1; j
<= ty
+ ysize
; j
++)
344 for (i
= tx
- 1; i
<= tx
+ xsize
; i
++) /* clear out space for
347 for (j
= ty
; j
< ty
+ ysize
; j
++)
348 for (i
= tx
; i
< tx
+ xsize
; i
++) { /* now put in the walls */
352 for (j
= ty
+ 1; j
< ty
+ ysize
- 1; j
++)
353 for (i
= tx
+ 1; i
< tx
+ xsize
- 1; i
++) /* now clear out
357 switch (rnd(2)) { /* locate the door on the treasure room */
359 item
[i
= tx
+ rund(xsize
)][j
= ty
+ (ysize
- 1) * rund(2)] = OCLOSEDDOOR
;
360 iarg
[i
][j
] = glyph
; /* on horizontal walls */
363 item
[i
= tx
+ (xsize
- 1) * rund(2)][j
= ty
+ rund(ysize
)] = OCLOSEDDOOR
;
364 iarg
[i
][j
] = glyph
; /* on vertical walls */
370 playery
= ty
+ (ysize
>> 1);
372 for (playerx
= tx
+ 1; playerx
<= tx
+ xsize
- 2; playerx
+= 2)
373 for (i
= 0, j
= rnd(6); i
<= j
; i
++) {
375 createmonster(makemonst(lv
+ 1));
378 for (playerx
= tx
+ 1; playerx
<= tx
+ xsize
- 2; playerx
+= 2)
379 for (i
= 0, j
= rnd(4); i
<= j
; i
++) {
381 createmonster(makemonst(lv
+ 3));
393 subroutine to create the objects in the maze for the given level
400 fillroom(OENTRANCE
, 0); /* entrance to dungeon */
401 fillroom(ODNDSTORE
, 0); /* the DND STORE */
402 fillroom(OSCHOOL
, 0); /* college of Larn */
403 fillroom(OBANK
, 0); /* 1st national bank of larn */
404 fillroom(OVOLDOWN
, 0); /* volcano shaft to temple */
405 fillroom(OHOME
, 0); /* the players home & family */
406 fillroom(OTRADEPOST
, 0); /* the trading post */
407 fillroom(OLRS
, 0); /* the larn revenue service */
411 fillroom(OVOLUP
, 0); /* volcano shaft up from the temple */
413 /* make the fixed objects in the maze STAIRS */
414 if ((j
> 0) && (j
!= MAXLEVEL
- 1) && (j
!= MAXLEVEL
+ MAXVLEVEL
- 1))
415 fillroom(OSTAIRSDOWN
, 0);
416 if ((j
> 1) && (j
!= MAXLEVEL
))
417 fillroom(OSTAIRSUP
, 0);
419 /* make the random objects in the maze */
421 fillmroom(rund(3), OBOOK
, j
);
422 fillmroom(rund(3), OALTAR
, 0);
423 fillmroom(rund(3), OSTATUE
, 0);
424 fillmroom(rund(3), OPIT
, 0);
425 fillmroom(rund(3), OFOUNTAIN
, 0);
426 fillmroom(rnd(3) - 2, OIVTELETRAP
, 0);
427 fillmroom(rund(2), OTHRONE
, 0);
428 fillmroom(rund(2), OMIRROR
, 0);
429 fillmroom(rund(2), OTRAPARROWIV
, 0);
430 fillmroom(rnd(3) - 2, OIVDARTRAP
, 0);
431 fillmroom(rund(3), OCOOKIE
, 0);
433 fillmroom(1, OCHEST
, j
);
435 fillmroom(rund(2), OCHEST
, j
);
436 if ((j
!= MAXLEVEL
- 1) && (j
!= MAXLEVEL
+ MAXVLEVEL
- 1))
437 fillmroom(rund(2), OIVTRAPDOOR
, 0);
439 fillmroom((rund(2)), ODIAMOND
, rnd(10 * j
+ 1) + 10);
440 fillmroom(rund(2), ORUBY
, rnd(6 * j
+ 1) + 6);
441 fillmroom(rund(2), OEMERALD
, rnd(4 * j
+ 1) + 4);
442 fillmroom(rund(2), OSAPPHIRE
, rnd(3 * j
+ 1) + 2);
444 for (i
= 0; i
< rnd(4) + 3; i
++)
445 fillroom(OPOTION
, newpotion()); /* make a POTION */
446 for (i
= 0; i
< rnd(5) + 3; i
++)
447 fillroom(OSCROLL
, newscroll()); /* make a SCROLL */
448 for (i
= 0; i
< rnd(12) + 11; i
++)
449 fillroom(OGOLDPILE
, 12 * rnd(j
+ 1) + (j
<< 3) + 10); /* make GOLD */
451 fillroom(OBANK2
, 0); /* branch office of the bank */
452 froom(2, ORING
, 0); /* a ring mail */
453 froom(1, OSTUDLEATHER
, 0); /* a studded leather */
454 froom(3, OSPLINT
, 0); /* a splint mail */
455 froom(5, OSHIELD
, rund(3)); /* a shield */
456 froom(2, OBATTLEAXE
, rund(3)); /* a battle axe */
457 froom(5, OLONGSWORD
, rund(3)); /* a long sword */
458 froom(5, OFLAIL
, rund(3)); /* a flail */
459 froom(4, OREGENRING
, rund(3)); /* ring of regeneration */
460 froom(1, OPROTRING
, rund(3)); /* ring of protection */
461 froom(2, OSTRRING
, 4); /* ring of strength + 4 */
462 froom(7, OSPEAR
, rnd(5)); /* a spear */
463 froom(3, OORBOFDRAGON
, 0); /* orb of dragon slaying */
464 froom(4, OSPIRITSCARAB
, 0); /* scarab of negate spirit */
465 froom(4, OCUBEofUNDEAD
, 0); /* cube of undead control */
466 froom(2, ORINGOFEXTRA
, 0); /* ring of extra regen */
467 froom(3, ONOTHEFT
, 0); /* device of antitheft */
468 froom(2, OSWORDofSLASHING
, 0); /* sword of slashing */
469 if (c
[BESSMANN
] == 0) {
470 froom(4, OHAMMER
, 0); /* Bessman's flailing hammer */
473 if (c
[HARDGAME
] < 3 || (rnd(4) == 3)) {
475 froom(3, OSWORD
, 3); /* sunsword + 3 */
476 froom(5, O2SWORD
, rnd(4)); /* a two handed sword */
477 froom(3, OBELT
, 4); /* belt of striking */
478 froom(3, OENERGYRING
, 3); /* energy ring */
479 froom(4, OPLATE
, 5); /* platemail + 5 */
485 subroutine to fill in a number of objects of the same kind
489 fillmroom(int n
, int what_i
, int arg
)
494 /* truncate to char width (just in case it matters) */
496 for (i
= 0; i
< n
; i
++)
501 froom(int n
, int theitem
, int arg
)
504 fillroom(theitem
, arg
);
508 subroutine to put an object into an empty room
512 fillroom(int what_i
, int arg
)
517 /* truncate to char width (just in case it matters) */
529 c
[RANDOMWALK
]++;/* count up these random walks */
548 subroutine to put monsters into an empty room without walls or other
555 for (trys
= 5; trys
> 0; --trys
) { /* max # of creation attempts */
558 if ((item
[x
][y
] == 0) && (mitem
[x
][y
] == 0) && ((playerx
!= x
) || (playery
!= y
))) {
561 hitp
[x
][y
] = monster
[what
].hitpoints
;
565 return (-1); /* creation failure */
569 creates an entire set of monsters for a level
570 must be done when entering a new level
571 if sethp(1) then wipe out old monsters else leave them there
578 for (i
= 0; i
< MAXY
; i
++)
579 for (j
= 0; j
< MAXX
; j
++)
584 } /* if teleported and found level 1 then know
587 j
= rnd(12) + 2 + (level
>> 1);
589 j
= (level
>> 1) + 1;
590 for (i
= 0; i
< j
; i
++)
591 fillmonst(makemonst(level
));
596 * Function to destroy all genocided monsters on the present level
602 for (y
= 0; y
< MAXY
; y
++)
603 for (x
= 0; x
< MAXX
; x
++)
604 if (monster
[mitem
[x
][y
]].genocided
)
605 mitem
[x
][y
] = 0; /* no more monster */