[net.sources.games] Phantasia 3.3.1+ Part 3 of 4

nonh@utzoo.UUCP (Chris Robertson) (10/09/85)

: This is a shell archive.  Remove everything up to this line, save the rest
# in a file and then type "/bin/sh file" to extract the following files:
# func2.c func3.c main.c monsters pathdefs.c setup.c
if test -s "func2.c"
	then
	echo Will not overwrite existing 'func2.c'
else
	sed -e "s/^X//" > func2.c << 'TiDDleYwiNKs'
X/*
X * func2.c  Phantasia support routines
X */
X
X#include "phant.h"
X
Xvoid
Xdecree(stat)		    /* king and valar stuff */
X
Xreg struct  stats   *stat;
X{
X	FILE	*fp;
X	short	arg;
X	char	aline[80], *cp;
X	struct	stats	sbuf;
X	struct	energyvoid vbuf;
X	double	temp1 = 0.0, temp2 = 0.0;
X	int 	ch;
X	reg int loc;
X
X	move(6,0);
X	clrtoeol();
X	if (stat->typ < 20 && !su)	/* king */
X	{
X		addstr("0:Census  1:Transport  2:Curse  3:Energy Void  4:Bestow  5:Collect Taxes  ");
X		ch = getans(" ", TRUE);
X		move(6,0);
X		clrtoeol();
X		move(4,0);
X		switch (ch)
X		{
X			case '0':
X				showusers(TRUE);
X				return;
X			case '1':
X				arg = TRANSPORT;
X				cp = "transport";
X				break;
X			case '2':
X				arg = CURSED;
X				cp = "curse";
X				break;
X			case '3':
X				addstr("Enter the X Y coordinates of void: ");
X				getstring(aline,30);
X				sscanf(aline,"%F %F",&temp1,&temp2);
X				vbuf.v_x = floor(temp1);
X				vbuf.v_y = floor(temp2);
X				vbuf.active = TRUE;
X				if ((loc = allocvoid()) > 20)
X					mvaddstr(5,0,"Sorry, void creation limit reached.\n");
X				else
X					voidupdate(&vbuf,loc);
X				goto EXIT;
X			case '4':
X				arg = GOLD;
X				addstr("Amount of gold to bestow: ");
X				temp1 = inflt();
X				if (temp1 > stat->gld || temp1 < 0)
X				{
X					mvaddstr(5,0,"You don't have that !\n");
X					return;
X				}
X				stat->gld -= floor(temp1);
X				cp = "give gold to";
X				break;
X			case '5':
X				fp = fopen(goldfile,"r");
X				fread((char *) &temp1,sizeof(double),1,fp);
X				fclose(fp);
X				mvprintw(4,0,"You have collected %.0f in gold.\n",temp1);
X				stat->gld += floor(temp1);
X				fp = fopen(goldfile,"w");
X				temp1 = 0.0;
X				fwrite((char *) &temp1,sizeof(double),1,fp);
X				fclose(fp);
X				return;
X			default:
X				return;
X		}
X	}
X	else    /* council of wise, valar, etc. */
X	{
X		addstr("1:Heal  ");
X		if (stat->pal || su)
X			addstr("2:Seek Grail  ");
X		if (stat->typ == 99 || su)
X			addstr("3:Throw Monster  4:Relocate  5:Bless  ");
X		if (su)
X			addstr("6:Vaporize  ");
X		ch = getans(" ", TRUE);
X		if (!su && ch > '2' && stat->typ != 99)
X		{
X			illcmd();
X			return;
X		}
X		switch (ch)
X		{
X			case '1':
X				arg = HEAL;
X				cp = "heal";
X				break;
X			case '2':
X				if (stat->pal)
X				{
X					fp = fopen(voidfile,"r");
X					fread((char *) &vbuf,sizeof(vbuf),1,fp);
X					fclose(fp);
X					temp1 = dist(stat->x, vbuf.v_x, stat->y, vbuf.v_y);
X					temp1 = floor(temp1 + roll(-temp1/10.0,temp1/5.0));
X					mvprintw(5,0,"The palantir says the Grail is about %.0f away.\n",temp1);
X					return;
X				}
X				else
X				{
X					mvaddstr(5,0,"You need a palantir to seek the Grail.\n");
X					return;
X				}
X			case '3':
X				mvaddstr(4,0,"Which monster [0-99]? ");
X				temp1 = inflt();
X				temp1 = max(0,min(99,temp1));
X				cp = "throw a monster at";
X				arg = MONSTER;
X				break;
X			case '4':
X				mvaddstr(4,0,"New X Y coordinates: ");
X				getstring(aline,30);
X				sscanf(aline,"%F %F",&temp1,&temp2);
X				cp = "relocate";
X				arg = MOVED;
X				break;
X			case '5':
X				arg = BLESS;
X				cp = "bless";
X				break;
X			case '6':
X				if (su)
X				{
X					cp = "vaporize";
X					arg = VAPORIZED;
X					break;
X				}
X			default:
X				return;
X		}
X	}
X	mvprintw(4,0,"Who do you want to %s? ",cp);
X	getstring(aline,21);
X	trunc(aline);
X	if (strcmp(stat->name,aline))
X	{
X		if ((loc = findname(aline,&sbuf)) >= 0)
X		{
X			if (sbuf.tampered)
X			{
X				mvaddstr(5,0,"That person has something pending already.\n");
X				return;
X			}
X			else
X			{
X				sbuf.tampered = arg;
X				sbuf.scratch1 = floor(temp1);
X				sbuf.scratch2 = floor(temp2);
X				update(&sbuf,loc);
XEXIT:			mvaddstr(5,0,"It is done.\n");
X				return;
X			}
X		}
X		else
X			mvaddstr(5,0,"There is no one by that name.\n");
X	}
X	else
X		mvaddstr(5,0,"You may not do it to yourself!\n");
X}
X
X/****************************************************************/
X
Xvoid
Xchecktampered(stat)	    /* see if decree'd etc. */
X
Xreg struct  stats   *stat;
X{
X	struct	energyvoid vbuf;
X	struct	stats sbuf;
X	FILE	*fp;
X	reg int loc = 0;
X
X	/* first check for energy voids */
X
X	if ((fp = fopen(voidfile,"r")) == NULL)
X	{
X		error(voidfile);
X		/*NOTREACHED*/
X	}
X	while (fread((char *) &vbuf,sizeof(vbuf),1,fp))
X		if (vbuf.active && vbuf.v_x == stat->x && vbuf.v_y == stat->y)
X		{
X			fclose(fp);
X			if (loc)
X			{
X				vbuf.active = FALSE;
X				voidupdate(&vbuf,loc);
X				tampered(stat,NRGVOID,&sbuf);
X			}
X			else if (stat->status != CLOAKED)
X				tampered(stat,GRAIL,&sbuf);
X			break;
X		}
X		else
X			++loc;
X	fclose(fp);
X
X	/* now check for other things */
X
X	statread(&sbuf,fileloc);
X	if (sbuf.tampered)
X		tampered(stat,sbuf.tampered,&sbuf);
X}
X
X/****************************************************************/
X
Xvoid
Xvoidupdate(vp,loc)	    /* update an energy void */
X
Xreg struct energyvoid  *vp;
Xreg int loc;
X{
X	FILE	*fp;
X
X	fp = fopen(voidfile,ACCESS);
X	fseek(fp,(long) (loc*sizeof(*vp)),0);
X	fwrite((char *) vp,sizeof(*vp),1,fp);
X	fclose(fp);
X}
X
X/****************************************************************/
X
Xint
Xallocvoid() 	    /* find a space to put an energy void */
X{
X	FILE	*fp;
X	reg int loc = 0;
X	struct	energyvoid vbuf;
X
X	fp = fopen(voidfile,"r");
X	while (fread((char *) &vbuf,sizeof(vbuf),1,fp))
X		if (vbuf.active)
X			++loc;
X		else
X		{
X			fclose(fp);
X			return (loc);
X		}
X	fclose(fp);
X	return (loc);
X}
X
X/****************************************************************/
X
Xvoid
Xstatread(stat,loc)	    /* read a charac. structure */
X
Xreg struct  stats   *stat;
Xreg int loc;
X{
X	fseek(read_pfile,(long) (loc * sizeof(*stat)),0);
X	fread((char *) stat,sizeof(*stat),1,read_pfile);
X}
X
X/****************************************************************/
X
Xvoid
Xtampered(stat,what,bufp)	    /* decree'd, intervened, etc. */
X
Xreg struct  stats   *stat, *bufp;
Xshort	what;
X{
X	struct	energyvoid vbuf;
X	reg int loc;
X	struct	stats	sbuf;
X
X	changed = TRUE;
X	move(4,0);
X	stat->tampered = OFF;
X	switch ((int) what)
X	{
X		case NRGVOID:
X			addstr("You've hit an energy void !\n");
X			stat->man /= 3;
X			stat->energy /= 2;
X			stat->gld = floor(stat->gld/1.25) + 0.1;
X			stat->x += roll(-12,25);
X			stat->y += roll(-12,25);
X			break;
X		case TRANSPORT:
X			addstr("The king transported you !  ");
X			if (stat->chm)
X			{
X				addstr("But your charm save you...\n");
X				--stat->chm;
X			}
X			else
X			{
X				stat->x += roll(-50,100) * circ(stat->x,stat->y);
X				stat->y += roll(-50,100) * circ(stat->x,stat->y);
X				addch('\n');
X			}
X			break;
X		case GOLD:
X			printw("The king has bestowed %.0f gold pieces on you !\n",
X							bufp->scratch1);
X			stat->gld += bufp->scratch1;
X			break;
X		case CURSED:
X			addstr("You've been cursed !  ");
X			if (stat->bls)
X			{
X				addstr("But your blessing saved you...\n");
X				stat->bls = FALSE;
X			}
X			else
X			{
X				addch('\n');
X				stat->psn += 2;
X				stat->energy = 10;
X				stat->mxn  *= 0.95;
X				stat->status = PLAYING;
X			}
X			break;
X		case VAPORIZED:
X			addstr("Woops!  You've been vaporized!\n");
X			death(stat, "Vaporization");
X			break;
X		case MONSTER:
X			addstr("The Valar zapped you with a monster!\n");
X			more(7);
X			fight(stat,(int) bufp->scratch1);
X			return;
X		case BLESS:
X			addstr("The Valar has blessed you!\n");
X			stat->energy = (stat->mxn *= 1.05) + stat->shd;
X			stat->man += 500;
X			stat->str += 0.5;
X			stat->brn += 0.5;
X			stat->mag += 0.5;
X			stat->psn = min(0.5,stat->psn);
X			break;
X		case MOVED:
X			addstr("You've been relocated...\n");
X			stat->x = bufp->scratch1;
X			stat->y = bufp->scratch2;
X			break;
X		case HEAL:
X			addstr("You've been healed!\n");
X			stat->psn -=  0.25;
X			stat->energy = stat->mxn + stat->shd;
X			break;
X		case STOLEN:
X			addstr("You've been bumped off as Valar!\n");
X			stat->typ = 20 + roll(1,6);
X			break;
X		case GRAIL:
X			addstr("You have found The Holy Grail!!\n");
X			if (stat->typ < 20)
X			{
X				addstr("However, you are not experienced enough to behold it.\n");
X				stat->sin *= stat->sin;
X				stat->man +=  1000;
X			}
X			else if (stat->typ == 99 || stat->typ == 90)
X			{
X				addstr("You have made it to the position of Valar once already.\n");
X				addstr("The Grail is of no more use to you now.\n");
X			}
X			else
X			{
X				addstr("It is now time to see if you are worthy to behold it...\n");
X				refresh();
X				sleep(4);
X				if (rnd() / 2.0 < stat->sin)
X				{
X					addstr("You blew this one!\n");
X					stat->str = stat->man = stat->quk = stat->energy = stat->mxn
X						= stat->x = stat->y = stat->mag = stat->brn
X						= stat->exp = 1;
X					stat->lvl = 0;
X				}
X				else
X				{
X					addstr("You made to position of Valar!\n");
X					stat->typ = 99;
X					fseek(read_pfile,0L,0);
X					loc = 0;
X					while (fread((char *) &sbuf,sizeof(sbuf),1,read_pfile))
X						if (sbuf.typ == 99)
X						{
X							sbuf.tampered = STOLEN;
X							update(&sbuf,loc);
X							break;
X						}
X						else
X							++loc;
X				}
X			default:
X				break;
X		}
X		vbuf.active = TRUE;
X		vbuf.v_x = roll(-1e6,2e6);
X		vbuf.v_y = roll(-1e6,2e6);
X		voidupdate(&vbuf,0);
X		break;
X	}
X}
X
X/****************************************************************/
X
Xvoid
Xadjuststats(stat)		/* make sure things are within limits, etc. */
X
Xreg struct  stats   *stat;
X{
X	long	ltemp;
X	reg int temp;
X
X	stat->x = floor(stat->x);
X	stat->y = floor(stat->y);
X	valhala = (stat->typ == 99);
X	throne = (stat->x == 0.0 && stat->y == 0.0);
X#ifdef WORM
X	temp = abs(stat->x)/400;
X	if (temp > 16)
X		temp = 0;
X
X	/* wormholes are at y = 0 and x = -400, +800, -1200, +1600, ... */
X
X	if (stat->y == 0.0 && !throne && !valhala && temp <= 16 &&
X			((sgn(stat->x) == -1 && temp % 2 == 1) ||
X					(sgn(stat->x) == 1 && temp % 2 == 0)))
X	{
X		if (!wmhl)
X			stat->wormhole = temp;
X		wmhl = TRUE;
X	}
X	else
X		wmhl = FALSE;
X#endif
X	speed = stat->quk + stat->quks - spdcalc(stat->lvl,stat->gld,stat->gem);
X	strength = stat->str + stat->swd - strcalc(stat->str,stat->psn);
X	time(&ltemp);
X	stat->age += (ltemp - secs);
X	secs = ltemp;
X	stat->quks = min(99,stat->quks);
X	stat->man = min(stat->man,stat->lvl*15 + 5000);
X	stat->chm = min(stat->chm,stat->lvl + 10);
X	/* stat->typ = (stat->crn && stat->typ < 10)? -abs(stat->typ) : abs(stat->typ); */
X	if (level(stat->exp) > stat->lvl)
X	{
X		movelvl(stat);
X		if (stat->lvl > 5)
X			timeout = TRUE;
X	}
X	stat->gld = floor(stat->gld) + 0.1;
X	stat->gem = floor(stat->gem) + 0.1;
X	if (stat->rng.type)
X		stat->energy = stat->mxn + stat->shd;
X	if (stat->rng.type && stat->rng.duration <= 0)  /* clean up rings */
X		switch (stat->rng.type)
X		{
X			case DLBAD:
X			case NAZBAD:
X				stat->rng.type = SPOILED;
X				stat->rng.duration = roll(10,25);
X				break;
X			case NAZREG:
X				stat->rng.type = NONE;
X				break;
X			case SPOILED:
X				death(stat, "A cursed ring");
X				break;
X		}	/* DLREG is ok, so do nothing with it */
X	if (stat->age > stat->degen * 5000)
X	{
X		++stat->degen;
X		if (stat->quk > 23)
X			--stat->quk;
X		stat->str *= 0.97;
X		stat->brn *= 0.95;
X		stat->mag *= 0.97;
X		stat->mxn *= 0.95;
X		if (stat->quks)
X			--stat->quks;
X		stat->swd *= 0.93;
X		stat->shd *= 0.95;
X	}
X}
X
X/****************************************************************/
X
Xvoid
Xcheckinterm(stat)		/* see if other person on same x,y */
X
Xreg struct  stats   *stat;
X{
X	struct	stats	sbuf;
X	reg int foeloc = 0;
X
X	users = 0;
X	fseek(read_pfile,0L,0);
X	while (fread((char *) &sbuf,sizeof(sbuf),1,read_pfile))
X	{
X		if (sbuf.status && (sbuf.status != CLOAKED || sbuf.typ != 99))
X		{
X			++users;
X			if (stat->x == sbuf.x && stat->y == sbuf.y
X					&& foeloc != fileloc && sbuf.typ != 99
X					&& stat->typ !=99 && !stat->wormhole && !sbuf.wormhole)
X			{
X				interm(stat,foeloc);
X				return;
X			}
X		}
X		++foeloc;
X	}
X}
X
X/****************************************************************/
X
Xint
Xgch(rngtyp) 	/* get a character from terminal, but check ring if crazy */
X
Xshort	rngtyp;
X{
X	refresh();
X	if (abs(rngtyp) != SPOILED)
X		return (getans("T ", TRUE));
X	else
X	{
X		getans(" ", TRUE);
X		return (roll(0,5) + '0');
X	}
X}
X
X/****************************************************************/
X
Xint
Xrngcalc(chartyp)		    /* pick a duration of a ring */
X
Xshort	chartyp;
X{
X	static	int rngtab[] = { 0, 10, 20, 13, 25, 40, 20};
X
X	if (chartyp > 10)
X		chartyp -= 10;
X	return (rngtab[chartyp - 1]);
X}
X
X/****************************************************************/
X
Xvoid
Xinterm(stat,who)		/* interterminal battle routine */
X
Xreg struct  stats   *stat;
Xint who;
X{
X#define MAXWAIT 20
X#define BLOCK	sizeof(struct stats)
X#define RAN 1
X#define STUCK	2
X#define BLEWIT	3
X#define KILLED	4
X#define readfoe()   fseek(read_pfile,foeplace,0);fread((char *) foe,BLOCK,1,\
X					read_pfile)
X#define updateme()  fseek(access_pfile,myplace,0);fwrite((char *) stat,BLOCK,\
X					1,access_pfile);fflush(access_pfile)
X
X	double	temp, foespeed, oldhits = 0.0, myhits;
X	struct	stats	sbuf;
X	reg		struct  stats *foe;
X	reg		int loop, lines = 8;
X	int 	ch;
X	long	myplace, foeplace;
X	short	oldtags;
X	bool	luckout = FALSE;
X	char	foename[21];
X
X	fghting = TRUE;
X	mvaddstr(4,0,"Preparing for battle!\n");
X	refresh();
X
X	/* set up variables, file, etc. */
X
X	myplace = fileloc * BLOCK;
X	foeplace = who * BLOCK;
X	fseek(read_pfile,0L,0);
X	setbuf(read_pfile, (char *) NULL);
X	stat->status = INBATTLE;
X	myhits = stat->energy;
X
X	/* stats.tampered must be non-zero to stop a king or valar trashing it */
X
X	stat->tampered = oldtags = 1;
X	stat->scratch1 = 0.0;
X	stat->istat = 0;
X	updateme();
X	foe = &sbuf;
X	readfoe();
X	foespeed = foe->quk + foe->quks - spdcalc(foe->lvl,foe->gld,foe->gem);
X	if (abs(stat->lvl - foe->lvl) > 20)     /* see if greatly mismatched */
X	{
X		temp = ((double) (stat->lvl - foe->lvl))/((double) max(stat->lvl,
X													foe->lvl));
X		if (temp > 0.5)     /* this one outweighs his/her foe */
X			foespeed *= 2.0;
X		else if (temp < -0.5)	/* foe outweighs this one */
X			speed *= 2.0;
X	}
X	if (stat->blind)
X		strcpy(foename,"someone");
X	else
X		strcpy(foename,foe->name);
X	mvprintw(6,0,"You have encountered %s   Level: %d\n",foename,foe->lvl);
X	refresh();
X
X	/* now wait for foe to respond */
X
X	for (loop = 1.5*MAXWAIT; foe->status != INBATTLE && loop; --loop)
X	{
X		readfoe();
X		sleep(1);
X	}
X	if (foe->status != INBATTLE)
X	{
X		mvprintw(5,0,"%s is not responding.\n",foename);
X		goto LEAVE;
X	}
X
X	/* otherwise, everything is set to go */
X
X	move(4,0);
X	clrtoeol();
X
X	/* check to see who goes first */
X
X	if (speed > foespeed)
X		goto HITFOE;
X	else if (foespeed > speed)
X		goto WAIT;
X	else if (stat->lvl > foe->lvl)
X		goto HITFOE;
X	else if (foe->lvl > stat->lvl)
X		goto WAIT;
X	else    /* no one is faster */
X	{
X		printw("You can't fight %s yet.",foename);
X		goto LEAVE;
X	}
X
X/* routine to hit, etc */
X
XHITFOE: printstats(stat);
X	mesg();
X	mvprintw(1,26,"%9.0f",myhits);
X	mvaddstr(7,0,"1:Fight  2:Run Away!  3:Power Blast  ");
X	if (luckout)
X		clrtoeol();
X	else
X		addstr("4:Luckout  ");
X	ch = gch(stat->rng.type);
X	move(lines = 8,0);
X	clrtobot();
X	switch (ch)
X	{
X		default:    /* fight */
X			temp = roll(2,strength);
XHIT:		mvprintw(lines++,0,"You hit %s %.0f times!",foename,temp);
X			stat->sin += 0.5;
X			stat->scratch1 += temp;
X			stat->istat = FALSE;
X			break;
X		case '2':   /* run away */
X			--stat->scratch1;	/* this value changes to indicate action */
X			if (rnd() > 0.25)
X			{
X				mvaddstr(lines++,0,"You got away!");
X				stat->istat = RAN;
X				goto LEAVE;
X			}
X			mvprintw(lines++,0,"%s is still after you!",foename);
X			stat->istat = STUCK;
X			break;
X		case '3':   /* power blast */
X			temp = min(stat->man,stat->lvl*5);
X			stat->man -= temp;
X			temp = (rnd() + 0.5) * temp * stat->mag * 0.2 + 2;
X			mvprintw(lines++,0,"You blasted %s !",foename);
X			goto HIT;
X		case '4':   /* luckout */
X			if (luckout || rnd() > 0.1)
X			{
X				luckout = TRUE;
X				mvaddstr(lines++,0,"Not this time...");
X				--stat->scratch1;
X				stat->istat = BLEWIT;
X			}
X			else
X			{
X				mvaddstr(lines++,0,"You just lucked out!");
X				stat->scratch1 = foe->energy + 5;
X			}
X			break;
X	}
X	refresh();
X	stat->scratch1 = floor(stat->scratch1);	/* clean up any mess */
X	if (stat->scratch1 > foe->energy)
X		stat->istat = KILLED;
X	else if (rnd() * speed < rnd() * foespeed)
X	{	/* foe's turn */
X		++stat->tampered;
X		updateme();
X		goto WAIT;
X	}
X	updateme();
X
X	if (stat->istat == KILLED)
X	{
X		mvprintw(lines++,0,"You killed %s!",foename);
X		stat->exp += foe->exp;
X		stat->crn += (stat->lvl < 1000)? foe->crn : 0;
X		stat->amu += foe->amu;
X		stat->chm += foe->chm;
X		stat->gld += foe->gld;
X		stat->gem += foe->gem;
X		stat->swd = max(stat->swd,foe->swd);
X		stat->shd = max(stat->shd,foe->shd);
X		stat->quks = max(stat->quks,foe->quks);
X		if (foe->vrg == TRUE)
X		{
X			mvaddstr(lines++,0,"You have rescued a virgin.  Will you be honourable? ");
X			if ((ch = getans("YN",FALSE)) == 'Y')
X				stat->vrg = TRUE;
X			else
X			{
X				++stat->sin;
X				stat->exp += 8000;
X			}
X		}
X		sleep(3);     /* give other person time to die */
X		goto LEAVE;
X	}
X	goto HITFOE;    /* otherwise, my turn again */
X
X/* routine to wait for foe to do something */
X
XWAIT:	printstats(stat);
X	mesg();
X	mvprintw(1,26,"%9.0f",myhits);
X	mvaddstr(4,0,"Waiting...\n");
X	refresh();
X	for (loop = MAXWAIT; loop; --loop)
X	{
X		readfoe();
X		if (foe->scratch1 != oldhits)
X			switch (foe->istat)
X			{
X				case RAN:
X					mvprintw(lines++,0,"%s ran away!",foename);
X					goto LEAVE;
X				case STUCK:
X					mvprintw(lines++,0,"%s tried to run away.",foename);
X					goto BOT;
X				case BLEWIT:
X					mvprintw(lines++,0,"%s tried to luckout!",foename);
X					goto BOT;
X				default:
X					temp = foe->scratch1 - oldhits;
X					mvprintw(lines++,0,"%s hit you %.0f times!",foename,temp);
X					myhits -= temp;
X					goto BOT;
X			}
X		sleep(1);
X	}
X
X	/* timeout */
X
X	mvaddstr(22,0,"Timeout: waiting for response.  Do you want to wait? ");
X	refresh();
X	ch = getans("NY", FALSE);
X	move(22,0);
X	clrtobot();
X	if (ch == 'Y')
X		goto WAIT;
X	goto LEAVE;
X
X/* routine to decide what happens next */
X
XBOT:	refresh();
X	if (lines > 21)
X	{
X		more(lines);
X		move(lines = 8,0);
X		clrtobot();
X	}
X	if (foe->istat == KILLED || myhits < 0.0)
X	{
X		updateme();
X		death(stat,foename);
X	}
X	if (foe->istat == KILLED)
X	{
X		myhits = -2;
X		goto LEAVE;	/* main will pick up death */
X	}
X	oldhits = foe->scratch1;
X	if (foe->tampered != oldtags)
X	{
X		oldtags = foe->tampered;
X		goto HITFOE;
X	}
X	goto WAIT;
X
X/* routine to clean up things and leave */
X
XLEAVE:	updateme();
X	stat->x += roll(5,-10);
X	stat->y += roll(5,-10);
X	stat->energy = myhits;
X	stat->tampered = OFF;
X	stat->status = PLAYING;
X	changed = TRUE;
X	more(lines);
X	move(4,0);
X	clrtobot();
X}
X
X/****************************************************************/
X
Xint
Xinterrupt() 	    /* call when break key is hit */
X{
X	char	line[81];
X	reg int loop;
X	int 	x, y, ch;
X
X#ifdef SYS3
X	signal(SIGINT,SIG_IGN);
X#endif
X#ifdef SYS5
X	signal(SIGINT,SIG_IGN);
X#endif
X	getyx(stdscr,y,x);
X	for (loop = 79; loop >= 0; --loop)	/* snarf line */
X	{
X		move(4,loop);
X		line[loop] = inch();
X	}
X	line[80] = '\0';
X	clrtoeol();
X	if (fghting)
X	{
X		move(4,0);
X		clrtoeol();
X		addstr("Quitting now will automatically kill your character. Still want to? ");
X		ch = getans("NY", FALSE);
X		if (ch == 'Y')
X			longjmp(mainenv,DIE);
X	}
X	else
X	{
X		move(4,0);
X		clrtoeol();
X		addstr("Do you really want to quit? ");
X		ch = getans("NY", FALSE);
X		if (ch == 'Y')
X			longjmp(mainenv,QUIT);
X	}
X	mvaddstr(4,0,line); /* return screen to previous state */
X	move(y,x);
X	refresh();
X#ifdef SYS3
X	signal(SIGINT,interrupt);
X#endif
X#ifdef SYS5
X	signal(SIGINT,interrupt);
X#endif
X}
X
X/****************************************************************/
X
Xvoid
Xpurge()     /* remove old players */
X{
X	struct	stats	sbuf;
X	reg int loc, today, temp;
X	long	ltime;
X
X	loc = 0;
X	time(&ltime);
X	today = localtime(&ltime)->tm_yday;
X	fseek(read_pfile,0L,0);
X	while(fread((char *) &sbuf,sizeof(sbuf),1,read_pfile))
X	{
X		temp = today - sbuf.lastused;
X		if (temp < 0)
X			temp += 365;
X		if (temp > 21)	    /* more than three weeks old --> delete */
X		{
X			initchar(&sbuf);
X			strcpy(sbuf.name,"<null>");
X			fseek(access_pfile,(long) (loc * sizeof(sbuf)),0);
X			fwrite((char *) &sbuf,sizeof(sbuf),1,access_pfile);
X			fflush(access_pfile);
X		}
X		++loc;
X	}
X}
TiDDleYwiNKs
	size="`wc -c func2.c`"
	size=`set - $size;echo $1`
