|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 14814 (0x39de) Types: TextFile Names: »create.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Ularn/create.c«
/* create.c */ #include "header.h" extern char spelknow[],larnlevels[]; extern char beenhere[],wizard,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; extern int char_picked; scbr(); clear(); c[LEVEL]=1; /* player starts at level one */ c[REGENCOUNTER]=16; c[ECOUNTER]=96; /*start regeneration correctly*/ c[SHIELD] = c[WEAR] = c[WIELD] = -1; if (char_picked >= 'a' && char_picked <= 'h') pick_char(char_picked); else { for (i=0; i<26; i++) iven[i]=0; pick_char(0); } playerx=rnd(MAXX-2); playery=rnd(MAXY-2); oldx=0; oldy=25; gtime=0; /* time clock starts at zero */ cbak[SPELLS] = -50; 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<MAXY; i++) for (j=0; j<MAXX; j++) know[j][i]=mitem[j][i]=0; else { getlevel(); sethp(0); goto chgn; /* yuck! */ } makemaze(x); makeobject(x); beenhere[x]=1; sethp(1); #if WIZID if (wizard || x==0) #else if (x==0) #endif for (j=0; j<MAXY; j++) for (i=0; i<MAXX; i++) know[i][j]=1; chgn: checkgen(); /* wipe out any genocided monsters */ } /* makemaze(level) int level; subroutine to make the caverns for a given level. only walls are made. */ static int mx,mxl,mxh,my,myl,myh,tmp2; makemaze(k) int k; { register int i,j; int tmp, z; if (k > 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; i<MAXY; i++) for (j=0; j<MAXX; j++) item[j][i]=tmp; if (k==0) return; eat(1,1); if (k==1) item[33][MAXY-1]=0; /* exit from dungeon */ /* now for open spaces -- not on level 10 */ if (k != MAXLEVEL-1) { tmp2 = rnd(3)+3; for (tmp=0; tmp<tmp2; tmp++) { my = rnd(11)+2; myl = my - rnd(2); myh = my + rnd(2); if (k < MAXLEVEL) { mx = rnd(44)+5; mxl = mx - rnd(4); mxh = mx + rnd(12)+3; z=0; } else { mx = rnd(60)+3; mxl = mx - rnd(2); mxh = mx + rnd(2); z = makemonst(k); } for (i=mxl; i<mxh; i++) for (j=myl; j<myh; j++) { item[i][j]=0; if ((mitem[i][j]=z)) hitp[i][j]=monster[z].hitpoints; } } } if (k!=MAXLEVEL-1) { my=rnd(MAXY-2); for (i=1; i<MAXX-1; i++) item[i][my] = 0; } if (k>1) 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); } for (i=18*rund(20); i>0; i--) lgetl(); /* advance to desired maze */ for (i=0; i<MAXY; i++) { row = lgetl(); for (j=0; j<MAXX; j++) { it = mit = arg = marg = 0; switch(*row++) { case '#': it = OWALL; break; case 'D': it = OCLOSEDDOOR; arg = rnd(30); break; case '~': if (k!=MAXLEVEL-1) break; it = OLARNEYE; mit = DEMONPRINCE; marg = monster[mit].hitpoints; break; case '!': if (k!=MAXLEVEL+MAXVLEVEL-1) break; it = OPOTION; arg = 21; mit = LUCIFER; marg = monster[mit].hitpoints; break; case '.': if (k<MAXLEVEL) break; mit = makemonst(k+1); marg = monster[mit].hitpoints; break; case '-': it = newobject(k+1,&arg); break; }; item[j][i] = it; iarg[j][i] = arg; mitem[j][i] = mit; hitp[j][i] = marg; #if WIZID know[j][i] = (wizard) ? 1 : 0; #else know[j][i] = 0; #endif } } lrclose(); return(1); } /* function to make a treasure room on a level level 10's treasure room has the eye in it and demon lords level V3 has potion of cure dianthroritis and demon prince */ treasureroom(lv) register int lv; { register int tx,ty,xsize,ysize; for (tx=1+rnd(10); tx<MAXX-10; tx+=10) if ( (lv==MAXLEVEL-1) || (lv==MAXLEVEL+MAXVLEVEL-1) || rnd(13)==2) { xsize = rnd(6)+3; ysize = rnd(3)+3; ty = rnd(MAXY-9)+1; /* upper left corner of room */ if (lv==MAXLEVEL-1 || lv==MAXLEVEL+MAXVLEVEL-1) troom(lv,xsize,ysize,tx=tx+rnd(MAXX-24),ty,rnd(3)+6); else troom(lv,xsize,ysize,tx,ty,rnd(9)); } } /* * subroutine to create a treasure room of any size at a given location * room is filled with objects and monsters * the coordinate given is that of the upper left corner of the room */ troom(lv,xsize,ysize,tx,ty,glyph) int lv,xsize,ysize,tx,ty,glyph; { register int i,j; int tp1,tp2; for (j=ty-1; j<=ty+ysize; j++) for (i=tx-1; i<=tx+xsize; i++) /* clear out space for room */ item[i][j]=0; for (j=ty; j<ty+ysize; j++) for (i=tx; i<tx+xsize; i++) /* now put in the walls */ { item[i][j]=OWALL; mitem[i][j]=0; } for (j=ty+1; j<ty+ysize-1; j++) for (i=tx+1; i<tx+xsize-1; i++) /* now clear out interior */ item[i][j]=0; switch(rnd(2)) /* locate the door on the treasure room */ { case 1: item[i=tx+rund(xsize)][j=ty+(ysize-1)*rund(2)]=OCLOSEDDOOR; iarg[i][j] = glyph; /* on horizontal walls */ break; case 2: item[i=tx+(xsize-1)*rund(2)][j=ty+rund(ysize)]=OCLOSEDDOOR; iarg[i][j] = glyph; /* on vertical walls */ break; }; tp1=playerx; tp2=playery; playery=ty+(ysize>>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+2)); } 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+4)); } playerx=tp1; playery=tp2; } /* *********** 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 object in the maze STAIRS and random object ELEVATORS */ if ((j>0) && (j != MAXLEVEL-1) && (j < MAXLEVEL+MAXVLEVEL-3)) fillroom(OSTAIRSDOWN,0); if ((j > 1) && (j != MAXLEVEL)) fillroom(OSTAIRSUP,0); if ((j>3) && (j != MAXLEVEL)) if (c[ELVUP]==0) if (rnd(100) > 85) { fillroom(OELEVATORUP,0); c[ELVUP]++; } if ((j>0) && (j<=MAXLEVEL-2)) if (c[ELVDOWN]==0) if (rnd(100) > 85) { fillroom(OELEVATORDOWN,0); c[ELVDOWN]++; } /* make the random objects in the maze */ fillmroom(rund(3),OBOOK,j); fillmroom(rund(3),OCOOKIE,0); fillmroom(rund(3),OALTAR,0); fillmroom(rund(3),OSTATUE,0); fillmroom(rund(3),OFOUNTAIN,0); fillmroom(rund(2),OTHRONE,0); fillmroom(rund(2),OMIRROR,0); if (j >= MAXLEVEL+MAXVLEVEL-3) fillroom(OPIT,0); fillmroom(rund(3),OPIT,0); if (j >= MAXLEVEL+MAXVLEVEL-3) fillroom(OIVTRAPDOOR,0); fillmroom(rund(2),OIVTRAPDOOR,0); fillmroom(rund(2),OTRAPARROWIV,0); fillmroom(rnd(3)-2,OIVTELETRAP,0); fillmroom(rnd(3)-2,OIVDARTRAP,0); if (j==1) fillmroom(1,OCHEST,j); else fillmroom(rund(2),OCHEST,j); if (j<MAXLEVEL-1) { 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; i<rnd(4)+3; i++) fillroom(OPOTION,newpotion()); /* make a POTION */ for (i=0; i<rnd(5)+3; i++) fillroom(OSCROLL,newscroll()); /* make a SCROLL */ for (i=0; i<rnd(12)+11; i++) fillroom(OGOLDPILE,12*rnd(j+1)+(j<<3)+10); /* make GOLD */ if (j==8) fillroom(OBANK2,0); /* branch office of the bank */ if ( (c[PAD]==0) && (j>=4) ) if (rnd(100) > 75) { fillroom(OPAD,0); /* Dealer McDope's Pad */ c[PAD]++; } froom(2,ORING,0); /* a ring mail */ froom(1,OSTUDLEATHER,0); /* a studded leather */ froom(3,OSPLINT,0); /* a splint mail*/ froom(5,OSHIELD,rund(3)); /* a shield */ froom(2,OBATTLEAXE,rund(3)); /* a battle axe */ froom(5,OLONGSWORD,rund(3)); /* a long sword */ froom(5,OFLAIL,rund(3)); /* a flail */ froom(7,OSPEAR,rnd(5)); /* a spear */ froom(4,OREGENRING,rund(3)); /* ring of regeneration */ froom(1,OPROTRING,rund(3)); /* ring of protection */ froom(2,OSTRRING,rund(5)); /* ring of strength */ froom(2,ORINGOFEXTRA,0); /* ring of extra regen */ if (c[LAMP]==0) { if (rnd(120) < 8) { fillroom (OBRASSLAMP,0); c[LAMP]++; goto zug; } } if (c[WAND]==0) { /* wand of wonder */ if (rnd(120) < 8) { fillroom(OWWAND,0); c[WAND]++; goto zug; } } if (c[DRAGSLAY]==0) /* orb of dragon slaying */ if(rnd(120) < 8) { fillroom(OORBOFDRAGON,0); c[DRAGSLAY]++; goto zug; } if (c[NEGATE]==0) /* scarab of negate spirit */ if(rnd(120) < 8) { fillroom(OSPIRITSCARAB,0); c[NEGATE]++; goto zug; } if (c[CUBEUNDEAD]==0) /* cube of undead control */ if (rnd(120) < 8) { fillroom(OCUBEofUNDEAD,0); c[CUBEUNDEAD]++; goto zug; } if (c[DEVICE]==0) /* device of antitheft */ if (rnd(120) < 8) { fillroom(ONOTHEFT,0); c[DEVICE]++; goto zug; } if(c[TALISMAN]==0) /* talisman of the sphere */ if(rnd(120) < 8) { fillroom(OSPHTALISMAN,0); c[TALISMAN]++; goto zug; } if (c[HAND]==0) /* hand of fear */ if (rnd(120) < 8) { fillroom(OHANDofFEAR,0); c[HAND]++; goto zug; } if (c[ORB] == 0) /* orb of enlightenment */ if (rnd(120) < 8) { fillroom(OORB,0); c[ORB]++; goto zug; } if (c[ELVEN]==0) /* elven chain */ if (rnd(120) < 8) { fillroom(OELVENCHAIN,0); c[ELVEN]++; } zug: if (c[SLASH]==0) /* sword of slashing */ if (rnd(120) < 8) { fillroom(OSWORDofSLASHING,0); c[SLASH]++; } if (c[BESSMANN]==0) /* Bessman's flailing hammer */ if(rnd(120) < 8) { fillroom(OHAMMER,0); c[BESSMANN]++; } if ((j>=10)&&(j<=20)&&(c[SLAY]==0)) /* Slayer */ if (rnd(100) > 85-(j-10)) { fillroom (OSLAYER,0); c[SLAY]++; } if ((c[STAFF]==0) && (j>=8) && (j<=20)) /* staff of power */ if (rnd(100) > 85-(j-10)) { fillroom(OPSTAFF,0); c[STAFF]++; } if (c[HARDGAME]<3 || (rnd(4)==3)) { if (j>3) { froom(3,OSWORD,rund(6)); /* sunsword */ froom(5,O2SWORD,rnd(6)); /* a two handed sword */ froom(3,OBELT,rund(7)); /* belt of striking */ froom(3,OENERGYRING,rund(6)); /* energy ring */ froom(4,OPLATE,rund(8)); /* platemail */ } } } /* 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<n; i++) fillroom(what,arg); } froom(n,itm,arg) int n; char itm; int arg; { if (rnd(151) < n) fillroom(itm,arg); } /* * subroutine to put an object into an empty room * uses a random walk */ fillroom(what,arg) char what; int arg; { register int x,y; x=rnd(MAXX-2); y=rnd(MAXY-2); while (item[x][y]) { x += rnd(3)-2; y += rnd(3)-2; if (x > 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=10; 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<MAXY; i++) for (j=0; j<MAXX; j++) stealth[j][i]=0; if (level==0) { c[TELEFLAG]=0; return; } /* if teleported and found level 1 then know level we are on */ if (flg) j = rnd(12) + 2 + (level>>1); else j = (level>>1) + 1; for (i=0; i<j; i++) fillmonst(makemonst(level)); if ((level >= 11) && (level<=15)) { i=level-10; for (j=1;j<=i;j++) if (fillmonst(DEMONLORD+rund(7))==-1) j--; } if (level > 15 ) { i=level-15; for (j=1;j<=i;j++) if (fillmonst(DEMONPRINCE)==-1) j--; } positionplayer(); } /* * Function to destroy all genocided monsters on the present level */ checkgen() { register int x,y; for (y=0; y<MAXY; y++) for (x=0; x<MAXX; x++) if (monster[mitem[x][y]].genocided) mitem[x][y]=0; /* no more monster */ }