#ifndef lint static char rcsid[] = "$NetBSD: create.c,v 1.3 1995/03/23 08:33:14 cgd Exp $"; #endif /* not lint */ /* create.c Larn is copyrighted 1986 by Noah Morgan. */ #include "header.h" extern char spelknow[],larnlevels[]; extern char beenhere[],wizard; extern short level; extern short oldx,oldy; /* makeplayer() subroutine to create the player and the players attributes this is called at the beginning of a game and at no other time */ makeplayer() { register int i; scbr(); clear(); c[HPMAX]=c[HP]=10; /* start player off with 15 hit points */ c[LEVEL]=1; /* player starts at level one */ c[SPELLMAX]=c[SPELLS]=1; /* total # spells starts off as 3 */ c[REGENCOUNTER]=16; c[ECOUNTER]=96; /*start regeneration correctly*/ c[SHIELD] = c[WEAR] = c[WIELD] = -1; for (i=0; i<26; i++) iven[i]=0; spelknow[0]=spelknow[1]=1; /*he knows protection, magic missile*/ if (c[HARDGAME]<=0) { iven[0]=OLEATHER; iven[1]=ODAGGER; ivenarg[1]=ivenarg[0]=c[WEAR]=0; c[WIELD]=1; } playerx=rnd(MAXX-2); playery=rnd(MAXY-2); oldx=0; oldy=25; gtime=0; /* time clock starts at zero */ cbak[SPELLS] = -50; for (i=0; i<6; i++) c[i]=12; /* make the attributes, ie str, int, etc. */ recalc(); } /* newcavelevel(level) int level; function to enter a new level. This routine must be called anytime the player changes levels. If that level is unknown it will be created. A new set of monsters will be created for a new level, and existing levels will get a few more monsters. Note that it is here we remove genocided monsters from the present level. */ newcavelevel(x) register int x; { register int i,j; if (beenhere[level]) savelevel(); /* put the level back into storage */ level = x; /* get the new level and put in working storage */ if (beenhere[x]==0) for (i=0; i 1 && (rnd(17)<=4 || k==MAXLEVEL-1 || k==MAXLEVEL+MAXVLEVEL-1)) { if (cannedlevel(k)); return; /* read maze from data file */ } if (k==0) tmp=0; else tmp=OWALL; for (i=0; i1) treasureroom(k); } /* function to eat away a filled in maze */ eat(xx,yy) register int xx,yy; { register int dir,try; dir = rnd(4); try=2; while (try) { switch(dir) { case 1: if (xx <= 2) break; /* west */ if ((item[xx-1][yy]!=OWALL) || (item[xx-2][yy]!=OWALL)) break; item[xx-1][yy] = item[xx-2][yy] = 0; eat(xx-2,yy); break; case 2: if (xx >= MAXX-3) break; /* east */ if ((item[xx+1][yy]!=OWALL) || (item[xx+2][yy]!=OWALL)) break; item[xx+1][yy] = item[xx+2][yy] = 0; eat(xx+2,yy); break; case 3: if (yy <= 2) break; /* south */ if ((item[xx][yy-1]!=OWALL) || (item[xx][yy-2]!=OWALL)) break; item[xx][yy-1] = item[xx][yy-2] = 0; eat(xx,yy-2); break; case 4: if (yy >= MAXY-3 ) break; /* north */ if ((item[xx][yy+1]!=OWALL) || (item[xx][yy+2]!=OWALL)) break; item[xx][yy+1] = item[xx][yy+2] = 0; eat(xx,yy+2); break; }; if (++dir > 4) { dir=1; --try; } } } /* * function to read in a maze from a data file * * Format of maze data file: 1st character = # of mazes in file (ascii digit) * For each maze: 18 lines (1st 17 used) 67 characters per line * * Special characters in maze data file: * * # wall D door . random monster * ~ eye of larn ! cure dianthroritis * - random object */ cannedlevel(k) int k; { char *row,*lgetl(); register int i,j; int it,arg,mit,marg; if (lopen(larnlevels)<0) { write(1,"Can't open the maze data file\n",30); died(-282); return(0); } i=lgetc(); if (i<='0') { died(-282); return(0); } for (i=18*rund(i-'0'); i>0; i--) lgetl(); /* advance to desired maze */ for (i=0; i>1); if (c[HARDGAME]<2) for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2) for (i=0, j=rnd(6); i<=j; i++) { something(lv+2); createmonster(makemonst(lv+1)); } else for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2) for (i=0, j=rnd(4); i<=j; i++) { something(lv+2); createmonster(makemonst(lv+3)); } playerx=tp1; playery=tp2; } static void fillroom(); /* *********** MAKE_OBJECT *********** subroutine to create the objects in the maze for the given level */ makeobject(j) register int j; { register int i; if (j==0) { fillroom(OENTRANCE,0); /* entrance to dungeon */ fillroom(ODNDSTORE,0); /* the DND STORE */ fillroom(OSCHOOL,0); /* college of Larn */ fillroom(OBANK,0); /* 1st national bank of larn */ fillroom(OVOLDOWN,0); /* volcano shaft to temple */ fillroom(OHOME,0); /* the players home & family */ fillroom(OTRADEPOST,0); /* the trading post */ fillroom(OLRS,0); /* the larn revenue service */ return; } if (j==MAXLEVEL) fillroom(OVOLUP,0); /* volcano shaft up from the temple */ /* make the fixed objects in the maze STAIRS */ if ((j>0) && (j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1)) fillroom(OSTAIRSDOWN,0); if ((j > 1) && (j != MAXLEVEL)) fillroom(OSTAIRSUP,0); /* make the random objects in the maze */ fillmroom(rund(3),OBOOK,j); fillmroom(rund(3),OALTAR,0); fillmroom(rund(3),OSTATUE,0); fillmroom(rund(3),OPIT,0); fillmroom(rund(3),OFOUNTAIN,0); fillmroom( rnd(3)-2,OIVTELETRAP,0); fillmroom(rund(2),OTHRONE,0); fillmroom(rund(2),OMIRROR,0); fillmroom(rund(2),OTRAPARROWIV,0); fillmroom( rnd(3)-2,OIVDARTRAP,0); fillmroom(rund(3),OCOOKIE,0); if (j==1) fillmroom(1,OCHEST,j); else fillmroom(rund(2),OCHEST,j); if ((j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1)) fillmroom(rund(2),OIVTRAPDOOR,0); if (j<=10) { fillmroom((rund(2)),ODIAMOND,rnd(10*j+1)+10); fillmroom(rund(2),ORUBY,rnd(6*j+1)+6); fillmroom(rund(2),OEMERALD,rnd(4*j+1)+4); fillmroom(rund(2),OSAPPHIRE,rnd(3*j+1)+2); } for (i=0; i3) { froom(3,OSWORD,3); /* sunsword + 3 */ froom(5,O2SWORD,rnd(4)); /* a two handed sword */ froom(3,OBELT,4); /* belt of striking */ froom(3,OENERGYRING,3); /* energy ring */ froom(4,OPLATE,5); /* platemail + 5 */ } } } /* subroutine to fill in a number of objects of the same kind */ fillmroom(n,what,arg) int n,arg; char what; { register int i; for (i=0; i MAXX-2) x=1; if (x < 1) x=MAXX-2; if (y > MAXY-2) y=1; if (y < 1) y=MAXY-2; } item[x][y]=what; iarg[x][y]=arg; } /* subroutine to put monsters into an empty room without walls or other monsters */ fillmonst(what) char what; { register int x,y,trys; for (trys=5; trys>0; --trys) /* max # of creation attempts */ { x=rnd(MAXX-2); y=rnd(MAXY-2); if ((item[x][y]==0) && (mitem[x][y]==0) && ((playerx!=x) || (playery!=y))) { mitem[x][y] = what; know[x][y]=0; hitp[x][y] = monster[what].hitpoints; return(0); } } return(-1); /* creation failure */ } /* creates an entire set of monsters for a level must be done when entering a new level if sethp(1) then wipe out old monsters else leave them there */ sethp(flg) int flg; { register int i,j; if (flg) for (i=0; i>1); else j = (level>>1) + 1; for (i=0; i