echo "x - func2.c, $size characters"

	if test "$size" != "19688"
		then
		echo "Warning: error in transmitting 'func2.c';  should have 19688 characters."
	fi
fi
if test -s "func3.c"
	then
	echo Will not overwrite existing 'func3.c'
else
	sed -e "s/^X//" > func3.c << 'TiDDleYwiNKs'
X/*
X * func3.c	Phantasia support routines
X */
X#include "phant.h"
X
Xjmp_buf btimeout;
Xint catchalarm();
X
Xint
Xgetans(choices, def)	/* get a one character option from keyboard */
X
Xchar	*choices;
Xbool	def;
X{
X	int 	ch, loop, oldx, oldy;
X	char	*cptr;
X	char	command[80];
X
X	getyx(stdscr, oldy, oldx);
X	alarm(0);
X
X	for (loop = 9; loop; --loop)
X		if (setjmp(btimeout))
X			if (def)
X				return(*choices);
X			else if (loop > 1)
X				goto YELL;
X			else
X				break;
X		else
X		{
X			clrtoeol();
X			refresh();
X#ifdef BSD41
X			sigset(SIGALRM, catchalarm);
X#else
X			signal(SIGALRM, catchalarm);
X#endif
X			if (!inshell)	/* wait forever during a shell escape */
X				if (timeout)
X					alarm(7);
X				else
X					alarm(600);
X			ch = getch();
X#ifdef SHELL
X			if (ch == '!')	/* shell escape */
X			{
X				shellcmd();
X				refresh();
X				getans(choices, def);
X			}
X#endif
X			alarm(0);
X			if ((cptr = strchr(choices, toupper(ch))) != NULL)
X				return(*cptr);
X			else if (def)
X				return(toupper(ch));
X			else if (!def && loop > 1)
X			{
XYELL:			mvprintw(oldy+1,0,"Please choose one of : [%s]\n", choices);
X				move(oldy, oldx);
X				clrtoeol();
X				continue;
X			}
X			else
X				break;
X		}
X	return(*choices);
X}
X
X/****************************************************************/
X
Xint
Xcatchalarm()
X{
X	longjmp(btimeout, 1);
X}
X
X/****************************************************************/
X
Xvoid
Xerror(whichfile)
X
Xchar	*whichfile;
X{
X	extern int errno;
X
X	clear();
X	printw("An unrecoverable error has occurred reading %s.   (errno = %d)\n",
X				whichfile, errno);
X	addstr("Please run 'setup' to determine the problem.\n");
X	exit1();
X	/*NOTREACHED*/
X}
X
X/****************************************************************/
X
Xvoid
Xmesg()
X{
X	FILE	*fp;
X	char	s[100];
X
X	move(3,0);
X	clrtoeol();
X	if ((fp = fopen(messfile, "r")) != NULL)
X	{
X		if (fgets(s,100,fp))
X			addstr(s);
X		fclose(fp);
X	}
X}
X
X/****************************************************************/
X
Xdouble
Xdist(x1, x2, y1, y2)
X
Xdouble	x1, x2, y1, y2;
X{
X	double	deltax, deltay;
X
X	deltax = x1 - x2;
X	deltay = y1 - y2;
X	return(sqrt(deltax * deltax + deltay * deltay));
X}
X
X/****************************************************************/
X
Xvoid
Xscoreboard(stat)		    /* enter login into scoreboard */
X
Xreg struct stats *stat;
X{
X	static	struct	sb_ent sbuf;
X	FILE	*fp;
X	reg int loc = 0;
X	bool	found = FALSE;
X
X	if ((fp = fopen(sbfile, "r")) != NULL)
X	{
X		while (fread((char *) &sbuf, sizeof(sbuf), 1, fp))
X			if (!strcmp(stat->login, sbuf.s_login))
X			{
X				found = TRUE;
X				break;
X			}
X			else
X				++loc;
X		fclose(fp);
X	}
X
X	/*
X	 * At this point, 'loc' will either indicate a point beyond
X	 * the end of file, or the place where the previous entry
X	 * was found.
X	 */
X
X	if ((!found) || stat->lvl > sbuf.s_level)
X	{
X		strcpy(sbuf.s_login, stat->login);
X		strcpy(sbuf.s_name, stat->name);
X		sbuf.s_level = stat->lvl;
X		sbuf.s_type = stat->typ;
X	}
X	if ((fp = fopen(sbfile, ACCESS)) == NULL)
X	{
X		error(sbfile);
X		/*NOTREACHED*/
X	}
X	fseek(fp, (long) (loc * sizeof(sbuf)), 0);
X	fwrite((char *) &sbuf, sizeof(sbuf), 1, fp);
X	fclose(fp);
X}
X
X/****************************************************************/
X
Xvoid
Xshow_sb()			/* printout the scoreboard */
X{
X	static	struct	sb_ent	sbuf;
X	FILE	*fp;
X
X	if ((fp = fopen(sbfile, "r")) != NULL)
X		while (fread((char *) &sbuf, sizeof(sbuf), 1, fp))
X			printf("%-20s   Login: %-9s  Level: %6d  Type: %3s\n",
X			sbuf.s_name, sbuf.s_login, sbuf.s_level, ptype('s',sbuf.s_type));
X}
X
X/****************************************************************/
X
Xint
Xill_sig(whichsig)		/* come here on bad signals */
X
Xint whichsig;
X{
X	clear();
X	printw("Error: caught signal # %d.\n", whichsig);
X	exit1();
X	/*NOTREACHED*/
X}
TiDDleYwiNKs
	size="`wc -c func3.c`"
	size=`set - $size;echo $1`
