]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - larn/create.c
2 static char rcsid
[] = "$NetBSD: create.c,v 1.4 1997/03/29 20:42:17 thorpej Exp $";
5 /* create.c Larn is copyrighted 1986 by Noah Morgan. */
7 extern char spelknow
[],larnlevels
[];
8 extern char beenhere
[],wizard
;
10 extern short oldx
,oldy
;
14 subroutine to create the player and the players attributes
15 this is called at the beginning of a game and at no other time
21 c
[HPMAX
]=c
[HP
]=10; /* start player off with 15 hit points */
22 c
[LEVEL
]=1; /* player starts at level one */
23 c
[SPELLMAX
]=c
[SPELLS
]=1; /* total # spells starts off as 3 */
24 c
[REGENCOUNTER
]=16; c
[ECOUNTER
]=96; /*start regeneration correctly*/
25 c
[SHIELD
] = c
[WEAR
] = c
[WIELD
] = -1;
26 for (i
=0; i
<26; i
++) iven
[i
]=0;
27 spelknow
[0]=spelknow
[1]=1; /*he knows protection, magic missile*/
30 iven
[0]=OLEATHER
; iven
[1]=ODAGGER
;
31 ivenarg
[1]=ivenarg
[0]=c
[WEAR
]=0; c
[WIELD
]=1;
33 playerx
=rnd(MAXX
-2); playery
=rnd(MAXY
-2);
35 gtime
=0; /* time clock starts at zero */
37 for (i
=0; i
<6; i
++) c
[i
]=12; /* make the attributes, ie str, int, etc. */
45 function to enter a new level. This routine must be called anytime the
46 player changes levels. If that level is unknown it will be created.
47 A new set of monsters will be created for a new level, and existing
48 levels will get a few more monsters.
49 Note that it is here we remove genocided monsters from the present level.
55 if (beenhere
[level
]) savelevel(); /* put the level back into storage */
56 level
= x
; /* get the new level and put in working storage */
57 if (beenhere
[x
]==0) for (i
=0; i
<MAXY
; i
++) for (j
=0; j
<MAXX
; j
++) know
[j
][i
]=mitem
[j
][i
]=0;
58 else { getlevel(); sethp(0); goto chgn
; }
59 makemaze(x
); makeobject(x
); beenhere
[x
]=1; sethp(1);
67 for (j
=0; j
<MAXY
; j
++)
68 for (i
=0; i
<MAXX
; i
++)
70 chgn
: checkgen(); /* wipe out any genocided monsters */
77 subroutine to make the caverns for a given level. only walls are made.
79 static int mx
,mxl
,mxh
,my
,myl
,myh
,tmp2
;
85 if (k
> 1 && (rnd(17)<=4 || k
==MAXLEVEL
-1 || k
==MAXLEVEL
+MAXVLEVEL
-1))
87 if (cannedlevel(k
)); return; /* read maze from data file */
89 if (k
==0) tmp
=0; else tmp
=OWALL
;
90 for (i
=0; i
<MAXY
; i
++) for (j
=0; j
<MAXX
; j
++) item
[j
][i
]=tmp
;
91 if (k
==0) return; eat(1,1);
92 if (k
==1) item
[33][MAXY
-1]=0; /* exit from dungeon */
94 /* now for open spaces -- not on level 10 */
98 for (tmp
=0; tmp
<tmp2
; tmp
++)
100 my
= rnd(11)+2; myl
= my
- rnd(2); myh
= my
+ rnd(2);
103 mx
= rnd(44)+5; mxl
= mx
- rnd(4); mxh
= mx
+ rnd(12)+3;
108 mx
= rnd(60)+3; mxl
= mx
- rnd(2); mxh
= mx
+ rnd(2);
111 for (i
=mxl
; i
<mxh
; i
++) for (j
=myl
; j
<myh
; j
++)
113 if ((mitem
[i
][j
]=z
)) hitp
[i
][j
]=monster
[z
].hitpoints
;
117 if (k
!=MAXLEVEL
-1) { my
=rnd(MAXY
-2); for (i
=1; i
<MAXX
-1; i
++) item
[i
][my
] = 0; }
118 if (k
>1) treasureroom(k
);
122 function to eat away a filled in maze
127 register int dir
,try;
133 case 1: if (xx
<= 2) break; /* west */
134 if ((item
[xx
-1][yy
]!=OWALL
) || (item
[xx
-2][yy
]!=OWALL
)) break;
135 item
[xx
-1][yy
] = item
[xx
-2][yy
] = 0;
138 case 2: if (xx
>= MAXX
-3) break; /* east */
139 if ((item
[xx
+1][yy
]!=OWALL
) || (item
[xx
+2][yy
]!=OWALL
)) break;
140 item
[xx
+1][yy
] = item
[xx
+2][yy
] = 0;
143 case 3: if (yy
<= 2) break; /* south */
144 if ((item
[xx
][yy
-1]!=OWALL
) || (item
[xx
][yy
-2]!=OWALL
)) break;
145 item
[xx
][yy
-1] = item
[xx
][yy
-2] = 0;
148 case 4: if (yy
>= MAXY
-3 ) break; /* north */
149 if ((item
[xx
][yy
+1]!=OWALL
) || (item
[xx
][yy
+2]!=OWALL
)) break;
150 item
[xx
][yy
+1] = item
[xx
][yy
+2] = 0;
153 if (++dir
> 4) { dir
=1; --try; }
158 * function to read in a maze from a data file
160 * Format of maze data file: 1st character = # of mazes in file (ascii digit)
161 * For each maze: 18 lines (1st 17 used) 67 characters per line
163 * Special characters in maze data file:
165 * # wall D door . random monster
166 * ~ eye of larn ! cure dianthroritis
175 if (lopen(larnlevels
)<0)
177 write(1,"Can't open the maze data file\n",30); died(-282); return(0);
179 i
=lgetc(); if (i
<='0') { died(-282); return(0); }
180 for (i
=18*rund(i
-'0'); i
>0; i
--) lgetl(); /* advance to desired maze */
181 for (i
=0; i
<MAXY
; i
++)
184 for (j
=0; j
<MAXX
; j
++)
186 it
= mit
= arg
= marg
= 0;
189 case '#': it
= OWALL
; break;
190 case 'D': it
= OCLOSEDDOOR
; arg
= rnd(30); break;
191 case '~': if (k
!=MAXLEVEL
-1) break;
193 mit
= rund(8)+DEMONLORD
;
194 marg
= monster
[mit
].hitpoints
; break;
195 case '!': if (k
!=MAXLEVEL
+MAXVLEVEL
-1) break;
196 it
= OPOTION
; arg
= 21;
198 marg
= monster
[mit
].hitpoints
; break;
199 case '.': if (k
<MAXLEVEL
) break;
200 mit
= makemonst(k
+1);
201 marg
= monster
[mit
].hitpoints
; break;
202 case '-': it
= newobject(k
+1,&arg
); break;
204 item
[j
][i
] = it
; iarg
[j
][i
] = arg
;
205 mitem
[j
][i
] = mit
; hitp
[j
][i
] = marg
;
208 know
[j
][i
] = (wizard
) ? 1 : 0;
219 function to make a treasure room on a level
220 level 10's treasure room has the eye in it and demon lords
221 level V3 has potion of cure dianthroritis and demon prince
226 register int tx
,ty
,xsize
,ysize
;
228 for (tx
=1+rnd(10); tx
<MAXX
-10; tx
+=10)
229 if ( (lv
==MAXLEVEL
-1) || (lv
==MAXLEVEL
+MAXVLEVEL
-1) || rnd(13)==2)
231 xsize
= rnd(6)+3; ysize
= rnd(3)+3;
232 ty
= rnd(MAXY
-9)+1; /* upper left corner of room */
233 if (lv
==MAXLEVEL
-1 || lv
==MAXLEVEL
+MAXVLEVEL
-1)
234 troom(lv
,xsize
,ysize
,tx
=tx
+rnd(MAXX
-24),ty
,rnd(3)+6);
235 else troom(lv
,xsize
,ysize
,tx
,ty
,rnd(9));
240 * subroutine to create a treasure room of any size at a given location
241 * room is filled with objects and monsters
242 * the coordinate given is that of the upper left corner of the room
244 troom(lv
,xsize
,ysize
,tx
,ty
,glyph
)
245 int lv
,xsize
,ysize
,tx
,ty
,glyph
;
249 for (j
=ty
-1; j
<=ty
+ysize
; j
++)
250 for (i
=tx
-1; i
<=tx
+xsize
; i
++) /* clear out space for room */
252 for (j
=ty
; j
<ty
+ysize
; j
++)
253 for (i
=tx
; i
<tx
+xsize
; i
++) /* now put in the walls */
255 item
[i
][j
]=OWALL
; mitem
[i
][j
]=0;
257 for (j
=ty
+1; j
<ty
+ysize
-1; j
++)
258 for (i
=tx
+1; i
<tx
+xsize
-1; i
++) /* now clear out interior */
261 switch(rnd(2)) /* locate the door on the treasure room */
263 case 1: item
[i
=tx
+rund(xsize
)][j
=ty
+(ysize
-1)*rund(2)]=OCLOSEDDOOR
;
264 iarg
[i
][j
] = glyph
; /* on horizontal walls */
266 case 2: item
[i
=tx
+(xsize
-1)*rund(2)][j
=ty
+rund(ysize
)]=OCLOSEDDOOR
;
267 iarg
[i
][j
] = glyph
; /* on vertical walls */
271 tp1
=playerx
; tp2
=playery
; playery
=ty
+(ysize
>>1);
273 for (playerx
=tx
+1; playerx
<=tx
+xsize
-2; playerx
+=2)
274 for (i
=0, j
=rnd(6); i
<=j
; i
++)
275 { something(lv
+2); createmonster(makemonst(lv
+1)); }
277 for (playerx
=tx
+1; playerx
<=tx
+xsize
-2; playerx
+=2)
278 for (i
=0, j
=rnd(4); i
<=j
; i
++)
279 { something(lv
+2); createmonster(makemonst(lv
+3)); }
281 playerx
=tp1
; playery
=tp2
;
284 static void fillroom();
290 subroutine to create the objects in the maze for the given level
298 fillroom(OENTRANCE
,0); /* entrance to dungeon */
299 fillroom(ODNDSTORE
,0); /* the DND STORE */
300 fillroom(OSCHOOL
,0); /* college of Larn */
301 fillroom(OBANK
,0); /* 1st national bank of larn */
302 fillroom(OVOLDOWN
,0); /* volcano shaft to temple */
303 fillroom(OHOME
,0); /* the players home & family */
304 fillroom(OTRADEPOST
,0); /* the trading post */
305 fillroom(OLRS
,0); /* the larn revenue service */
309 if (j
==MAXLEVEL
) fillroom(OVOLUP
,0); /* volcano shaft up from the temple */
311 /* make the fixed objects in the maze STAIRS */
312 if ((j
>0) && (j
!= MAXLEVEL
-1) && (j
!= MAXLEVEL
+MAXVLEVEL
-1))
313 fillroom(OSTAIRSDOWN
,0);
314 if ((j
> 1) && (j
!= MAXLEVEL
)) fillroom(OSTAIRSUP
,0);
316 /* make the random objects in the maze */
318 fillmroom(rund(3),OBOOK
,j
); fillmroom(rund(3),OALTAR
,0);
319 fillmroom(rund(3),OSTATUE
,0); fillmroom(rund(3),OPIT
,0);
320 fillmroom(rund(3),OFOUNTAIN
,0); fillmroom( rnd(3)-2,OIVTELETRAP
,0);
321 fillmroom(rund(2),OTHRONE
,0); fillmroom(rund(2),OMIRROR
,0);
322 fillmroom(rund(2),OTRAPARROWIV
,0); fillmroom( rnd(3)-2,OIVDARTRAP
,0);
323 fillmroom(rund(3),OCOOKIE
,0);
324 if (j
==1) fillmroom(1,OCHEST
,j
);
325 else fillmroom(rund(2),OCHEST
,j
);
326 if ((j
!= MAXLEVEL
-1) && (j
!= MAXLEVEL
+MAXVLEVEL
-1))
327 fillmroom(rund(2),OIVTRAPDOOR
,0);
330 fillmroom((rund(2)),ODIAMOND
,rnd(10*j
+1)+10);
331 fillmroom(rund(2),ORUBY
,rnd(6*j
+1)+6);
332 fillmroom(rund(2),OEMERALD
,rnd(4*j
+1)+4);
333 fillmroom(rund(2),OSAPPHIRE
,rnd(3*j
+1)+2);
335 for (i
=0; i
<rnd(4)+3; i
++)
336 fillroom(OPOTION
,newpotion()); /* make a POTION */
337 for (i
=0; i
<rnd(5)+3; i
++)
338 fillroom(OSCROLL
,newscroll()); /* make a SCROLL */
339 for (i
=0; i
<rnd(12)+11; i
++)
340 fillroom(OGOLDPILE
,12*rnd(j
+1)+(j
<<3)+10); /* make GOLD */
341 if (j
==5) fillroom(OBANK2
,0); /* branch office of the bank */
342 froom(2,ORING
,0); /* a ring mail */
343 froom(1,OSTUDLEATHER
,0); /* a studded leather */
344 froom(3,OSPLINT
,0); /* a splint mail */
345 froom(5,OSHIELD
,rund(3)); /* a shield */
346 froom(2,OBATTLEAXE
,rund(3)); /* a battle axe */
347 froom(5,OLONGSWORD
,rund(3)); /* a long sword */
348 froom(5,OFLAIL
,rund(3)); /* a flail */
349 froom(4,OREGENRING
,rund(3)); /* ring of regeneration */
350 froom(1,OPROTRING
,rund(3)); /* ring of protection */
351 froom(2,OSTRRING
,4); /* ring of strength + 4 */
352 froom(7,OSPEAR
,rnd(5)); /* a spear */
353 froom(3,OORBOFDRAGON
,0); /* orb of dragon slaying*/
354 froom(4,OSPIRITSCARAB
,0); /*scarab of negate spirit*/
355 froom(4,OCUBEofUNDEAD
,0); /* cube of undead control */
356 froom(2,ORINGOFEXTRA
,0); /* ring of extra regen */
357 froom(3,ONOTHEFT
,0); /* device of antitheft */
358 froom(2,OSWORDofSLASHING
,0); /* sword of slashing */
361 froom(4,OHAMMER
,0);/*Bessman's flailing hammer*/ c
[BESSMANN
]=1;
363 if (c
[HARDGAME
]<3 || (rnd(4)==3))
367 froom(3,OSWORD
,3); /* sunsword + 3 */
368 froom(5,O2SWORD
,rnd(4)); /* a two handed sword */
369 froom(3,OBELT
,4); /* belt of striking */
370 froom(3,OENERGYRING
,3); /* energy ring */
371 froom(4,OPLATE
,5); /* platemail + 5 */
377 subroutine to fill in a number of objects of the same kind
380 fillmroom(n
,what
,arg
)
385 for (i
=0; i
<n
; i
++) fillroom(what
,arg
);
390 { if (rnd(151) < n
) fillroom(itm
,arg
); }
393 subroutine to put an object into an empty room
407 x
=rnd(MAXX
-2); y
=rnd(MAXY
-2);
412 c
[RANDOMWALK
]++; /* count up these random walks */
415 x
+= rnd(3)-2; y
+= rnd(3)-2;
416 if (x
> MAXX
-2) x
=1; if (x
< 1) x
=MAXX
-2;
417 if (y
> MAXY
-2) y
=1; if (y
< 1) y
=MAXY
-2;
419 item
[x
][y
]=what
; iarg
[x
][y
]=arg
;
423 subroutine to put monsters into an empty room without walls or other
429 register int x
,y
,trys
;
430 for (trys
=5; trys
>0; --trys
) /* max # of creation attempts */
432 x
=rnd(MAXX
-2); y
=rnd(MAXY
-2);
433 if ((item
[x
][y
]==0) && (mitem
[x
][y
]==0) && ((playerx
!=x
) || (playery
!=y
)))
435 mitem
[x
][y
] = what
; know
[x
][y
]=0;
436 hitp
[x
][y
] = monster
[what
].hitpoints
; return(0);
439 return(-1); /* creation failure */
443 creates an entire set of monsters for a level
444 must be done when entering a new level
445 if sethp(1) then wipe out old monsters else leave them there
451 if (flg
) for (i
=0; i
<MAXY
; i
++) for (j
=0; j
<MAXX
; j
++) stealth
[j
][i
]=0;
452 if (level
==0) { c
[TELEFLAG
]=0; return; } /* if teleported and found level 1 then know level we are on */
453 if (flg
) j
= rnd(12) + 2 + (level
>>1); else j
= (level
>>1) + 1;
454 for (i
=0; i
<j
; i
++) fillmonst(makemonst(level
));
459 * Function to destroy all genocided monsters on the present level
464 for (y
=0; y
<MAXY
; y
++)
465 for (x
=0; x
<MAXX
; x
++)
466 if (monster
[mitem
[x
][y
]].genocided
)
467 mitem
[x
][y
]=0; /* no more monster */