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 */