echo "x - func3.c, $size characters"

	if test "$size" != "3649"
		then
		echo "Warning: error in transmitting 'func3.c';  should have 3649 characters."
	fi
fi
if test -s "main.c"
	then
	echo Will not overwrite existing 'main.c'
else
	sed -e "s/^X//" > main.c << 'TiDDleYwiNKs'
X/*
X * Phantasia 3.3.1 -- Interterminal fantasy game
X *
X * Edward A. Estes
X * AT&T, August 28, 1985
X */
X
X/*
X * This version of Phantasia has been heavily hacked by Chris Robertson,
X * September 1985.  Changes include:
X * - lots of cosmetics in the display (alignment, words not numbers, etc.)
X * - added a shell escape 
X * - added HJKL keys for movement (== WSNE) for rogue, vi fans
X * - timeout may be temporarily suspended with ^P (for answering phone etc.)
X * - only SPACE BAR == melee in fighting so you aren't killed by typeahead
X * - M == magic and B == luckout when fighting (commonest answers now
X *      easier to type)
X * - speeded response by keeping the peoplefile and monsterfile always open
X * - "more" accepts a RETURN as well as SPACE BAR
X * - added "is in <wherever>" for non-visible or non-playing characters
X * - neatened up the source code (set up indents, etc. for 4-char tabstop)
X * - threw away RAND because it bombed on at least 2 systems, redid algorithm
X * - characters are purged less frequently (3 weeks)
X * - updated help file appropriately
X *
X * All complaints and suggestions to {decvax, linus, ihnp4}!utzoo!nonh
X *    and DON'T BUG Ted Estes for things I did, please.
X */
X
X/* DISCLAIMER:
X *
X * This game is distributed for free as is.  It is not guaranteed to work
X * in every conceivable environment.  It is not even guaranteed to work
X * in ANY environment.
X *
X * This game is distributed without notice of copyright, therefore it
X * may be used in any manner the recipient sees fit.  However, the
X * author assumes no responsibility for maintaining or revising this
X * game, in its original form, or any derivatives thereof.
X *
X * The author shall not be responsible for any loss, cost, or damage,
X * including consequential damage, caused by reliance on this material.
X *
X * The author makes no warranties, express or implied, including warranties
X * of merchantability or fitness for a particular purpose or use.
X *
X * AT&T is in no way connected with this game.
X */
X
X/*
X * This is the program which drives the whole mess.  Hopefully, you will be
X * able to wade through the garbage if you have to fix something.
X * Several undocumented items exist.  The program checks uid and sets the
X * boolean flag 'su' (super user) if the person is allowed special powers.
X * This only happens if the game is invoked with '-S' as an option.
X * The 'su' may execute any of the valar/council options.  Also,
X * a 'vaporize' option exists to kill anybody at will.	The 'su' can select
X * character type 7, which starts out with the maximum possible in each
X * category.  (The resulting character is an experimento.)  The 'su' may
X * also change the stats of other characters with the -x option (this won't
X * work if they are currently playing! --CMR), or his own stats during play
X * by typing 'A' instead of a movement command.
X */
X
X/*
X * The program allocates as much file space as it needs to store characters,
X * so the possibility exists for the character file to grow without bound.
X * The file is purged upon normal entry to try to avoid that problem.
X * A similar problem exists for energy voids.  To alleviate the problem here,
X * the void file is cleared with every new king.
X */
X
X/*
X * The support functions are split among various files with no apparent
X * order.  Use of 'ctags' is recommended to find a particular function.
X */
X
X/*
X * Put one line of text into the file 'motd' for announcements, etc.
X */
X
X/*
X * If ENEMY is defined, a list of restricted login names is checked
X * in the file 'enemy'.  These names are listed, one per line, with
X * no trailing blanks.  These logins cannot play.
X */
X
X/*
X * The scoreboard file is updated when someone dies, and keeps track
X * of the highest character to date for that login.
X * Being purged from the character file does not cause the scoreboard
X * to be updated.
X */
X
X#include "phant.h"
X
Xdouble	strength, speed;
Xbool	beyond, marsh, throne, valhala, changed, fghting, su, wmhl,
X		inshell, timeout;
Xint 	fileloc, users;
Xjmp_buf fightenv, mainenv;
Xlong	secs;
XFILE	*read_pfile, *access_pfile;		/* pointers to peoplefile */
XFILE	*mfile;							/* pointer to monsterfile */
X
X#ifdef WORM
X/*
X * worm hole map -- This table is carefully set up so that one can always
X * return the way he/she came by inverting the initial path.
X */
Xstruct	worm_hole   w_h[] =
X	{
X	0,0,0,0,		35,22,2,0,		2,2,0,1,		59,34,64,0,
X	54,47,0,60,		50,62,0,56,		19,31,25,0,		0,35,41,41,
X	0,46,40,23,		24,0,29,30,		44,57,56,0,		0,44,39,40,
X	61,41,0,42,		32,0,17,18,		57,0,63,64,		0,33,26,34,
X	48,0,54,55,		28,23,22,13,	63,25,13,19,	34,6,18,20,
X	27,26,19,21,	15,27,20,27,	1,28,34,17,		17,29,8,24,
X	29,9,23,25,		18,30,24,6,		20,32,27,15,	21,20,21,26,
X	22,17,46,29,	23,24,28,9,		25,38,9,31,		6,39,30,32,
X	26,13,31,33,	15,40,32,35,	3,19,15,22,		7,1,33,36,
X	37,37,35,37,	36,36,36,38,	30,42,37,39,	31,43,38,11,
X	33,45,11,8,		12,48,7,7,		38,49,12,43,	39,51,42,44,
X	11,10,43,45,	40,52,44,46,	8,53,45,28,		4,54,51,48,
X	41,16,47,49,	42,55,48,50,	62,5,49,51,		43,56,50,47,
X	45,58,53,53,	46,59,52,52,	47,4,55,16,		49,61,16,54,
X	51,63,5,10,		10,14,59,58,	52,64,57,59,	53,3,58,57,
X	60,60,4,61,		55,12,60,62,	5,50,61,63,		56,18,62,14,
X	58,33,14,3
X	};
X#endif
X
Xmain(argc,argv) 	    /* Phantasia main routine */
X
Xint	argc;
Xchar	*argv[];
X{
X	static	struct	stats	charac;
X	char	aline[200], *login = NULL;
X	double	x = 0.0, y = 0.0;
X	int		ch, ch2, loop, temp;
X	FILE	*fp;
X	bool	shrt = FALSE, examine = FALSE, header = FALSE;
X
X	inshell = FALSE;
X	if ((login = getlogin()) == NULL)
X		login = getpwuid(getuid())->pw_name;
X#ifdef ENEMY
X
X	/* check hit list of restricted accounts */
X
X	if ((fp = fopen(enemyfile, "r")) != NULL)
X	{
X		char	enemy[25];
X
X		while (fscanf(fp, "%s", enemy) != EOF)
X			if (!strcmp(login,enemy))
X			{
X				printf ("The Phantasia privileges for the account '%s' have been revoked.\n", login);
X				printf ("Mail comments to %s.\n", WIZARD);
X				exit (0);
X			}
X			fclose (fp);
X	}
X#endif
X
X	/* get file pointers for peoplefile -- one read, one access */
X
X	if((read_pfile = fopen(peoplefile,"r")) == NULL)
X	{
X		error(peoplefile);
X		exit1();
X	}
X	if((access_pfile = fopen(peoplefile,ACCESS)) == NULL)
X	{
X		error(peoplefile);
X		exit1();
X	}
X
X	/* fp for monsterfile */
X
X	if ((mfile = fopen(monsterfile,"r")) == NULL)
X	{
X		error(monsterfile);
X		exit1();
X	}
X
X	setbuf(stdin, (char *) NULL);   /* this may or may not be necessary */
X	su = FALSE;
X	fghting = FALSE;
X	timeout = FALSE;
X	users = 0;
X	while (--argc && (*++argv)[0] == '-')
X	switch ((*argv)[1])
X	{
X		case 'h':	    /* help */
X			if ((fp = fopen(helpfile, "r")) != NULL)
X			{
X				while (fgets(aline, 200, fp))
X				fputs(aline, stdout);
X				fclose(fp);
X			}
X			exit(0);
X			/*NOTREACHED*/
X		case 's':	    /* short */
X			shrt = TRUE;
X			break;
X		case 'x':	    /* examine */
X			examine = TRUE;
X			break;
X		case 'H':	    /* Header */
X			header = TRUE;
X			break;
X		case 'm':	    /* monsters */
X			printmonster();
X			exit(0);
X			/*NOTREACHED*/
X		case 'a':	    /* all users */
X			showusers(FALSE);
X			exit(0);
X			/*NOTREACHED*/
X		case 'p':	    /* purge old players */
X			purge();
X			exit(0);
X			/*NOTREACHED*/
X		case 'S':
X			su = (getuid() == UID);
X			break;
X		case 'b':
X			show_sb();
X			exit(0);
X			/*NOTREACHED*/
X		}
X	if (!isatty(0)) /* don't let non-tty's play */
X		exit(0);
X	init1();	/* set up for screen stuff */
X	if (examine)
X	{
X		cstat(NULL);
X		exit1();
X		/*NOTREACHED*/
X	}
X	if (!shrt)
X	{
X		titlestuff();
X		purge();    /* clean up old characters */
X	}
X	if (header)
X	{
X		exit1();
X		/*NOTREACHED*/
X	}
X#ifdef OK_TO_PLAY
X	if (!ok_to_play())
X	{
X		mvaddstr(22,27,"Sorry, you can't play now.\n");
X		exit1();
X		/*NOTREACHED*/
X	}
X#endif
X	mvaddstr(22,24,"Do you have a character to run? ");
X	ch = getans("NY", FALSE);
X	if (ch == 'Y')
X		fileloc = findchar(&charac);
X	else
X	{
X		initchar(&charac);
X		clear();
X		mvaddstr(4,21,"Which type of character do you want:");
X		mvaddstr(8,0,"1: Magic User  2: Fighter  3: Elf  4: Dwarf  5:Halfling  6: Experimento  ");
X		ch = getans("1234567", FALSE);
X		do
X		{
X			genchar(&charac,ch);
X			mvprintw(12,14,"Strength:      %2.0f   Quickness:     %2d   Mana:        %3.0f", charac.str,charac.quk,charac.man);
X			mvprintw(13,14,"Energy Level:  %2.0f   Brains:        %2.0f   Magic Level:  %2.0f", charac.energy,charac.brn,charac.mag);
X			if (charac.typ != 6)
X			{
X				mvaddstr(14,14,"Type '1' to keep > ");
X				ch2 = getans(" ", TRUE);
X			}
X			else
X				break;
X		} while (ch2 != '1');
X		if (charac.typ == 6)
X			for (;;)
X			{
X				mvaddstr(16,0,"Enter X Y coordinates for your experimento: ");
X				getstring(aline,80);
X				sscanf(aline,"%F %F",&charac.x,&charac.y);
X				if (abs(charac.x) > 1.2e6 || abs(charac.y) > 1.2e6)
X					mvaddstr(17,0,"Invalid coordinates.  Try again.\n");
X				else
X				break;
X			}
X		for (;;)
X		{
X			mvaddstr(18,0,"Give your character a name [max 20 characters]: ");
X			getstring(aline,80);
X			strncpy(charac.name,aline,20);
X			charac.name[20] = '\0';
X			trunc(charac.name);
X			if (charac.name[0] == '\0')
X				mvaddstr(19,0,"Invalid name.");
X			else if (findname(charac.name, (struct stats *) NULL) >= 0)
X				mvaddstr(19,0,"Name already in use.");
X			else
X				break;
X			addstr("  Pick another.\n");
X		}
X		putchar('\n');
X		fflush(stdout);
X		nocrmode();
X		do
X		{
X			strcpy(charac.pswd,getpass("Give your character a password [max 8 characters]: "));
X			putchar('\n');
X			strcpy(aline,getpass("One more time to verify: "));
X		} while (strcmp(charac.pswd,aline));
X		fileloc = findspace();
X	}
X	crmode();
X	if (charac.status)
X	{
X		clear();
X		addstr("Your character did not exit normally last time.\n");
X		addstr("If you think you have good cause to have your character ");
X		printw("saved,\nyou may quit and mail your reason to '%s'.\n",WIZARD);
X		addstr("Otherwise, continuing spells certain death.\n");
X		addstr("Do you want to quit? ");
X		ch = getans("YN", FALSE);
X		if (ch== 'Y')
X		{
X			charac.tampered = charac.quk;	/* store this away */
X			charac.quk = -100;
X			leave(&charac);
X			/*NOTREACHED*/
X		}
X		death(&charac, "Stupidity");
X	}
X	charac.status = PLAYING;
X	if (charac.lvl > 5)
X		timeout = TRUE;
X	strcpy(charac.login,login);
X	time(&secs);
X	charac.lastused = localtime(&secs)->tm_yday;
X	update(&charac,fileloc);
X	clear();
X#ifdef	BSD41
X	sigset(SIGINT,interrupt);
X#endif
X#ifdef	BSD42
X	signal(SIGINT,interrupt);
X#endif
X#ifdef	SYS3
X	signal(SIGINT,interrupt);
X#endif
X#ifdef	SYS5
X	signal(SIGINT,interrupt);
X#endif
X
X	/* all set for now */
X
X
XTOP:
X	switch (setjmp(mainenv))
X	{
X		case QUIT:
X#ifdef	BSD41
X			sigrelse(SIGINT);
X#endif
X#ifdef	BSD42
X			signal(SIGINT,interrupt);
X#endif
X#ifdef	SYS3
X			signal(SIGINT,interrupt);
X#endif
X#ifdef	SYS5
X			signal(SIGINT,interrupt);
X#endif
X			leave(&charac);
X			/*NOTREACHED*/
X		case DIE:
X#ifdef	BSD41
X			sigrelse(SIGINT);
X#endif
X#ifdef	BSD42
X			signal(SIGINT,interrupt);
X#endif
X#ifdef	SYS3
X			signal(SIGINT,interrupt);
X#endif
X#ifdef	SYS5
X			signal(SIGINT,interrupt);
X#endif
X			death(&charac, "Bailing out");
X			break;
X	}
X#ifdef OK_TO_PLAY
X	if (!ok_to_play())
X	{
X		mvaddstr(6,0,"Whoops!  Can't play now.\n");
X		leave(&charac);
X		/*NOTREACHED*/
X	}
X#endif
X	fghting = FALSE;
X	adjuststats(&charac);
X	if (throne && !charac.crn && (charac.typ < 10 || charac.typ > 20))
X	{
X		mvaddstr(5,0,"You're not allowed in the Lord's Chamber without a crown.\n");
X		changed = TRUE;
X		charac.x = charac.y = 10 + roll(8, 5);
X	}
X	if (charac.status != CLOAKED && abs(charac.x) == abs(charac.y) && 
X	floor(sqrt(fabs(charac.x/100.0))) == sqrt(fabs(charac.x/100.0)) && !throne)
X	{
X		trade(&charac);
X		clear();
X	}
X	checktampered(&charac);
X	checkinterm(&charac);
X	if (charac.energy < 0 || (charac.lvl >= 10000 && charac.typ != 99))
X		death(&charac, "Interterminal battle");
X	neatstuff(&charac);
X	if (changed)
X	{
X		update(&charac,fileloc);
X		changed = FALSE;
X		goto TOP;
X	}
X	mesg();
X	ch='U';
X	printstats(&charac);
X	move(6,0);
X#ifdef WORM
X	if (!wmhl)
X#endif
X	{
X		if (throne)
X			kingstuff(&charac);
X		addstr("1:Move  2:Players  3:Talk  4:Stats  5:Quit  ");
X		if (charac.lvl >= 7 && charac.mag >= 20)
X			addstr("6:Cloak  ");
X		if (charac.lvl >= 12 && charac.mag >= 40)
X			addstr("7:Teleport  ");
X		if (charac.typ > 20)
X			addstr("8:Intervene ");
X		ch = gch(charac.rng.type);
X		if (charac.lvl > 5)		/* will re-set after a ^P */
X			timeout = TRUE;
X		mvaddstr(4,0,"\n\n");
X		if (charac.status == CLOAKED)
X			if (charac.man > 3.0)
X				charac.man -= 3;
X			else
X			{
X				charac.status = PLAYING;
X				changed = TRUE;
X			}
X		move(7,0);
X		/* clrtobot(); */
X		if (charac.typ == 99 && (ch == '1' || ch == '7'))
X			ch = ' ';
X		switch (ch2 = ch)
X		{
X			case 'A':				/* for altering your char if you're su */
X				if (su)
X				{
X					cstat(&charac);
X					goto TOP;
X				}
X				/*FALLTHROUGH*/
X			case '\020':			/* ^P -- suspend the game temporarily */
X				if (timeout)
X					timeout = FALSE;
X				goto TOP;
X				/*NOTREACHED*/
X			case 'K':
X			case 'N':
X				charac.y += maxmove;
X				break;
X			case 'J':
X			case 'S':
X				charac.y -= maxmove;
X				break;
X			case 'L':
X			case 'E':
X				charac.x += maxmove;
X				break;
X			case 'H':
X			case 'W':
X				charac.x -= maxmove;
X				break;
X			default:    /* rest */
X				charac.energy += (charac.mxn+charac.shd)/15+charac.lvl/3+2;
X				charac.energy = min(charac.energy,charac.mxn + charac.shd);
X				if (charac.status != CLOAKED)
X				{
X					charac.man += circ(charac.x,charac.y)/4;
X					charac.man += charac.lvl/6;
X					randattack();
X				}
X				break;
X			case '1':   /* move */
X				for (loop = 3; loop; --loop)
X				{
X					mvaddstr(4,0,"X Y Coordinates: ");
X					getstring(aline,80);
X					if (sscanf(aline,"%F %F",&x,&y) != 2)
X						mvaddstr(5,0,"Try again\n");
X					else if (dist(charac.x, x, charac.y, y) > maxmove)
X						illmove();
X					else
X					{
X						charac.x = x;
X						charac.y = y;
X						break;
X					}
X				}
X				break;
X			case '2':   /* players */
X				printplayers(&charac);
X				break;
X			case '3':   /* message */
X				mvaddstr(4,0,"Message: ");
X				getstring(aline, 80);
X				fp = fopen(messfile, "w");
X				if (*aline)
X					fprintf(fp, "%s: %s", charac.name, aline);
X				fclose(fp);
X				break;
X			case '4':	/* stats */
X				showall(&charac);
X				break;
X			case '5':	/* good-bye */
X				leave(&charac);
X				/*NOTREACHED*/
X			case '6':	/* cloak */
X				if (charac.lvl < 7 || charac.mag < 20)
X					illcmd();
X				else if (charac.status == CLOAKED)
X					charac.status = PLAYING;
X				else if (charac.man < 35)
X				{
X					mvaddstr(5,0,"No power left.\n");
X					refresh();
X				}
X				else
X				{
X					changed = TRUE;
X					charac.man -= 35;
X					charac.status = CLOAKED;
X				}
X				break;
X			case '7':	/* teleport */
X				if (charac.lvl < 12 || charac.mag < 40)
X					illcmd();
X				else for (loop = 3; loop; --loop)
X				{
X					mvaddstr(4,0,"X Y Coordinates: ");
X					getstring(aline,80);
X					if (sscanf(aline,"%F %F",&x,&y) == 2)
X						if ((temp = dist(charac.x,x,charac.y,y)) > (charac.lvl
X								+ charac.mag)*20+((charac.typ > 30) ? 1e+6 : 0)
X								&& !throne)
X							illmove();
X						else if ((temp = (temp/75+1)*20) > charac.man
X											&& !throne)
X							mvaddstr(5,0,"Not enough power for that distance.\n");
X						else
X						{
X							charac.x = x;
X							charac.y = y;
X							if (!throne)
X								charac.man -= temp;
X							break;
X						}
X				}
X				break;
X			case 'C':
X			case '9':	/* monster */
X				if (throne)
X					mvaddstr(5,0,"No monsters in the chamber!\n");
X				else if (charac.typ != 99)
X				{
X					charac.status = PLAYING;
X					changed = TRUE;
X					charac.sin += 1e-6;
X					fight(&charac,-1);
X				}
X				break;
X			case '0':	/* decree */
X				if (su || charac.typ > 10 && charac.typ < 20 && throne)
X					decree(&charac);
X				else
X					illcmd();
X				break;
X			case '8':	/* intervention */
X				if (su || charac.typ > 20)
X					valarstuff(&charac);
X				else
X					illcmd();
X				break;
X			case '\014':    /* redo screen */
X				clear();
X		}
X		if (ch2 == 'E' || ch2 == 'W' || ch2 == 'N' || ch2 == 'S'
X			|| ch2 == 'L' || ch2 == 'H' || ch2 == 'K' || ch2 == 'J'
X			|| ch2 == '1' || ch2 == '7')
X		{
X			checkmov(&charac);
X			randattack();
X			changed = TRUE;
X		}
X	}
X#ifdef WORM
X	else
X	{
X		addstr("F: Forward  B: Back  R: Right  L: Left  Q: Quit  T: Talk P: Players  S: Stats ");
X		ch = getans(" ", TRUE);
X		move(6,0);
X		/* clrtobot(); */
X		if (charac.status == CLOAKED)
X			if (charac.man > 3.0)
X				charac.man -= 3;
X			else
X			{
X				charac.status = PLAYING;
X				changed = TRUE;
X			}
X		switch (ch)
X		{
X			case 'A':				/* for altering your char if you're su */
X				if (su)
X				{
X					cstat(&charac);
X					goto TOP;
X				}
X				/*FALLTHROUGH*/
X			default:	/* rest */
X				charac.energy += (charac.mxn+charac.shd)/15+charac.lvl/3+2;
X				charac.energy = min(charac.energy,charac.mxn + charac.shd);
X				if (charac.status != CLOAKED)
X					charac.man += charac.lvl/5;
X				break;
X			case '\020':			/* ^P -- suspend the game temporarily */
X				if (timeout)
X					timeout = FALSE;
X				goto TOP;
X				/*NOTREACHED*/
X			case 'F':
X				temp = w_h[charac.wormhole].f;
X				goto CHKMOVE;
X			case 'B':
X				temp = w_h[charac.wormhole].b;
X				goto CHKMOVE;
X			case 'R':
X				temp = w_h[charac.wormhole].r;
X				goto CHKMOVE;
X			case 'L':
X				temp = w_h[charac.wormhole].l;
X				goto CHKMOVE;
X			case 'Q':
X				leave(&charac);
X				/*NOTREACHED*/
X			case 'T':
X				mvaddstr(4,0,"Message: ");
X				getstring(aline, 80);
X				fp = fopen(messfile, "w");
X				if (*aline)
X					fprintf(fp, "%s: %s", charac.name, aline);
X				fclose(fp);
X				break;
X			case 'P':
X				printplayers(&charac);
X				break;
X			case 'S':
X				showall(&charac);
X				break;
X			case '\014':    /* redo screen */
X				clear();
X				break;
X		}
X		goto TOP;
XCHKMOVE:
X		if (!temp)
X		{
X			charac.y = 0.0;
X			charac.x = pow(-1.0,(double) charac.wormhole) * charac.wormhole
X								* 400 - 1.0;
X			charac.wormhole = 0;
X			changed = TRUE;
X		}
X		else
X			charac.wormhole = temp;
X		}
X#endif
X	goto TOP;
X}
X
X/*
X * This function is provided to allow one to restrict access to the game.
X * Tailor this routine as appropriate.
X */
X
X#ifdef	OK_TO_PLAY
X#include <sys/types.h>
X#include <utmp.h>   /* used for counting users on system */
X
Xbool
Xok_to_play()	    /* return FALSE if playing is not allowed at this time */
X{
X#define MAXUSERS    30	/* max. number of people on system */
X	reg struct  tm	*tp;
X	reg int numusers = 0;
X	FILE	*fp;
X	long	now;
X	struct	utmp	ubuf;
X
X	if (su)
X		return (TRUE);
X
X	/* check time of day */
X
X	time(&now);
X	tp = localtime(&now);
X	if (((tp->tm_hour > 8 && tp->tm_hour < 12)		/* 8-noon */
X		|| (tp->tm_hour > 12 && tp->tm_hour < 16))	/* 1-4 pm */
X		&& (tp->tm_wday != 0 && tp->tm_wday != 6))	/* not a weekend */
X		return (FALSE);
X
X	/* check # of users */
X
X	if ((fp = fopen("/etc/utmp","r")) != NULL)
X	{
X		while (fread((char *) &ubuf,sizeof(ubuf),1,fp))
X#ifdef	SYS5
X			if (ubuf.ut_type == USER_PROCESS)
X#else
X			if (*ubuf.ut_name)
X#endif
X				++numusers;
X		fclose(fp);
X		if (numusers > MAXUSERS)
X			return (FALSE);
X	}
X	return (TRUE);
X}
X#endif
TiDDleYwiNKs
	size="`wc -c main.c`"
	size=`set - $size;echo $1`
