DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T c

⟦1f6150c6e⟧ TextFile

    Length: 14814 (0x39de)
    Types: TextFile
    Names: »create.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Ularn/create.c« 

TextFile

/*	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 */
}