]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - larn/create.c
46c09c935a70316cca85a712b19599653ab02719
1 /* create.c Larn is copyrighted 1986 by Noah Morgan. */
3 extern char spelknow
[],larnlevels
[];
4 extern char beenhere
[],wizard
,level
;
5 extern short oldx
,oldy
;
9 subroutine to create the player and the players attributes
10 this is called at the beginning of a game and at no other time
16 c
[HPMAX
]=c
[HP
]=10; /* start player off with 15 hit points */
17 c
[LEVEL
]=1; /* player starts at level one */
18 c
[SPELLMAX
]=c
[SPELLS
]=1; /* total # spells starts off as 3 */
19 c
[REGENCOUNTER
]=16; c
[ECOUNTER
]=96; /*start regeneration correctly*/
20 c
[SHIELD
] = c
[WEAR
] = c
[WIELD
] = -1;
21 for (i
=0; i
<26; i
++) iven
[i
]=0;
22 spelknow
[0]=spelknow
[1]=1; /*he knows protection, magic missile*/
25 iven
[0]=OLEATHER
; iven
[1]=ODAGGER
;
26 ivenarg
[1]=ivenarg
[0]=c
[WEAR
]=0; c
[WIELD
]=1;
28 playerx
=rnd(MAXX
-2); playery
=rnd(MAXY
-2);
30 gtime
=0; /* time clock starts at zero */
32 for (i
=0; i
<6; i
++) c
[i
]=12; /* make the attributes, ie str, int, etc. */
40 function to enter a new level. This routine must be called anytime the
41 player changes levels. If that level is unknown it will be created.
42 A new set of monsters will be created for a new level, and existing
43 levels will get a few more monsters.
44 Note that it is here we remove genocided monsters from the present level.
50 if (beenhere
[level
]) savelevel(); /* put the level back into storage */
51 level
= x
; /* get the new level and put in working storage */
52 if (beenhere
[x
]==0) for (i
=0; i
<MAXY
; i
++) for (j
=0; j
<MAXX
; j
++) know
[j
][i
]=mitem
[j
][i
]=0;
53 else { getlevel(); sethp(0); goto chgn
; }
54 makemaze(x
); makeobject(x
); beenhere
[x
]=1; sethp(1);
62 for (j
=0; j
<MAXY
; j
++)
63 for (i
=0; i
<MAXX
; i
++)
65 chgn
: checkgen(); /* wipe out any genocided monsters */
72 subroutine to make the caverns for a given level. only walls are made.
74 static int mx
,mxl
,mxh
,my
,myl
,myh
,tmp2
;
80 if (k
> 1 && (rnd(17)<=4 || k
==MAXLEVEL
-1 || k
==MAXLEVEL
+MAXVLEVEL
-1))
82 if (cannedlevel(k
)); return; /* read maze from data file */
84 if (k
==0) tmp
=0; else tmp
=OWALL
;
85 for (i
=0; i
<MAXY
; i
++) for (j
=0; j
<MAXX
; j
++) item
[j
][i
]=tmp
;
86 if (k
==0) return; eat(1,1);
87 if (k
==1) item
[33][MAXY
-1]=0; /* exit from dungeon */
89 /* now for open spaces -- not on level 10 */
93 for (tmp
=0; tmp
<tmp2
; tmp
++)
95 my
= rnd(11)+2; myl
= my
- rnd(2); myh
= my
+ rnd(2);
98 mx
= rnd(44)+5; mxl
= mx
- rnd(4); mxh
= mx
+ rnd(12)+3;
103 mx
= rnd(60)+3; mxl
= mx
- rnd(2); mxh
= mx
+ rnd(2);
106 for (i
=mxl
; i
<mxh
; i
++) for (j
=myl
; j
<myh
; j
++)
108 if ((mitem
[i
][j
]=z
)) hitp
[i
][j
]=monster
[z
].hitpoints
;
112 if (k
!=MAXLEVEL
-1) { my
=rnd(MAXY
-2); for (i
=1; i
<MAXX
-1; i
++) item
[i
][my
] = 0; }
113 if (k
>1) treasureroom(k
);
117 function to eat away a filled in maze
122 register int dir
,try;
128 case 1: if (xx
<= 2) break; /* west */
129 if ((item
[xx
-1][yy
]!=OWALL
) || (item
[xx
-2][yy
]!=OWALL
)) break;
130 item
[xx
-1][yy
] = item
[xx
-2][yy
] = 0;
133 case 2: if (xx
>= MAXX
-3) break; /* east */
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 3: if (yy
<= 2) break; /* south */
139 if ((item
[xx
][yy
-1]!=OWALL
) || (item
[xx
][yy
-2]!=OWALL
)) break;
140 item
[xx
][yy
-1] = item
[xx
][yy
-2] = 0;
143 case 4: if (yy
>= MAXY
-3 ) break; /* north */
144 if ((item
[xx
][yy
+1]!=OWALL
) || (item
[xx
][yy
+2]!=OWALL
)) break;
145 item
[xx
][yy
+1] = item
[xx
][yy
+2] = 0;
148 if (++dir
> 4) { dir
=1; --try; }
153 * function to read in a maze from a data file
155 * Format of maze data file: 1st character = # of mazes in file (ascii digit)
156 * For each maze: 18 lines (1st 17 used) 67 characters per line
158 * Special characters in maze data file:
160 * # wall D door . random monster
161 * ~ eye of larn ! cure dianthroritis
170 if (lopen(larnlevels
)<0)
172 write(1,"Can't open the maze data file\n",30); died(-282); return(0);
174 i
=lgetc(); if (i
<='0') { died(-282); return(0); }
175 for (i
=18*rund(i
-'0'); i
>0; i
--) lgetl(); /* advance to desired maze */
176 for (i
=0; i
<MAXY
; i
++)
179 for (j
=0; j
<MAXX
; j
++)
181 it
= mit
= arg
= marg
= 0;
184 case '#': it
= OWALL
; break;
185 case 'D': it
= OCLOSEDDOOR
; arg
= rnd(30); break;
186 case '~': if (k
!=MAXLEVEL
-1) break;
188 mit
= rund(8)+DEMONLORD
;
189 marg
= monster
[mit
].hitpoints
; break;
190 case '!': if (k
!=MAXLEVEL
+MAXVLEVEL
-1) break;
191 it
= OPOTION
; arg
= 21;
193 marg
= monster
[mit
].hitpoints
; break;
194 case '.': if (k
<MAXLEVEL
) break;
195 mit
= makemonst(k
+1);
196 marg
= monster
[mit
].hitpoints
; break;
197 case '-': it
= newobject(k
+1,&arg
); break;
199 item
[j
][i
] = it
; iarg
[j
][i
] = arg
;
200 mitem
[j
][i
] = mit
; hitp
[j
][i
] = marg
;
203 know
[j
][i
] = (wizard
) ? 1 : 0;
214 function to make a treasure room on a level
215 level 10's treasure room has the eye in it and demon lords
216 level V3 has potion of cure dianthroritis and demon prince
221 register int tx
,ty
,xsize
,ysize
;
223 for (tx
=1+rnd(10); tx
<MAXX
-10; tx
+=10)
224 if ( (lv
==MAXLEVEL
-1) || (lv
==MAXLEVEL
+MAXVLEVEL
-1) || rnd(13)==2)
226 xsize
= rnd(6)+3; ysize
= rnd(3)+3;
227 ty
= rnd(MAXY
-9)+1; /* upper left corner of room */
228 if (lv
==MAXLEVEL
-1 || lv
==MAXLEVEL
+MAXVLEVEL
-1)
229 troom(lv
,xsize
,ysize
,tx
=tx
+rnd(MAXX
-24),ty
,rnd(3)+6);
230 else troom(lv
,xsize
,ysize
,tx
,ty
,rnd(9));
235 * subroutine to create a treasure room of any size at a given location
236 * room is filled with objects and monsters
237 * the coordinate given is that of the upper left corner of the room
239 troom(lv
,xsize
,ysize
,tx
,ty
,glyph
)
240 int lv
,xsize
,ysize
,tx
,ty
,glyph
;
244 for (j
=ty
-1; j
<=ty
+ysize
; j
++)
245 for (i
=tx
-1; i
<=tx
+xsize
; i
++) /* clear out space for room */
247 for (j
=ty
; j
<ty
+ysize
; j
++)
248 for (i
=tx
; i
<tx
+xsize
; i
++) /* now put in the walls */
250 item
[i
][j
]=OWALL
; mitem
[i
][j
]=0;
252 for (j
=ty
+1; j
<ty
+ysize
-1; j
++)
253 for (i
=tx
+1; i
<tx
+xsize
-1; i
++) /* now clear out interior */
256 switch(rnd(2)) /* locate the door on the treasure room */
258 case 1: item
[i
=tx
+rund(xsize
)][j
=ty
+(ysize
-1)*rund(2)]=OCLOSEDDOOR
;
259 iarg
[i
][j
] = glyph
; /* on horizontal walls */
261 case 2: item
[i
=tx
+(xsize
-1)*rund(2)][j
=ty
+rund(ysize
)]=OCLOSEDDOOR
;
262 iarg
[i
][j
] = glyph
; /* on vertical walls */
266 tp1
=playerx
; tp2
=playery
; playery
=ty
+(ysize
>>1);
268 for (playerx
=tx
+1; playerx
<=tx
+xsize
-2; playerx
+=2)
269 for (i
=0, j
=rnd(6); i
<=j
; i
++)
270 { something(lv
+2); createmonster(makemonst(lv
+1)); }
272 for (playerx
=tx
+1; playerx
<=tx
+xsize
-2; playerx
+=2)
273 for (i
=0, j
=rnd(4); i
<=j
; i
++)
274 { something(lv
+2); createmonster(makemonst(lv
+3)); }
276 playerx
=tp1
; playery
=tp2
;
279 static void fillroom();
285 subroutine to create the objects in the maze for the given level
293 fillroom(OENTRANCE
,0); /* entrance to dungeon */
294 fillroom(ODNDSTORE
,0); /* the DND STORE */
295 fillroom(OSCHOOL
,0); /* college of Larn */
296 fillroom(OBANK
,0); /* 1st national bank of larn */
297 fillroom(OVOLDOWN
,0); /* volcano shaft to temple */
298 fillroom(OHOME
,0); /* the players home & family */
299 fillroom(OTRADEPOST
,0); /* the trading post */
300 fillroom(OLRS
,0); /* the larn revenue service */
304 if (j
==MAXLEVEL
) fillroom(OVOLUP
,0); /* volcano shaft up from the temple */
306 /* make the fixed objects in the maze STAIRS */
307 if ((j
>0) && (j
!= MAXLEVEL
-1) && (j
!= MAXLEVEL
+MAXVLEVEL
-1))
308 fillroom(OSTAIRSDOWN
,0);
309 if ((j
> 1) && (j
!= MAXLEVEL
)) fillroom(OSTAIRSUP
,0);
311 /* make the random objects in the maze */
313 fillmroom(rund(3),OBOOK
,j
); fillmroom(rund(3),OALTAR
,0);
314 fillmroom(rund(3),OSTATUE
,0); fillmroom(rund(3),OPIT
,0);
315 fillmroom(rund(3),OFOUNTAIN
,0); fillmroom( rnd(3)-2,OIVTELETRAP
,0);
316 fillmroom(rund(2),OTHRONE
,0); fillmroom(rund(2),OMIRROR
,0);
317 fillmroom(rund(2),OTRAPARROWIV
,0); fillmroom( rnd(3)-2,OIVDARTRAP
,0);
318 fillmroom(rund(3),OCOOKIE
,0);
319 if (j
==1) fillmroom(1,OCHEST
,j
);
320 else fillmroom(rund(2),OCHEST
,j
);
321 if ((j
!= MAXLEVEL
-1) && (j
!= MAXLEVEL
+MAXVLEVEL
-1))
322 fillmroom(rund(2),OIVTRAPDOOR
,0);
325 fillmroom((rund(2)),ODIAMOND
,rnd(10*j
+1)+10);
326 fillmroom(rund(2),ORUBY
,rnd(6*j
+1)+6);
327 fillmroom(rund(2),OEMERALD
,rnd(4*j
+1)+4);
328 fillmroom(rund(2),OSAPPHIRE
,rnd(3*j
+1)+2);
330 for (i
=0; i
<rnd(4)+3; i
++)
331 fillroom(OPOTION
,newpotion()); /* make a POTION */
332 for (i
=0; i
<rnd(5)+3; i
++)
333 fillroom(OSCROLL
,newscroll()); /* make a SCROLL */
334 for (i
=0; i
<rnd(12)+11; i
++)
335 fillroom(OGOLDPILE
,12*rnd(j
+1)+(j
<<3)+10); /* make GOLD */
336 if (j
==5) fillroom(OBANK2
,0); /* branch office of the bank */
337 froom(2,ORING
,0); /* a ring mail */
338 froom(1,OSTUDLEATHER
,0); /* a studded leather */
339 froom(3,OSPLINT
,0); /* a splint mail */
340 froom(5,OSHIELD
,rund(3)); /* a shield */
341 froom(2,OBATTLEAXE
,rund(3)); /* a battle axe */
342 froom(5,OLONGSWORD
,rund(3)); /* a long sword */
343 froom(5,OFLAIL
,rund(3)); /* a flail */
344 froom(4,OREGENRING
,rund(3)); /* ring of regeneration */
345 froom(1,OPROTRING
,rund(3)); /* ring of protection */
346 froom(2,OSTRRING
,4); /* ring of strength + 4 */
347 froom(7,OSPEAR
,rnd(5)); /* a spear */
348 froom(3,OORBOFDRAGON
,0); /* orb of dragon slaying*/
349 froom(4,OSPIRITSCARAB
,0); /*scarab of negate spirit*/
350 froom(4,OCUBEofUNDEAD
,0); /* cube of undead control */
351 froom(2,ORINGOFEXTRA
,0); /* ring of extra regen */
352 froom(3,ONOTHEFT
,0); /* device of antitheft */
353 froom(2,OSWORDofSLASHING
,0); /* sword of slashing */
356 froom(4,OHAMMER
,0);/*Bessman's flailing hammer*/ c
[BESSMANN
]=1;
358 if (c
[HARDGAME
]<3 || (rnd(4)==3))
362 froom(3,OSWORD
,3); /* sunsword + 3 */
363 froom(5,O2SWORD
,rnd(4)); /* a two handed sword */
364 froom(3,OBELT
,4); /* belt of striking */
365 froom(3,OENERGYRING
,3); /* energy ring */
366 froom(4,OPLATE
,5); /* platemail + 5 */
372 subroutine to fill in a number of objects of the same kind
375 fillmroom(n
,what
,arg
)
380 for (i
=0; i
<n
; i
++) fillroom(what
,arg
);
385 { if (rnd(151) < n
) fillroom(itm
,arg
); }
388 subroutine to put an object into an empty room
402 x
=rnd(MAXX
-2); y
=rnd(MAXY
-2);
407 c
[RANDOMWALK
]++; /* count up these random walks */
410 x
+= rnd(3)-2; y
+= rnd(3)-2;
411 if (x
> MAXX
-2) x
=1; if (x
< 1) x
=MAXX
-2;
412 if (y
> MAXY
-2) y
=1; if (y
< 1) y
=MAXY
-2;
414 item
[x
][y
]=what
; iarg
[x
][y
]=arg
;
418 subroutine to put monsters into an empty room without walls or other
424 register int x
,y
,trys
;
425 for (trys
=5; trys
>0; --trys
) /* max # of creation attempts */
427 x
=rnd(MAXX
-2); y
=rnd(MAXY
-2);
428 if ((item
[x
][y
]==0) && (mitem
[x
][y
]==0) && ((playerx
!=x
) || (playery
!=y
)))
430 mitem
[x
][y
] = what
; know
[x
][y
]=0;
431 hitp
[x
][y
] = monster
[what
].hitpoints
; return(0);
434 return(-1); /* creation failure */
438 creates an entire set of monsters for a level
439 must be done when entering a new level
440 if sethp(1) then wipe out old monsters else leave them there
446 if (flg
) for (i
=0; i
<MAXY
; i
++) for (j
=0; j
<MAXX
; j
++) stealth
[j
][i
]=0;
447 if (level
==0) { c
[TELEFLAG
]=0; return; } /* if teleported and found level 1 then know level we are on */
448 if (flg
) j
= rnd(12) + 2 + (level
>>1); else j
= (level
>>1) + 1;
449 for (i
=0; i
<j
; i
++) fillmonst(makemonst(level
));
454 * Function to destroy all genocided monsters on the present level
459 for (y
=0; y
<MAXY
; y
++)
460 for (x
=0; x
<MAXX
; x
++)
461 if (monster
[mitem
[x
][y
]].genocided
)
462 mitem
[x
][y
]=0; /* no more monster */