echo "x - main.c, $size characters"

	if test "$size" != "18696"
		then
		echo "Warning: error in transmitting 'main.c';  should have 18696 characters."
	fi
fi
if test -s "monsters"
	then
	echo Will not overwrite existing 'monsters'
else
	sed -e "s/^X//" > monsters << 'TiDDleYwiNKs'
Xa Water Leaper    12      14      16      24      59      0       0     62
Xa Leech           4       19      29      30      66      0       0     73
Xan Urisk          13      30      15      46      127     1       0     3
XShellycoat        28      21      18      63      226     2       0     0
Xa Naiad           21      62      27      58      378     2       0     11
Xa Nixie           22      58      28      108     604     3       0     6
Xa Glaistig        21      106     25      127     1002    3       0     0
Xa Mermaid         18      116     22      108     809     3       0     0
Xa Merman          24      115     23      109     808     4       0     0
Xa Siren           22      128     31      89      915     4       0     24
Xa Lamprey         14      67      33      156     1562    4       15    37
Xa Kopoacinth      26      36      26      206     2006    5       0     20
Xa Kelpie          61      25      24      223     4025    5       0     0
Xan Aspidchelone   114     104     19      898     10041   7       0     2
Xan Idiot          13      14      16      28      49      0       0     0
Xsome Green Slime  1       5       45      100     57      0       0     26
Xa Pixie           11      29      23      26      64      0       0     32
Xa Serpent         10      18      25      25      79      0       0     10
Xa Cluricaun       12      27      20      30      81      0       14    5
Xan Imp            22      30      14      40      92      0       0     1
Xa Centipede       3       8       18      15      33      0       0     61
Xa Beetle          2       11      21      26      44      0       0     48
Xa Fir Darrig      18      22      17      35      107     0       14    1
XModnar            15      23      20      40      101     7       2     12
Xa Gnome           7       45      26      23      111     0       0     21
Xa Sprite          9       37      25      31      132     1       0     43
Xa Mimic           11      55      29      47      213     1       3     2
Xa Kobold          13      10      14      21      121     1       12    68
Xa Spider          6       11      28      28      124     1       0     57
Xan Uldra          14      37      21      32      93      1       0     6
Xa Gnoll           20      25      15      40      166     1       0     61
Xa Bogie           23      28      19      57      189     1       0     57
Xa Fachan          9       40      15      45      139     1       14    10
Xa Moron           3       1       10      10      28      0       0     50
Xan Orc            25      13      16      26      141     1       0     92
Xa Ghillie Dhu     12      16      13      28      104     2       14    2
Xa Bogle           19      15      16      35      157     2       14    15
Xa Shrieker        2       62      27      9       213     2       16    0
Xa Carrion Crawler 12      20      20      65      142     2       0     42
Xa Trow            15      17      23      51      136     2       0     36
Xa Warg            20      10      17      45      152     2       0     88
Xa Stirge          2       6       35      25      153     2       0     95
Xa Crebain         5       11      31      31      82      2       0     81
Xa Killmoulis      30      19      8       75      175     3       14    22
Xa Hob-goblin      35      20      15      72      246     3       0     18
Xa Unicorn         27      57      27      57      627     3       1     0
Xa Fenoderee       16      6       21      65      222     3       0     42
Xan Ogre           42      14      16      115     409     3       0     19
Xa Dodo            62      12      11      76      563     3       0     3
Xa Hydra           14      27      33      99      599     3       0     27
Xa Hamadryad       23      47      26      62      426     3       0     12
Xa Bwca            21      17      19      55      387     3       14    1
Xan Owlbear        35      16      18      100     623     4       0     22
XBlack Annis       37      52      15      65      786     4       0     2
Xa Jello Blob      100     25      7       264     1257    4       0     13
Xa Jubjub Bird     45      23      12      114     1191    4       0     0
Xa Wichtlein       13      40      25      61      800     4       0     8
Xa Cocodrill       39      28      24      206     1438    4       0     38
Xa Troll           75      12      20      185     1013    4       24    29
Xa Bonnacon        89      26      9       255     1661    4       17    14
Xa Gargoyle        22      21      29      200     1753    5       0     7
Xa Chaladrius      8       49      37      172     1929    5       0     20
Xa Gwyllion        27      73      20      65      1888    5       0     4
Xa Cinomulgus      23      2       10      199     263     5       0     18
Xa Peridexion      26      32      24      98      1300    5       0     2
XSmeagol           41      33      27      373     2487    5       18    0
Xa Wraith          52      102     22      200     3112    5       25    13
Xa Snotgurgle      143     19      26      525     4752    6       0     3
Xa Phooka          42      63      21      300     4125    5       0     12
Xa Vortex          101     30      31      500     6992    6       9     4
XShelob            147     64      28      628     5003    7       13    0
Xa Thaumaturgist   35      200     23      400     7628    6       7     0
XSmaug             251     76      26      1022    9877    7       0     0
Xa Cold-drake      301     102     24      1222    10888   7       0     0
Xa Red Dragon      342     141     23      1299    11649   8       0     0
XScatha the Worm   406     208     20      1790    11999   8       0     0
XTiamat            506     381     29      2000    13001   9       11    0
Xa Bandersnatch    105     98      22      450     7981    6       0     3
Xa Harpy           103     49      24      263     7582    6       0     2
Xa Tigris          182     38      17      809     7777    6       0     3
Xa Gryphon         201     45      19      813     8888    7       0     1
Xa Coblynau        205     46      18      585     8333    6       0     2
Xa Chimaera        173     109     28      947     12006   7       0     0
Xa Jack-in-Irons   222     36      12      1000    9119    7       0     0
XSaruman           55      373     17      1500    17101   11      6     0
Xa Balrog          500     100     25      705     8103    7       8     0
XArgus             201     87      14      1500    10010   8       0     0
Xa Titan           302     1483    12      1625    11011   8       0     0
XCacus             256     43      19      1750    12012   8       0     0
XBegion            403     154     10      1875    13013   8       0     0
XGrendel           197     262     23      2000    14014   8       0     0
Xa Nazgul          250     251     26      1011    9988    12      10    9
Xa Succubus        186     1049    27      2007    19984   9       19    0
XRed Cap           143     50      35      1965    23456   9       0     0
Xa Nuckelavee      300     75      20      2185    11111   8       0     0
XCerberus          236     96      29      2600    25862   9       20    0
Xa Jabberwock      185     136     25      2265    23256   9       22    0
XUngoliant         399     2398    37      2784    27849   10      21    0
XLeanan-Sidhe      486     5432    46      3000    30004   9       5     0
Xthe Dark Lord     9999    9999    31      19999   30005   13      4     0
TiDDleYwiNKs
	size="`wc -c monsters`"
	size=`set - $size;echo $1`
