]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - larn/create.c
2 static char rcsid
[] = "$NetBSD: create.c,v 1.3 1995/03/23 08:33:14 cgd Exp $";
5 /* create.c Larn is copyrighted 1986 by Noah Morgan. */
7 extern char spelknow
[],larnlevels
[];
8 extern char beenhere
[],wizard
,level
;
9 extern short oldx
,oldy
;
13 subroutine to create the player and the players attributes
14 this is called at the beginning of a game and at no other time
20 c
[HPMAX
]=c
[HP
]=10; /* start player off with 15 hit points */
21 c
[LEVEL
]=1; /* player starts at level one */
22 c
[SPELLMAX
]=c
[SPELLS
]=1; /* total # spells starts off as 3 */
23 c
[REGENCOUNTER
]=16; c
[ECOUNTER
]=96; /*start regeneration correctly*/
24 c
[SHIELD
] = c
[WEAR
] = c
[WIELD
] = -1;
25 for (i
=0; i
<26; i
++) iven
[i
]=0;
26 spelknow
[0]=spelknow
[1]=1; /*he knows protection, magic missile*/
29 iven
[0]=OLEATHER
; iven
[1]=ODAGGER
;
30 ivenarg
[1]=ivenarg
[0]=c
[WEAR
]=0; c
[WIELD
]=1;
32 playerx
=rnd(MAXX
-2); playery
=rnd(MAXY
-2);
34 gtime
=0; /* time clock starts at zero */
36 for (i
=0; i
<6; i
++) c
[i
]=12; /* make the attributes, ie str, int, etc. */
44 function to enter a new level. This routine must be called anytime the
45 player changes levels. If that level is unknown it will be created.
46 A new set of monsters will be created for a new level, and existing
47 levels will get a few more monsters.
48 Note that it is here we remove genocided monsters from the present level.
54 if (beenhere
[level
]) savelevel(); /* put the level back into storage */
55 level
= x
; /* get the new level and put in working storage */
56 if (beenhere
[x
]==0) for (i
=0; i
<MAXY
; i
++) for (j
=0; j
<MAXX
; j
++) know
[j
][i
]=mitem
[j
][i
]=0;
57 else { getlevel(); sethp(0); goto chgn
; }
58 makemaze(x
); makeobject(x
); beenhere
[x
]=1; sethp(1);
66 for (j
=0; j
<MAXY
; j
++)
67 for (i
=0; i
<MAXX
; i
++)
69 chgn
: checkgen(); /* wipe out any genocided monsters */
76 subroutine to make the caverns for a given level. only walls are made.
78 static int mx
,mxl
,mxh
,my
,myl
,myh
,tmp2
;
84 if (k
> 1 && (rnd(17)<=4 || k
==MAXLEVEL
-1 || k
==MAXLEVEL
+MAXVLEVEL
-1))
86 if (cannedlevel(k
)); return; /* read maze from data file */
88 if (k
==0) tmp
=0; else tmp
=OWALL
;
89 for (i
=0; i
<MAXY
; i
++) for (j
=0; j
<MAXX
; j
++) item
[j
][i
]=tmp
;
90 if (k
==0) return; eat(1,1);
91 if (k
==1) item
[33][MAXY
-1]=0; /* exit from dungeon */
93 /* now for open spaces -- not on level 10 */
97 for (tmp
=0; tmp
<tmp2
; tmp
++)
99 my
= rnd(11)+2; myl
= my
- rnd(2); myh
= my
+ rnd(2);
102 mx
= rnd(44)+5; mxl
= mx
- rnd(4); mxh
= mx
+ rnd(12)+3;
107 mx
= rnd(60)+3; mxl
= mx
- rnd(2); mxh
= mx
+ rnd(2);
110 for (i
=mxl
; i
<mxh
; i
++) for (j
=myl
; j
<myh
; j
++)
112 if ((mitem
[i
][j
]=z
)) hitp
[i
][j
]=monster
[z
].hitpoints
;
116 if (k
!=MAXLEVEL
-1) { my
=rnd(MAXY
-2); for (i
=1; i
<MAXX
-1; i
++) item
[i
][my
] = 0; }
117 if (k
>1) treasureroom(k
);
121 function to eat away a filled in maze
126 register int dir
,try;
132 case 1: if (xx
<= 2) break; /* west */
133 if ((item
[xx
-1][yy
]!=OWALL
) || (item
[xx
-2][yy
]!=OWALL
)) break;
134 item
[xx
-1][yy
] = item
[xx
-2][yy
] = 0;
137 case 2: if (xx
>= MAXX
-3) break; /* east */
138 if ((item
[xx
+1][yy
]!=OWALL
) || (item
[xx
+2][yy
]!=OWALL
)) break;
139 item
[xx
+1][yy
] = item
[xx
+2][yy
] = 0;
142 case 3: if (yy
<= 2) break; /* south */
143 if ((item
[xx
][yy
-1]!=OWALL
) || (item
[xx
][yy
-2]!=OWALL
)) break;
144 item
[xx
][yy
-1] = item
[xx
][yy
-2] = 0;
147 case 4: if (yy
>= MAXY
-3 ) break; /* north */
148 if ((item
[xx
][yy
+1]!=OWALL
) || (item
[xx
][yy
+2]!=OWALL
)) break;
149 item
[xx
][yy
+1] = item
[xx
][yy
+2] = 0;
152 if (++dir
> 4) { dir
=1; --try; }
157 * function to read in a maze from a data file
159 * Format of maze data file: 1st character = # of mazes in file (ascii digit)
160 * For each maze: 18 lines (1st 17 used) 67 characters per line
162 * Special characters in maze data file:
164 * # wall D door . random monster
165 * ~ eye of larn ! cure dianthroritis
174 if (lopen(larnlevels
)<0)
176 write(1,"Can't open the maze data file\n",30); died(-282); return(0);
178 i
=lgetc(); if (i
<='0') { died(-282); return(0); }
179 for (i
=18*rund(i
-'0'); i
>0; i
--) lgetl(); /* advance to desired maze */
180 for (i
=0; i
<MAXY
; i
++)
183 for (j
=0; j
<MAXX
; j
++)
185 it
= mit
= arg
= marg
= 0;
188 case '#': it
= OWALL
; break;
189 case 'D': it
= OCLOSEDDOOR
; arg
= rnd(30); break;
190 case '~': if (k
!=MAXLEVEL
-1) break;
192 mit
= rund(8)+DEMONLORD
;
193 marg
= monster
[mit
].hitpoints
; break;
194 case '!': if (k
!=MAXLEVEL
+MAXVLEVEL
-1) break;
195 it
= OPOTION
; arg
= 21;
197 marg
= monster
[mit
].hitpoints
; break;
198 case '.': if (k
<MAXLEVEL
) break;
199 mit
= makemonst(k
+1);
200 marg
= monster
[mit
].hitpoints
; break;
201 case '-': it
= newobject(k
+1,&arg
); break;
203 item
[j
][i
] = it
; iarg
[j
][i
] = arg
;
204 mitem
[j
][i
] = mit
; hitp
[j
][i
] = marg
;
207 know
[j
][i
] = (wizard
) ? 1 : 0;
218 function to make a treasure room on a level
219 level 10's treasure room has the eye in it and demon lords
220 level V3 has potion of cure dianthroritis and demon prince
225 register int tx
,ty
,xsize
,ysize
;
227 for (tx
=1+rnd(10); tx
<MAXX
-10; tx
+=10)
228 if ( (lv
==MAXLEVEL
-1) || (lv
==MAXLEVEL
+MAXVLEVEL
-1) || rnd(13)==2)
230 xsize
= rnd(6)+3; ysize
= rnd(3)+3;
231 ty
= rnd(MAXY
-9)+1; /* upper left corner of room */
232 if (lv
==MAXLEVEL
-1 || lv
==MAXLEVEL
+MAXVLEVEL
-1)
233 troom(lv
,xsize
,ysize
,tx
=tx
+rnd(MAXX
-24),ty
,rnd(3)+6);
234 else troom(lv
,xsize
,ysize
,tx
,ty
,rnd(9));
239 * subroutine to create a treasure room of any size at a given location
240 * room is filled with objects and monsters
241 * the coordinate given is that of the upper left corner of the room
243 troom(lv
,xsize
,ysize
,tx
,ty
,glyph
)
244 int lv
,xsize
,ysize
,tx
,ty
,glyph
;
248 for (j
=ty
-1; j
<=ty
+ysize
; j
++)
249 for (i
=tx
-1; i
<=tx
+xsize
; i
++) /* clear out space for room */
251 for (j
=ty
; j
<ty
+ysize
; j
++)
252 for (i
=tx
; i
<tx
+xsize
; i
++) /* now put in the walls */
254 item
[i
][j
]=OWALL
; mitem
[i
][j
]=0;
256 for (j
=ty
+1; j
<ty
+ysize
-1; j
++)
257 for (i
=tx
+1; i
<tx
+xsize
-1; i
++) /* now clear out interior */
260 switch(rnd(2)) /* locate the door on the treasure room */
262 case 1: item
[i
=tx
+rund(xsize
)][j
=ty
+(ysize
-1)*rund(2)]=OCLOSEDDOOR
;
263 iarg
[i
][j
] = glyph
; /* on horizontal walls */
265 case 2: item
[i
=tx
+(xsize
-1)*rund(2)][j
=ty
+rund(ysize
)]=OCLOSEDDOOR
;
266 iarg
[i
][j
] = glyph
; /* on vertical walls */
270 tp1
=playerx
; tp2
=playery
; playery
=ty
+(ysize
>>1);
272 for (playerx
=tx
+1; playerx
<=tx
+xsize
-2; playerx
+=2)
273 for (i
=0, j
=rnd(6); i
<=j
; i
++)
274 { something(lv
+2); createmonster(makemonst(lv
+1)); }
276 for (playerx
=tx
+1; playerx
<=tx
+xsize
-2; playerx
+=2)
277 for (i
=0, j
=rnd(4); i
<=j
; i
++)
278 { something(lv
+2); createmonster(makemonst(lv
+3)); }
280 playerx
=tp1
; playery
=tp2
;
283 static void fillroom();
289 subroutine to create the objects in the maze for the given level
297 fillroom(OENTRANCE
,0); /* entrance to dungeon */
298 fillroom(ODNDSTORE
,0); /* the DND STORE */
299 fillroom(OSCHOOL
,0); /* college of Larn */
300 fillroom(OBANK
,0); /* 1st national bank of larn */
301 fillroom(OVOLDOWN
,0); /* volcano shaft to temple */
302 fillroom(OHOME
,0); /* the players home & family */
303 fillroom(OTRADEPOST
,0); /* the trading post */
304 fillroom(OLRS
,0); /* the larn revenue service */
308 if (j
==MAXLEVEL
) fillroom(OVOLUP
,0); /* volcano shaft up from the temple */
310 /* make the fixed objects in the maze STAIRS */
311 if ((j
>0) && (j
!= MAXLEVEL
-1) && (j
!= MAXLEVEL
+MAXVLEVEL
-1))
312 fillroom(OSTAIRSDOWN
,0);
313 if ((j
> 1) && (j
!= MAXLEVEL
)) fillroom(OSTAIRSUP
,0);
315 /* make the random objects in the maze */
317 fillmroom(rund(3),OBOOK
,j
); fillmroom(rund(3),OALTAR
,0);
318 fillmroom(rund(3),OSTATUE
,0); fillmroom(rund(3),OPIT
,0);
319 fillmroom(rund(3),OFOUNTAIN
,0); fillmroom( rnd(3)-2,OIVTELETRAP
,0);
320 fillmroom(rund(2),OTHRONE
,0); fillmroom(rund(2),OMIRROR
,0);
321 fillmroom(rund(2),OTRAPARROWIV
,0); fillmroom( rnd(3)-2,OIVDARTRAP
,0);
322 fillmroom(rund(3),OCOOKIE
,0);
323 if (j
==1) fillmroom(1,OCHEST
,j
);
324 else fillmroom(rund(2),OCHEST
,j
);
325 if ((j
!= MAXLEVEL
-1) && (j
!= MAXLEVEL
+MAXVLEVEL
-1))
326 fillmroom(rund(2),OIVTRAPDOOR
,0);
329 fillmroom((rund(2)),ODIAMOND
,rnd(10*j
+1)+10);
330 fillmroom(rund(2),ORUBY
,rnd(6*j
+1)+6);
331 fillmroom(rund(2),OEMERALD
,rnd(4*j
+1)+4);
332 fillmroom(rund(2),OSAPPHIRE
,rnd(3*j
+1)+2);
334 for (i
=0; i
<rnd(4)+3; i
++)
335 fillroom(OPOTION
,newpotion()); /* make a POTION */
336 for (i
=0; i
<rnd(5)+3; i
++)
337 fillroom(OSCROLL
,newscroll()); /* make a SCROLL */
338 for (i
=0; i
<rnd(12)+11; i
++)
339 fillroom(OGOLDPILE
,12*rnd(j
+1)+(j
<<3)+10); /* make GOLD */
340 if (j
==5) fillroom(OBANK2
,0); /* branch office of the bank */
341 froom(2,ORING
,0); /* a ring mail */
342 froom(1,OSTUDLEATHER
,0); /* a studded leather */
343 froom(3,OSPLINT
,0); /* a splint mail */
344 froom(5,OSHIELD
,rund(3)); /* a shield */
345 froom(2,OBATTLEAXE
,rund(3)); /* a battle axe */
346 froom(5,OLONGSWORD
,rund(3)); /* a long sword */
347 froom(5,OFLAIL
,rund(3)); /* a flail */
348 froom(4,OREGENRING
,rund(3)); /* ring of regeneration */
349 froom(1,OPROTRING
,rund(3)); /* ring of protection */
350 froom(2,OSTRRING
,4); /* ring of strength + 4 */
351 froom(7,OSPEAR
,rnd(5)); /* a spear */
352 froom(3,OORBOFDRAGON
,0); /* orb of dragon slaying*/
353 froom(4,OSPIRITSCARAB
,0); /*scarab of negate spirit*/
354 froom(4,OCUBEofUNDEAD
,0); /* cube of undead control */
355 froom(2,ORINGOFEXTRA
,0); /* ring of extra regen */
356 froom(3,ONOTHEFT
,0); /* device of antitheft */
357 froom(2,OSWORDofSLASHING
,0); /* sword of slashing */
360 froom(4,OHAMMER
,0);/*Bessman's flailing hammer*/ c
[BESSMANN
]=1;
362 if (c
[HARDGAME
]<3 || (rnd(4)==3))
366 froom(3,OSWORD
,3); /* sunsword + 3 */
367 froom(5,O2SWORD
,rnd(4)); /* a two handed sword */
368 froom(3,OBELT
,4); /* belt of striking */
369 froom(3,OENERGYRING
,3); /* energy ring */
370 froom(4,OPLATE
,5); /* platemail + 5 */
376 subroutine to fill in a number of objects of the same kind
379 fillmroom(n
,what
,arg
)
384 for (i
=0; i
<n
; i
++) fillroom(what
,arg
);
389 { if (rnd(151) < n
) fillroom(itm
,arg
); }
392 subroutine to put an object into an empty room
406 x
=rnd(MAXX
-2); y
=rnd(MAXY
-2);
411 c
[RANDOMWALK
]++; /* count up these random walks */
414 x
+= rnd(3)-2; y
+= rnd(3)-2;
415 if (x
> MAXX
-2) x
=1; if (x
< 1) x
=MAXX
-2;
416 if (y
> MAXY
-2) y
=1; if (y
< 1) y
=MAXY
-2;
418 item
[x
][y
]=what
; iarg
[x
][y
]=arg
;
422 subroutine to put monsters into an empty room without walls or other
428 register int x
,y
,trys
;
429 for (trys
=5; trys
>0; --trys
) /* max # of creation attempts */
431 x
=rnd(MAXX
-2); y
=rnd(MAXY
-2);
432 if ((item
[x
][y
]==0) && (mitem
[x
][y
]==0) && ((playerx
!=x
) || (playery
!=y
)))
434 mitem
[x
][y
] = what
; know
[x
][y
]=0;
435 hitp
[x
][y
] = monster
[what
].hitpoints
; return(0);
438 return(-1); /* creation failure */
442 creates an entire set of monsters for a level
443 must be done when entering a new level
444 if sethp(1) then wipe out old monsters else leave them there
450 if (flg
) for (i
=0; i
<MAXY
; i
++) for (j
=0; j
<MAXX
; j
++) stealth
[j
][i
]=0;
451 if (level
==0) { c
[TELEFLAG
]=0; return; } /* if teleported and found level 1 then know level we are on */
452 if (flg
) j
= rnd(12) + 2 + (level
>>1); else j
= (level
>>1) + 1;
453 for (i
=0; i
<j
; i
++) fillmonst(makemonst(level
));
458 * Function to destroy all genocided monsters on the present level
463 for (y
=0; y
<MAXY
; y
++)
464 for (x
=0; x
<MAXX
; x
++)
465 if (monster
[mitem
[x
][y
]].genocided
)
466 mitem
[x
][y
]=0; /* no more monster */