echo "x - monsters, $size characters"

	if test "$size" != "7442"
		then
		echo "Warning: error in transmitting 'monsters';  should have 7442 characters."
	fi
fi
if test -s "pathdefs.c"
	then
	echo Will not overwrite existing 'pathdefs.c'
else
	sed -e "s/^X//" > pathdefs.c << 'TiDDleYwiNKs'
X/*
X * pathdefs.c
X *
X * Edit these values to put things in different places.
X */
X
X#include "phant.h"
X
Xchar	monsterfile[] = PATH/monsters",
X		peoplefile[] = PATH/characs",
X		gameprog[] = PATH/phantasia",
X		messfile[] = PATH/mess",
X		lastdead[] = PATH/lastdead",
X		helpfile[] = PATH/phant.help",
X		motd[] = PATH/motd",
X		goldfile[] = PATH/gold",
X		voidfile[] = PATH/void",
X#ifdef ENEMY
X		enemyfile[] = PATH/enemy",
X#endif
X		sbfile[] = PATH/scoreboard";
TiDDleYwiNKs
	size="`wc -c pathdefs.c`"
	size=`set - $size;echo $1`
echo "x - pathdefs.c, $size characters"

	if test "$size" != "450"
		then
		echo "Warning: error in transmitting 'pathdefs.c';  should have 450 characters."
	fi
fi
if test -s "setup.c"
	then
	echo Will not overwrite existing 'setup.c'
else
	sed -e "s/^X//" > setup.c << 'TiDDleYwiNKs'
X/*
X * setup.c  Program to set up all files for Phantasia
X *
X *	This program tries to verify the parameters specified in
X *	the Makefile.  Since Phantasia assumes its files exist,
X *	simple errors can result in core dumps.
X *
X *	This program tries to check against this.
X * 
X *	Note that this is not fool-proof, and that this could
X *	be much more clever in checking everything.
X *	Hopefully, someone will enhance this someday.
X */
X
X#include "phant.h"
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#ifdef SMALL
X#define rnd()			    	((rand () % 1000)/1000.0)
X#endif
X
Xmain(argc,argv) 		/* program to init. files for Phantasia */
X
Xint argc;
Xchar	**argv;
X{
X	FILE	*fp;
X	struct	stats	sbuf;
X	struct	energyvoid grail;
X	struct	stat	fbuf;
X	register    int loop;
X	char	stbuf[128];
X	long	ltmp;
X
X	srand((int) time(NULL));	/* prime random numbers */
X	umask(077);
X
X	/* check where Phantasia lives */
X
X	if (stat(PATH",&fbuf) < 0)
X	{
X		perror(PATH");
X		exit(1);
X		/*NOTREACHED*/
X	}
X	if (fbuf.st_mode & S_IFDIR == 0)
X		Error("%s is not a directory.\n",PATH");
X
X	/* try to create data files */
X
X	if ((fp = fopen(goldfile,"w")) == NULL)
X		Error("cannot create %s.\n",goldfile);
X	else
X		fclose(fp);
X	if ((fp = fopen(motd,"w")) == NULL)
X		Error("cannot create %s.\n",motd);
X	else
X		fclose(fp);
X	if ((fp = fopen(messfile,"w")) == NULL)
X		Error("cannot create %s.\n",messfile);
X	else
X		fclose(fp);
X
X	/* do not reset character file if it already exists */
X
X	if (stat(peoplefile,&fbuf) < 0)
X	{
X		buildchar(&sbuf);
X		strcpy(sbuf.name,"<null>");
X		if ((fp = fopen(peoplefile,"w")) == NULL)
X			Error("cannot create %s.\n",peoplefile);
X		else
X		{
X			fwrite(&sbuf,sizeof(sbuf),1,fp);
X			fclose(fp);
X		}
X	}
X	grail.active = TRUE;
X	grail.v_x = roll(-1.0e6,2.0e6);
X	grail.v_y = roll(-1.0e6,2.0e6);
X	if ((fp = fopen(voidfile,"w")) == NULL)
X		Error("cannot create %s.\n",voidfile);
X	else
X	{
X		fwrite(&grail,sizeof(grail),1,fp);
X		fclose(fp);
X	}
X	if ((fp = fopen(lastdead,"w")) == NULL)
X		Error("cannot create %s.\n",lastdead);
X	else
X		fclose(fp);
X#ifdef ENEMY
X	if ((fp = fopen(enemyfile,"w")) == NULL)
X		Error("cannot create %s.\n",enemyfile);
X	else
X		fclose(fp);
X#endif
X	if ((fp = fopen(sbfile,"w")) == NULL)
X		Error("cannot create %s.\n",sbfile);
X	else
X		fclose(fp);
X	if (getuid() != UID)
X		fprintf(stderr,"Warning: UID (%d) is not equal to current uid.\n",UID);
X	exit(0);
X}
X
Xbuildchar(stat) 	    /* put in some default values */
X/* Note that this function is almost the same as initchar().
X	It is used to insure that unexpected values will not be found in a
X	new character file.				*/
Xstruct	stats	*stat;
X{
X	stat->x = roll(-125,251);
X	stat->y = roll(-125,251);
X	stat->exp = stat->lvl = stat->sin = 0;
X	stat->crn = stat->psn = 0;
X	stat->rng.type = NONE;
X	stat->rng.duration = 0;
X	stat->pal = FALSE;
X	stat->hw = stat->amu = stat->bls = 0;
X	stat->chm = 0;
X	stat->gem = 0.1;
X	stat->gld = roll(25,50) + roll(0,25) + 0.1;
X	stat->quks = stat->swd = stat->shd = 0;
X	stat->vrg = FALSE;
X	stat->typ = 0;
X}
X
XError(str,file)     /* print an error message, and exit */
Xchar	*str, *file;
X{
X	fprintf(stderr,"Error: ");
X	fprintf(stderr,str,file);
X	exit(1);
X	/*NOTREACHED*/
X}
TiDDleYwiNKs
	size="`wc -c setup.c`"
	size=`set - $size;echo $1`
echo "x - setup.c, $size characters"

	if test "$size" != "3123"
		then
		echo "Warning: error in transmitting 'setup.c';  should have 3123 characters."
	fi
fi