[net.sources] Phantasia

ksl@hou2e.UUCP (09/06/84)

[You saved that file which took 7 blocks and it doesn't work?]
[Yup.]
[Ha, ha, ha, ha, ha]

Well that's what it's like.  The game Phantasia (whoever
posted it) DOES NOT WORK!!!

ROAR
[In case you don't know, that's a dragon flame]
	 > > > > > > > > > > 
[Did you see that flame whiz by at 9600 baud?]
	 > > > > > > > > > > 
[There's another!]

estes@tty3b.UUCP (8-01-83"Edward E 9723i) (09/08/84)

----------CUT-----------CUT------------CUT------------CUT---------CUT--------
: This is a shar archieve.  Extract with sh, not csh.
: The rest of this file will extract:
: func0.c func1.c
echo extracting - func0.c
sed 's/^X//' > func0.c << '!EOR!'
X/*
X * func0.c	Phantasia support routines
X */
X
X#include "phant.h"
X
Xvoid	treasure(stat,treastyp,size)		/* select a treasure */
Xreg	struct	stats	*stat;
Xshort	treastyp;
Xreg	int	size;
X{
Xreg	int	which;
Xint	ch;
Xdouble	temp, temp2;
Xchar	aline[35];
XFILE	*fp;
X
X	which = roll(1,3);
X	move(3,0);
X	clrtobot();
X	move(5,0);
X	if (rnd() > 0.65)	/* gold and gems */
X		if (treastyp > 7)	/* gems */
X			{
X			temp = roll(1,(treastyp - 7)*(treastyp - 7)*(size - 1)/4);
X			printw("You have discovered %.0f gems!  Will you pick them up ? ",temp);
X			ch = rgetch();
X			addch('\n');
X			if (toupper(ch) == 'Y')
X				if (rnd() < treastyp/40 + 0.05)	/* cursed */
X					{
X					addstr("They were cursed!\n");
X					goto CURSE;
X					}
X				else
X					stat->gem += temp;
X			return;
X			}
X		else	/* gold */
X			{
X			temp = roll(treastyp*10,treastyp*treastyp*10*(size - 1));
X			printw("You have found %.0f gold pieces.  Do you want to pick them up ? ",temp);
X			ch = rgetch();
X			addch('\n');
X			if (toupper(ch) == 'Y')
X				if (rnd() < treastyp/35 + 0.04)	/* cursed */
X					{
X					addstr("They were cursed!\n");
X					goto CURSE;
X					}
X				else
X					{
X					stat->gld += floor(0.9 * temp);
X					fp = fopen(goldfile,"r");
X					fread((char *) &temp2,sizeof(double),1,fp);
X					fclose(fp);
X					fp = fopen(goldfile,"w");
X					temp2 += floor(temp/10);
X					fwrite((char *) &temp2,sizeof(double),1,fp);
X					fclose(fp);
X					}
X			return;
X			}
X	else	/* other treasures */
X		{
X		addstr("You have found some treasure.  Do you want to inspect it ? ");
X		ch = rgetch();
X		addch('\n');
X		if (toupper(ch) != 'Y')
X			return;
X		else
X			if (rnd() < 0.08 && treastyp != 4)
X				{
X				addstr("It was cursed!\n");
X				goto CURSE;
X				}
X			else
X				switch(treastyp)
X					{
X					case 1:
X						switch(which)
X							{
X							case 1:
X								addstr("You've discovered a power booster!\n");
X								stat->man += roll(size*4,size*30);
X								break;
X							case 2:
X								addstr("You have encountered a druid.\n");
X								stat->exp += roll(0,2000 + size*400);
X								break;
X							case 3:
X								addstr("You have found a holy orb.\n");
X								stat->sin = max(0,stat->sin - 0.25);
X								break;
X							}
X						break;
X					case 2:
X						switch (which)
X							{
X							case 1:
X								addstr("You have found an amulet.\n");
X								++stat->amu;
X								break;
X							case 2:
X								addstr("You've found some holy water!\n");
X								++stat->hw;
X								break;
X							case 3:
X								addstr("You've met a hermit!\n");
X								stat->sin *= 0.75;
X								stat->man += 12*size;
X								break;
X							}
X						break;
X					case 3:
X						switch (which)
X							{
X							case 1:
X								temp = roll(7,30 + size/10);
X								printw("You've found a +%.0f shield!\n",temp);
X								if (temp >= stat->shd)
X									stat->shd = temp;
X								else
X									somebetter();
X								break;
X							case 2:
X								addstr("You have rescued a virgin.  Will you be honorable ? ");
X								ch = rgetch();
X								if (toupper(ch) == 'Y')
X									stat->vrg = TRUE;
X								else
X									{
X									stat->exp += 2000*size;
X									++stat->sin;
X									}
X								break;
X							case 3:
X								addstr("You've discovered some athelas!\n");
X								--stat->psn;
X								break;
X							}
X						break;
X					case 4:
X						addstr("You've found a scroll.  Will you read it ? ");
X						ch = rgetch();
X						addch('\n');
X						if (toupper(ch) == 'Y')
X							switch ((int) roll(1,6))
X								{
X								case 1:
X									addstr("It throws up a shield for you next monster.\n");
X									paws(8);
X									longjmp(fightenv,2);
X									/*NOTREACHED*/
X								case 2:
X									addstr("It makes you invisible for you next monster.\n");
X									paws(8);
X									speed = 1e6;
X									longjmp(fightenv,0);
X									/*NOTREACHED*/
X								case 3:
X									addstr("It increases your strength ten fold to fight your next monster.\n");
X									paws(8);
X									strength *= 10;
X									longjmp(fightenv,0);
X									/*NOTREACHED*/
X								case 4:
X									addstr("It is a general knowledge scroll.\n");
X									stat->brn += roll(2,size);
X									stat->mag += roll(1,size/2);
X									break;
X							case 5:
X								addstr("It tells you how to pick your next monster.\n");
X								addstr("Which monster do you want [0-99] ? ");
X								which = inflt();
X								which = min(99,max(0,which));
X								fight(stat,which);
X								break;
X							case 6:
X								addstr("It was cursed!\n");
X								goto CURSE;
X							}
X						break;
X					case 5:
X						switch (which)
X							{
X							case 1:
X								temp = roll(size/4+5,size/2 + 9);
X								printw("You've discovered a +%.0f dagger.\n",temp);
X								if (temp >= stat->swd)
X									stat->swd = temp;
X								else
X									somebetter();
X								break;
X							case 2:
X								temp = roll(7.5 + size*3,size * 2 + 160);
X								printw("You have found some +%.0f armour!\n",temp);
X								if (temp >= stat->shd)
X									stat->shd = temp;
X								else
X									somebetter();
X								break;
X							case 3:
X								addstr("You've found a tablet.\n");
X								stat->brn += 4.5*size;
X								break;
X							}
X						break;
X					case 6:
X						switch (which)
X							{
X							case 1:
X								addstr("You've found a priest.\n");
X								stat->nrg = stat->mxn + stat->shd;
X								stat->sin /= 2;
X								stat->man += 24*size;
X								stat->brn += size;
X								break;
X							case 2:
X								addstr("You have come upon Robin Hood!\n");
X								stat->shd += size*2;
X								stat->str += size/2.5 + 1;
X								break;
X							case 3:
X									temp = roll(2 + size/4,size/1.2 + 10);
X								printw("You have found a +%.0f axe!\n",temp);
X								if (temp >= stat->swd)
X									stat->swd = temp;
X								else
X									somebetter();
X								break;
X							}
X						break;
X					case 7:
X						switch (which)
X							{
X							case 1:
X								addstr("You've discovered a charm!\n");
X								++stat->chm;
X								break;
X							case 2:
X								addstr("You have encountered Merlyn!\n");
X								stat->brn += size + 5;
X								stat->mag += size/3 + 5;
X								stat->man += size*10;
X								break;
X							case 3:
X								temp = roll(5+size/3,size/1.5 + 20);
X								printw("You have found a +%.0f war hammer!\n",temp);
X								if (temp >= stat->swd)
X									stat->swd = temp;
X								else
X									somebetter();
X								break;
X							}
X						break;
X					case 8:
X						switch (which)
X							{
X							case 1:
X								addstr("You have found a healing potion.\n");
X								stat->psn = min(-2,stat->psn-2);
X								break;
X							case 2:
X								addstr("You have discovered a transporter.  Do you wish to go anywhere ? ");
X								ch = rgetch();
X								addch('\n');
X								if (toupper(ch) == 'Y')
X									{
X									addstr("X Y Coordinates ? ");
X									getstring(aline,80);
X									sscanf(aline,"%F %F",&stat->x,&stat->y);
X									stat->x = floor(stat->x);
X									stat->y = floor(stat->y);
X									}
X								break;
X							case 3:
X								temp = roll(10 + size/1.2,size*3 + 30);
X								printw("You've found a +%.0f sword!\n",temp);
X								if (temp >= stat->swd)
X									stat->swd = temp;
X								else
X									somebetter();
X								break;
X							}
X						break;
X					case 10:
X					case 11:
X					case 12:
X					case 13:
X						if (rnd() < 0.33)
X							{
X							if (treastyp == 10)
X								{
X								addstr("You've found a pair of elven boots!\n");
X								stat->quk += 2;
X								break;
X								}
X							else if (treastyp == 11 && !stat->pal)
X								{
X								addstr("You've acquired Saruman's palantir.\n");
X								stat->pal = TRUE;
X								break;
X								}
X							else if (!stat->rng.type && stat->typ < 20 && (treastyp == 12 || treastyp == 13))
X								{
X								if (treastyp == 12)
X									if (rnd() < 0.8)
X										{
X										which = NAZREG;
X										temp = 15;
X										}
X									else
X										{
X										which = NAZBAD;
X										temp = 10 + rngcalc(stat->typ) + roll(0,5);
X										}
X								else
X									if (rnd() > 0.9)
X										{
X										which = DLREG;
X										temp = 0;
X										}
X									else
X										{
X										which = DLBAD;
X										temp = 15 + rngcalc(stat->typ) + roll(0,5);
X										}
X									addstr("You've discovered a ring.  Will you pick it up ? ");
X									ch = rgetch();
X									addch('\n');
X									if (toupper(ch) == 'Y')
X										{
X										stat->rng.type = which;
X										stat->rng.duration = temp;
X										}
X								}
X							break;
X							}
X						case 9:
X							switch (which)
X								{
X								case 1:
X									if (!(stat->lvl > 1000 || stat->crn > floor((double) stat->lvl/100)
X											|| stat->lvl < 10))
X										{
X										addstr("You have found a golden crown!\n");
X										++stat->crn;
X										break;
X										}
X								case 2:
X									addstr("You've been blessed!\n");
X									stat->bls = TRUE;
X									stat->sin /=3;
X									stat->nrg = stat->mxn + stat->shd;
X									stat->man += 100*size;
X									break;
X								case 3:
X									temp = roll(1,size/5+5);
X									temp = min(temp,99);
X									printw("You have discovered some +%.0f quicksilver!\n",temp);
X									if (temp >= stat->quks)
X										stat->quks = temp;
X									else
X										somebetter();
X									break;
X								}
X							break;
X						}
X		refresh();
X		return;
X		}
XCURSE:	if (stat->chm)
X		{
X		addstr("But your charm saved you!\n");
X		--stat->chm;
X		}
X	else if (stat->amu)
X		{
X		addstr("But your amulet saved you!\n");
X		--stat->amu;
X		}
X	else
X		{
X		stat->nrg = (stat->mxn + stat->shd)/10;
X		stat->psn += 0.25;
X		}
X}
X
Xvoid	callmonster(which,size,mons)		/* fill a structure with monster 'which' of size 'size' */
Xreg	int	which, size;
Xreg	struct	mstats	*mons;
X{
XFILE	*fp;
Xchar	instr[100];
X
X	which = min(which,99);
X	fp = fopen(monsterfile,"r");
X	for (++which; which; --which)
X		fgets(instr,100,fp);
X	strncpy(mons->name,instr,24);
X	mons->name[24] = '\0';
X	sscanf(instr + 24,"%F%F%F%F%F%d%d%d",&mons->str,&mons->brn,&mons->spd,&mons->hit,
X		&mons->exp,&mons->trs,&mons->typ,&mons->flk);
X	if (mons->typ == 2)	/* Modnar */
X		{
X		mons->str *= rnd() + 0.5;
X		mons->brn *= rnd() + 0.5;
X		mons->spd *= rnd() + 0.5;
X		mons->hit *= rnd() + 0.5;
X		mons->exp *= rnd() + 0.5;
X		mons->trs *= rnd();
X		}
X	else if (mons->typ == 3)	/* mimic */
X		{
X		fseek(fp,0L,0);
X		for (which = roll(0,100); which; --which)
X			fgets(instr,100,fp);
X		strncpy(mons->name,instr,24);
X		}
X	trunc(mons->name);
X	mons->str += (size-1)*mons->str/2;
X	mons->brn *= size;
X	mons->spd += size * 1.e-9;
X	mons->hit *= size;
X	mons->exp *= size;
X	fclose(fp);
X}
X
Xstruct	/* lookup table for rolling stats and making increases upon gaining levels */
X	{
X	struct
X		{
X		int	base;
X		int	interval;
X		float	increase;
X		} quick,      strength,      manna,	    energy,	   brains,	  magic;
X	} table[7] =
X		{
X/* mag. usr: */ 30, 6, 0.0,   20, 6, 2.0,    50,51,75.0,    30,16,20.0,    60,26, 6.0,	  5, 5,2.75,
X/* fighter:  */ 30, 6, 0.0,   40,16, 3.0,    30,21,40.0,    45,26,30.0,    25,21, 3.0,	  3, 4, 1.5,
X/* elf:      */ 32, 7, 0.0,   35,11, 2.5,    45,46,65.0,    30,21,25.0,    40,26, 4.0,	  4, 4, 2.0,
X/* dwarf:    */ 25, 6, 0.0,   45,21, 5.0,    25,21,30.0,    60,41,35.0,    20,21, 2.5,	  2, 4, 1.0,
X/* halfling: */ 34, 0, 0.0,   20, 6, 2.0,    25,21,30.0,    55,36,30.0,    40,36, 4.5,	  1, 4, 1.0,
X/* exprmnto: */ 27, 0, 0.0,   25, 0, 0.0,    100,0, 0.0,    35, 0, 0.0,    25, 0, 0.0,	  2, 0, 0.0,
X/* super:    */ 38, 0, 0.0,   65, 0, 0.0,    100,0, 0.0,    80, 0, 0.0,    85, 0, 0.0,	  9, 0, 0.0
X		};
X
Xvoid	genchar(res,type)				/* init a charac struct */
Xint	type;
Xreg	struct	stats	*res;
X{
Xregister int	subscript;
X
X	if (type < '1' || type > '6')
X		if (type != '7' || !su)
X			type = '2';	/* fighter is default */
X	subscript = type - '1';
X	res->quk = roll(table[subscript].quick.base,table[subscript].quick.interval);
X	res->str = roll(table[subscript].strength.base,table[subscript].strength.interval);
X	res->man = roll(table[subscript].manna.base,table[subscript].manna.interval);
X	res->mxn = res->nrg = roll(table[subscript].energy.base,table[subscript].energy.interval);
X	res->brn = roll(table[subscript].brains.base,table[subscript].brains.interval);
X	res->mag = roll(table[subscript].magic.base,table[subscript].magic.interval);
X	res->typ = subscript;
X	if (subscript < 6)
X		++res->typ;
X	if (type == '5')
X		res->exp = roll(600,200);	/* give halfling some exp. */
X}
X
Xvoid	movelvl(stat)				/* update stats for new level */
Xreg	struct	stats	*stat;
X{
Xreg	int	type;
Xreg	unsigned new;
Xdouble	inc;
X
X	changed = TRUE;
X	type = abs(stat->typ);
X	if (type < 6)
X		;	/* normal */
X	else if (type < 10)
X		type = roll(1,5);	/* experimento */
X	else if (type < 20)
X		{
X		type -= 10;	/* king */
X		if (type > 5)
X			type = roll(1,5);	/* experimento */
X		}
X	else if (type < 26)
X		type -= 20;	/* council of wise */
X	else
X		type = roll(1,5);	/* everything else */
X	new = level(stat->exp);
X	inc = new - stat->lvl;
X	--type; 		/* set up for subscripting into table */
X	stat->str += table[type].strength.increase * inc;
X	stat->man += table[type].manna.increase * inc;
X	stat->brn += table[type].brains.increase * inc;
X	stat->mag += table[type].magic.increase * inc;
X	stat->mxn += table[type].energy.increase * inc;
X	stat->nrg = stat->mxn + stat->shd;
X	if ((stat->lvl = min(10000,new)) >= 1000)
X		{	/* no longer able to be king */
X		stat->gld += stat->crn * 5000;
X		stat->crn = 0;
X		stat->typ = abs(stat->typ);
X		}
X	if (stat->lvl >= 3000 && stat->typ < 20)
X		{	/* make a member of the council */
X		mvaddstr(6,0,"You have made it to the Council of the Wise.\nGood Luck on your search for the Holy Grail.\n");
X		stat->rng.type = 0;
X		stat->rng.duration = 3;
X		stat->typ = abs(stat->typ) + (stat->typ > 10 ? 10 :20);
X		}
X}
X
Xchar	*printloc(x,y)			/* return a pointer to a string specifying location */
Xdouble	x,y;		/* also, set some global flags */
X{
Xreg	int	size, loc;
Xreg	char	*label;
Xstatic	char	res[80],
X		*nametable[4][4] =	 /* names of places */
X		{
X		"Anorien",	"Ithilien",	"Rohan",	"Lorien",
X		"Gondor",	"Mordor",	"Dunland",	"Rovanion",
X		"South Gondor", "Khand",	"Eriador",	"The Iron Hills",
X		"Far Harad",	"Near Harad",	"The Northern Waste", "Rhun"
X		};
X
X	throne = beyond = marsh = FALSE;
X	if (wmhl)
X		return (strcpy(res," is in the Wormholes"));
X	else if (valhala)
X		return (strcpy(res," is in Valhala"));
X	else if ((size = circ(x,y)) >= 1000)
X		{
X		if (max(abs(x),abs(y)) > 1100000)
X			{
X			label = "The Point of No Return";
X			beyond = TRUE;
X			}
X		else
X			label = "The Ashen Mountains";
X		}
X	else if (size >= 55)
X		label = "Morannon";
X	else if (size >= 35)
X		label = "Kennaquahair";
X	else if (size >= 20)
X		{
X		label = "The Dead Marshes";
X		marsh = TRUE;
X		}
X	else if (size >= 9)
X		label = "The Outer Waste";
X	else if (size >= 5)
X		label = "The Moors Adventurous";
X	else
X		{
X		if (!x && !y)
X			{
X			label = "The Lord's Chamber";
X			throne = TRUE;
X			}
X		else
X			{
X			loc = (x > 0) + 2 * (y >= 0);
X			label = nametable[size-1][loc];
X			}
X		}
X	sprintf(res," is in %s  (%.0f,%.0f)",label,x,y);
X	return (res);
X}
X
Xvoid	initchar(stat)				/* put in some default values */
Xreg	struct	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->blind = stat->vrg = 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->typ = 0;
X	stat->status = stat->tampered = OFF;
X	stat->scratch1 = stat->scratch2 = 0.0;
X	stat->wormhole = 0;
X	stat->age = 0;
X	stat->degen = 1;
X}
X
Xvoid	trade(stat)				/* trading post */
Xreg	struct	stats	*stat;
X{
Xstatic	struct
X		{
X		char	*item;
X		int	cost;
X		}	menu[] =
X			{
X			"Manna",1,
X			"Shield",5,
X			"Book",200,
X			"Sword",500,
X			"Charm",1000,
X			"Quiksilver",2500,
X			"Blessing",7000,
X			"Gem",1000	/* this is only to ease changing the value of gems */
X			};
Xdouble	temp;
Xint	ch;
Xreg	int	size, loop;
Xbool	cheat = FALSE;
X
X	changed = TRUE;
X	clear();
X	addstr("You are at a trading post. All purchases must be made with gold.");
X	size = sqrt(abs(stat->x/100)) + 1;
X	size = min(7,size);
X	mvprintw(4,0,"L:Leave  P:Purchase  S:Sell Gems ? ");
X	move(6,0);
X	for (loop = 0; loop < size; ++loop)
X		printw("(%d) %-10s: %6d\n",loop+1,menu[loop].item,menu[loop].cost);
XPROMPT:	mvprintw(1,0,"Gold:  %9.0f  Gems:  %9.0f  Level:   %6u  Charms: %6d\n",stat->gld,stat->gem,stat->lvl,stat->chm);
X	printw("Shield:%9.0f  Sword: %9.0f  Quicksilver:%3d  Blessed: %s",
X		stat->shd,stat->swd,stat->quks,(stat->bls ? " True" : "False"));
X	move(4,36);
X	ch = rgetch();
X	move(15,0);
X	clrtobot();
X	switch(toupper(ch))
X		{
X		case 'L':
X		case '\n':
X			stat->x -= floor(stat->x/10);
X			stat->y -= floor(stat->y/10);
X			return;
X		case 'P':
X			mvaddstr(15,0,"What what would you like to buy ? ");
X			ch = rgetch();
X			move(15,0);
X			clrtoeol();
X			if (ch - '0' > size)
X				addstr("Sorry, this merchant doesn't have that.");
X			else
X				switch (toupper(ch))
X					{
X					case '1':
X						printw("Manna is one per %d gold piece.  How many do you want (%.0f max) ? ",menu[0].cost,floor(stat->gld/menu[0].cost));
X						temp = inflt();
X						if (temp * menu[0].cost > stat->gld || temp < 0)
X							goto CHEAT;
X						else
X							{
X							stat->gld -= floor(temp) * menu[0].cost;
X							if (rnd() < 0.02)
X								goto DISHON;
X							else
X								stat->man += floor(temp);
X							}
X						break;
X					case '2':
X						printw("Shields are %d per +1.  How many do you want (%.0f max) ? ",menu[1].cost,floor(stat->gld/menu[1].cost));
X						temp = inflt();
X						if (!temp)
X							break;
X						if (temp * menu[1].cost > stat->gld || temp < 0)
X							goto CHEAT;
X						else
X							{
X							stat->gld -= floor(temp) * menu[1].cost;
X							if (rnd() < 0.02)
X								goto DISHON;
X							else
X								stat->shd = floor(temp);
X							}
X						break;
X					case '3':
X						printw("A book costs %d gp.  How many do you want (%.0f max) ? ",menu[2].cost,floor(stat->gld/menu[2].cost));
X						temp = inflt();
X						if (temp * menu[2].cost > stat->gld || temp < 0)
X							goto CHEAT;
X						else
X							{
X							stat->gld -= floor(temp) * menu[2].cost;
X							if (rnd() < 0.02)
X								goto DISHON;
X							else
X								if (rnd()*temp > stat->lvl/10 && temp != 1)
X									{
X									printw("\nYou blew your mind!\n");
X									stat->brn /= 5;
X									}
X								else
X									stat->brn += floor(temp)*roll(25,10);
X							}
X						break;
X					case '4':
X						printw("Swords are %d gp per +1.  How many + do you want (%.0f max) ? ",menu[3].cost,floor(stat->gld/menu[3].cost));
X						temp = inflt();
X						if (!temp)
X							break;
X						if (temp * menu[3].cost > stat->gld || temp < 0)
X							goto CHEAT;
X						else
X							{
X							stat->gld -= floor(temp) * menu[3].cost;
X							if (rnd() < 0.02)
X								goto DISHON;
X							else
X								stat->swd = floor(temp);
X							}
X						break;
X					case '5':
X						printw("A charm costs %d gp.  How many do you want (%.0f max) ? ",menu[4].cost,floor(stat->gld/menu[4].cost));
X						temp = inflt();
X						if (temp * menu[4].cost > stat->gld || temp < 0)
X							goto CHEAT;
X						else
X							{
X							stat->gld -= floor(temp) * menu[4].cost;
X							if (rnd() < 0.02)
X								goto DISHON;
X							else
X								stat->chm += floor(temp);
X							}
X						break;
X					case '6':
X						printw("Quicksilver is %d gp per +1.  How many + do you want (%.0f max) ? ",menu[5].cost,floor(stat->gld/menu[5].cost));
X						temp = inflt();
X						if (!temp)
X							break;
X						if (temp * menu[5].cost > stat->gld || temp < 0)
X							goto CHEAT;
X						else
X							{
X							stat->gld -= floor(temp) * menu[5].cost;
X							if (rnd() < 0.02)
X								goto DISHON;
X							else
X								stat->quks = min(99,floor(temp));
X							}
X						break;
X					case '7':
X						printw("A blessing requires a %d gp donation.  Still want one ? ",menu[6].cost);
X						ch = rgetch();
X						if (toupper(ch) == 'Y')
X							if (stat->gld < menu[6].cost)
X								goto CHEAT;
X							else
X								{
X								stat->gld -= menu[6].cost;
X								if (rnd() < 0.02)
X									goto DISHON;
X								else
X									stat->bls = TRUE;
X								}
X						break;
X					}
X			break;
X		case 'S':
X			mvprintw(15,0,"A gem is worth %d gp.  How many do you want to sell (%.0f max) ? ",menu[7].cost,stat->gem);
X			temp = inflt();
X			if (temp > stat->gem || temp < 0)
X				goto CHEAT;
X			else
X				{
X				stat->gem -= floor(temp);
X				stat->gld += floor(temp) * menu[7].cost;
X				}
X		}
X	goto PROMPT;
X
XCHEAT:	move(17,0);
X	if (!cheat)
X		{
X		addstr("Come on, merchants aren't stupid.  Stop cheating.\n");
X		cheat = TRUE;
X		goto PROMPT;
X		}
X	else
X		{
X		addstr("You had your chance.  This merchant happens to be\n");
X		printw("a %.0f level magic user, and you made %s mad!\n",roll(size*10,size*20),(rnd() < 0.5) ? "him" : "her");
X		stat->x += roll(-250,500)*size;
X		stat->y += roll(-250,500)*size;
X		stat->nrg = min(size*20,stat->mxn);
X		++stat->sin;
X		paws(23);
X		}
X	return;
X
XDISHON:	mvaddstr(17,0,"The merchant stole your money!");
X	refresh();
X	stat->x -= floor(stat->x/10);
X	stat->y -= floor(stat->y/10);
X	sleep(2);
X}
X
Xvoid	printstats(stat)				/* show characteristics */
Xreg	struct	stats	*stat;
X{
X	mvprintw(0,0,"%s%s\n",stat->name,printloc(stat->x,stat->y));
X	mvprintw(1,0,"Level :%7u   Energy  :%9.0f(%9.0f)  Manna:%9.0f  Users:%3d\n",
X		stat->lvl,stat->nrg,stat->mxn + stat->shd,stat->man,users);
X	mvprintw(2,0,"Quick :%3.0f(%3d)  Strength:%9.0f(%9.0f)  Gold :%9.0f    ",
X		speed,stat->quk + stat->quks,strength,stat->str + stat->swd,stat->gld);
X	switch (stat->status)
X		{
X		case PLAYING:
X			if (stat->nrg < 0.2 * (stat->mxn + stat->shd))
X				addstr("Low Energy\n");
X			else if (stat->blind)
X				addstr("Blind\n");
X			else
X				clrtoeol();
X			break;
X		case CLOAKED:
X			addstr("Cloaked\n");
X			break;
X		case INBATTLE:
X			addstr("In Battle\n");
X			break;
X		case OFF:
X			addstr("Off\n");
X		}
X}
X
Xvoid	showall(stat)				/* show special items */
Xreg	struct	stats	*stat;
X{
Xstatic	char	*flags[] =
X			{
X			"False",
X			" True"
X			};
X
X	mvprintw(6,0,"Type: %3d  --  ",stat->typ);
X	switch (abs(stat->typ))
X		{
X		case 1:
X		case 11:
X		case 21:
X			addstr("Magic User");
X			break;
X		case 2:
X		case 12:
X		case 22:
X			addstr("Fighter");
X			break;
X		case 3:
X		case 13:
X		case 23:
X			addstr("Elf");
X			break;
X		case 4:
X		case 14:
X		case 24:
X			addstr("Dwarf");
X			break;
X		case 5:
X		case 15:
X		case 25:
X			addstr("Halfling");
X			break;
X		case 6:
X		case 16:
X		case 26:
X			addstr("Experimento");
X			break;
X		case 90:
X			addstr("Ex-Valar");
X			break;
X		case 99:
X			addstr("Valar");
X		}
X	if (stat->typ > 10 && stat->typ < 90)
X		if (stat->typ > 20)
X			addstr(" (Council of Wise)");
X		else
X			addstr(" (King)");
X		addch('\n');
X	mvprintw(7,0,"Experience: %9.0f",stat->exp);
X	mvprintw(8,0,"Brains    : %9.0f",stat->brn);
X	mvprintw(9,0,"Magic Lvl : %9.0f",stat->mag);
X	mvprintw(10,0,"Sin       : %9.5f",stat->sin);
X	mvprintw(11,0,"Poison    : %9.5f",stat->psn);
X	mvprintw(12,0,"Gems      : %9.0f",stat->gem);
X	mvprintw(13,0,"Age       : %9d",stat->age);
X	mvprintw(7,40,"Holy Water: %9d",stat->hw);
X	mvprintw(8,40,"Amulets   : %9d",stat->amu);
X	mvprintw(9,40,"Charms    : %9d",stat->chm);
X	mvprintw(10,40,"Crowns    : %9d",stat->crn);
X	mvprintw(11,40,"Shield    : %9.0f",stat->shd);
X	mvprintw(12,40,"Sword     : %9.0f",stat->swd);
X	mvprintw(13,40,"Quickslver: %9d",stat->quks);
X
X	mvprintw(14,0,"Blessing: %s   Ring: %s   Virgin: %s   Palantir: %s",
X		flags[stat->bls],flags[stat->rng.type != 0],flags[stat->vrg],flags[stat->pal]);
X}
X
Xvoid	neatstuff(stat) 			/* random things */
Xreg	struct	stats	*stat;
X{
Xdouble	temp;
Xint	ch;
X
X	switch ((int) roll(0,100))
X		{
X		case 1:
X		case 2:
X			if (stat->psn > 0)
X				{
X				mvaddstr(5,0,"You've found a medic!  How much will you offer to be cured ? ");
X				temp = inflt();
X				if (temp < 0 || temp > stat->gld)
X					{
X					mvaddstr(6,0,"He was not amused, and made you worse.\n");
X					++stat->psn;
X					}
X				else if (rnd()/2.0 > (temp + 1)/max(stat->gld,1))
X					mvaddstr(6,0,"Sorry, he wasn't interested.\n");
X				else
X					{
X					mvaddstr(6,0,"He accepted.");
X					stat->psn = max(0,stat->psn-1);
X					stat->gld -= floor(temp);
X					}
X				}
X			break;
X		case 3:
X			mvaddstr(6,0,"You've been caught raping and pillaging!\n");
X			stat->exp += 4000;
X			stat->sin += 0.5;
X			break;
X		case 4:
X			temp = roll(6,50);
X			mvprintw(5,0,"You've found %.0f gold pieces, want them ? ",temp);
X			clrtoeol();
X			ch = rgetch();
X			if (toupper(ch) == 'Y')
X				stat->gld += temp;
X			break;
X		case 5:
X			if (stat->sin > 1)
X				{
X				mvaddstr(6,0,"You've found a Holy Orb!\n");
X				stat->sin -= 0.25;
X				}
X			break;
X		case 6:
X			if (stat->psn < 1)
X				{
X				mvaddstr(6,0,"You've been hit with a plague!\n");
X				++stat->psn;
X				}
X			break;
X		case 7:
X			mvaddstr(6,0,"You've found some holy water.\n");
X			++stat->hw;
X			break;
X		case 8:
X			mvaddstr(6,0,"You've met a Guru. . .");
X			if (rnd()*stat->sin > 1)
X				addstr("You disgusted him with your sins!\n");
X			else if (stat->psn > 0)
X				{
X				addstr("He looked kindly upon you, and cured you.\n");
X				stat->psn = 0;
X				}
X			else
X				{
X				addstr("He rewarded you for your virtue.\n");
X				stat->man += 50;
X				stat->shd += 2;
X				}
X			break;
X		case 9:
X			mvaddstr(6,0,"You've found an amulet.\n");
X			++stat->amu;
X			break;
X		case 10:
X			if (stat->blind)
X				{
X				mvaddstr(6,0,"You've regained your sight!\n");
X				stat->blind = FALSE;
X				}
X			break;
X		default:
X			if (stat->psn > 0)
X				stat->nrg -= min(stat->psn*stat->mxn/45,0.9*stat->mxn);
X			stat->nrg = max(stat->nrg,floor(stat->mxn/11));
X		}
X}
!EOR!
echo extracting - func1.c
sed 's/^X//' > func1.c << '!EOR!'
X/*
X * func1.c	Phantasia support routines
X */
X
X#include "phant.h"
X
Xbool	findname(name)				/* return TRUE if name in use */
Xreg	char	*name;
X{
XFILE	*fp;
Xstruct	stats	buf;
X
X	fp = fopen(peoplefile,"r");
X	while (fread((char *) &buf,sizeof(buf),1,fp))
X		if (!strcmp(buf.name,name))
X			{
X			fclose(fp);
X			mvaddstr(21,0,"Name already in use.\n");
X			refresh();
X			return (TRUE);
X			}
X	fclose(fp);
X	return (FALSE);
X}
X
Xint	findspace()				/* allocate space for a character in peoplefile */
X{
XFILE	*fp;
Xstruct	stats	buf;
Xreg	int	loc;
X
X	loc = 0;
X	fp = fopen(peoplefile,"r");
X	while (fread((char *) &buf,sizeof(buf),1,fp))
X		{
X		if (!strcmp(buf.name,"<null>"))
X			{
X			fclose(fp);
X			return (loc);
X			}
X		else
X			++loc;
X		}
X	fclose(fp);
X	fp = fopen(peoplefile,ACCESS);
X	fseek(fp,(long) loc * sizeof(buf),0);
X	initchar(&buf);
X	strcpy(buf.name,"inuse");
X	fwrite((char *) &buf,sizeof(buf),1,fp);
X	fclose(fp);
X	return (loc);
X}
X
Xint	findchar(stat)				/* retrieve a character from file */
Xreg	struct	stats	*stat;
X{
Xreg	int	loc = 0, loop;
Xchar	name[21];
XFILE	*fp;
X
X	if (fp = fopen(peoplefile,"r"))
X		{
X		clear();
X		mvprintw(10,0,"What was your character's name ? ");
X		getstring(name,21);
X		trunc(name);
X		while (fread((char *) stat,sizeof(*stat),1,fp))
X			{
X			if (!strcmp(stat->name,name))
X				{
X				move(11,0);
X				refresh();
X				fclose(fp);
X				nocrmode();
X				for (loop = 0; loop < 2; ++loop)
X					if (!strcmp(getpass("Password ? "),stat->pswd))
X						{
X						crmode();
X						return (loc);
X						}
X					else
X						printf("No good.\n");
X				exit1();
X				/*NOTREACHED*/
X				}
X			++loc;
X			}
X		}
X	fclose(fp);
X	addstr("\n\nNot found.\n");
X	exit1();
X/*NOTREACHED*/
X}
X
Xvoid	leave(stat)				/* save character in file */
Xreg	struct	stats	*stat;
X{
Xlong	ltemp;
X
X	if (!stat->lvl)
X		strcpy(stat->name,"<null>");
X	stat->status = OFF;
X	time(&ltemp);
X	stat->age += ltemp - secs;
X	update(stat,fileloc);
X	exit1();
X	/*NOTREACHED*/
X}
X
Xvoid	talk(name)				/* send message to all players */
Xreg	char	*name;
X{
XFILE	*fp;
Xchar	aline[160];
X
X	mvaddstr(5,0,"Message ? ");
X	getstring(aline,160);
X	fp = fopen(messfile,"w");
X	if (*aline)
X		fprintf(fp,"%s:  %s",name,aline);
X	fclose(fp);
X}
X
Xvoid	death(stat)				/* remove a player after dying */
Xreg	struct	stats	*stat;
X{
XFILE	*fp;
Xchar	aline[100];
Xint	ch;
Xreg	int	loop;
Xlong	ltemp;
X
X	clear();
X	if (stat->typ == 99)
X		if (stat->rng.duration)
X			{
X			addstr("Valar should be more cautious.  You've been killed.\n");
X			printw("You only have %d more chance(s).\n",--stat->rng.duration);
X			paws(3);
X			stat->nrg = stat->mxn;
X			return;
X			}
X		else
X			{
X			addstr("You had your chances, but Valar aren't totally\n");
X			addstr("immortal.  You are now left to wither and die . . .\n");
X			paws(3);
X			stat->brn = stat->lvl /25;
X			stat->nrg = stat->mxn;
X			stat->quks = stat->swd = 0;
X			stat->typ = 90;
X			return;
X			}
X	if (stat->lvl > 9999)
X		addstr("Characters greater than level 10K must be retired.  Sorry.");
X	switch(stat->rng.type)
X		{
X		case -DLREG:
X		case -NAZREG:
X			mvaddstr(4,0,"Your ring saved you from death!\n");
X			refresh();
X			stat->rng.type = NONE;
X			stat->nrg = stat->mxn/12+1;
X			stat->crn -= (stat->crn > 0);
X			return;
X		case DLBAD:
X		case -DLBAD:
X		case NAZBAD:
X		case -NAZBAD:
X		case -SPOILED:
X		case SPOILED:
X			mvaddstr(4,0,"Your ring has taken control of you and turned you into a monster!\n");
X			fp = fopen(monsterfile,"r");
X			for (loop = 0; loop <= 13; ++loop)
X				fgets(aline,100,fp);
X			ltemp = ftell(fp);
X			fclose(fp);
X			fp = fopen(monsterfile,ACCESS);
X			fseek(fp,ltemp,0);
X			fprintf(fp,"%-20s",stat->name);
X			fclose(fp);
X		}
X	initchar(stat);
X	fp = fopen(lastdead,"w");
X	fprintf(fp,"%s   Login:  %s",stat->name,stat->login);
X	fclose(fp);
X	strcpy(stat->name,"<null>");
X	update(stat,fileloc);
X	clear();
X	move(10,0);
X	switch ((int) roll(1,5))
X		{
X		case 1:
X			addstr("You've crapped out!  ");
X			break;
X		case 2:
X			addstr("You have been disemboweled.  ");
X			break;
X		case 3:
X			addstr("You've been mashed, mauled, and spit upon.  (You're dead.)\n");
X			break;
X		case 4:
X			addstr("You died!  ");
X			break;
X		case 5:
X			addstr("You're a complete failure -- you've died!!\n");
X		}
X	addstr("Care to give it another try ? ");
X	ch = rgetch();
X	if (toupper(ch) == 'Y')
X		{
X		endwin();
X		execl(gameprog,"phantasia","-s",0);
X		}
X	exit1();
X	/*NOTREACHED*/
X}
X
Xvoid	update(stat,place)			/* update charac file */
Xreg	struct	stats	*stat;
Xreg	int	place;
X{
XFILE	*fp;
X
X	fp = fopen(peoplefile,ACCESS);
X	fseek(fp,(long) place*sizeof(*stat),0);
X	fwrite((char *) stat,sizeof(*stat),1,fp);
X	fclose(fp);
X}
X
Xvoid	printplayers(stat)			/* show users */
Xreg	struct	stats	*stat;
X{
XFILE	*fp;
Xstruct	stats	buf;
Xreg	int	loop = 0;
Xdouble	loc;
Xlong	ltmp;
Xint	ch;
X
X	if (stat->blind)
X		{
X		mvaddstr(6,0,"You can't see anyone.\n");
X		return;
X		}
X	loc = circ(stat->x,stat->y);
X	mvaddstr(6,0,"Name                         X         Y       Lvl  Type  Login\n");
X	fp = fopen(peoplefile,"r");
X	while (fread((char *) &buf,sizeof(buf),1,fp))
X		{
X		if (buf.status)
X			{
X			ch = (buf.status == CLOAKED) ? '?' : 'W';
X			if (stat->typ > 10 || buf.typ > 10 || loc >= circ(buf.x,buf.y) || stat->pal)
X				if (buf.status != CLOAKED || (stat->typ == 99 && stat->pal))
X					if (buf.typ == 99)
X						addstr("The Valar is watching you. . .\n");
X					else if (buf.wormhole)
X						printw("%-20s         %c         %c    %6u  %3d   %-9s\n",
X							buf.name,ch,ch,buf.lvl,buf.typ,buf.login);
X					else
X						printw("%-20s  %8.0f  %8.0f    %6u  %3d   %-9s\n",
X							buf.name,buf.x,buf.y,buf.lvl,buf.typ,buf.login);
X				else
X					if (buf.typ == 99)
X						--loop;
X					else
X						printw("%-20s         ?         ?    %6u  %3d   %-9s\n",
X							buf.name,buf.lvl,buf.typ,buf.login);
X			++loop;
X			}
X		}
X	fclose(fp);
X	time(&ltmp);
X	printw("Total users = %d    %s\n",loop,ctime(&ltmp));
X	refresh();
X}
X
X
Xvoid	printhelp()				/* print help file */
X{
XFILE	*fp;
Xchar	instr[100];
X
X	fp = fopen(helpfile,"r");
X	while (fgets(instr,100,fp))
X		fputs(instr,stdout);
X	fclose(fp);
X}
X
Xvoid	titlestuff()				/* print out a header */
X{
XFILE	*fp;
Xchar	instr[80], hiname[21], nxtname[21], aline[80];
Xbool	cowfound = FALSE, kingfound = FALSE;
Xstruct	stats	buf;
Xdouble	hiexp, nxtexp;
Xunsigned	hilvl, nxtlvl;
Xreg	int	loop;
X
X	mvaddstr(0,15,"W e l c o m e   t o   P h a n t a s i a (vers. 3.2)!");
X	fp = fopen(motd,"r");
X	if (fgets(instr,80,fp))
X		mvaddstr(2,40 - strlen(instr)/2,instr);
X	fclose(fp);
X	fp = fopen(peoplefile,"r");
X	while (fread((char *) &buf,sizeof(buf),1,fp))
X		if (buf.typ > 10 && buf.typ < 20)
X			{
X			sprintf(instr,"The present ruler is %s  Level:%d",buf.name,buf.lvl);
X			mvaddstr(4,40 - strlen(instr)/2,instr);
X			kingfound = TRUE;
X			break;
X			}
X	if (!kingfound)
X		mvaddstr(4,24,"There is no ruler at this time.");
X	fseek(fp,0L,0);
X	while (fread((char *) &buf,sizeof(buf),1,fp))
X		if (buf.typ == 99)
X			{
X			sprintf(instr,"The Valar is %s   Login:  %s",buf.name,buf.login);
X			mvaddstr(6,40 - strlen(instr)/2,instr);
X			break;
X			}
X	fseek(fp,0L,0);
X	while (fread((char *) &buf,sizeof(buf),1,fp))
X		if (buf.typ > 20 && buf.typ < 90)
X			{
X			if (!cowfound)
X				{
X				mvaddstr(8,30,"Council of the Wise:");
X				loop = 10;
X				cowfound = TRUE;
X				}
X			/* This assumes a finite (<=7) number of C.O.W.: */
X			sprintf(instr,"%s   Login:  %s",buf.name,buf.login);
X			mvaddstr(loop++,40 - strlen(instr)/2,instr);
X			}
X	fseek(fp,0L,0);
X	*nxtname = *hiname = '\0';
X	hiexp = 0.0;
X	nxtlvl = hilvl = 0;
X	while (fread((char *) &buf,sizeof(buf),1,fp))
X		if (buf.exp > hiexp && buf.typ < 20)
X			{
X			nxtexp = hiexp;
X			hiexp = buf.exp;
X			nxtlvl = hilvl;
X			hilvl = buf.lvl;
X			strcpy(nxtname,hiname);
X			strcpy(hiname,buf.name);
X			}
X		else if (buf.exp > nxtexp && buf.typ < 20)
X			{
X			nxtexp = buf.exp;
X			nxtlvl = buf.lvl;
X			strcpy(nxtname,buf.name);
X			}
X	fclose(fp);
X	mvaddstr(17,28,"Highest characters are:");
X	sprintf(instr,"%s  Level:%d   and   %s  Level:%d",hiname,hilvl,nxtname,nxtlvl);
X	mvaddstr(19,40 - strlen(instr)/2,instr);
X	fp = fopen(lastdead,"r");
X	fgets(aline,80,fp);
X	sprintf(instr,"The last character to die is %s",aline);
X	mvaddstr(21,40 - strlen(instr)/2,instr);
X	fclose(fp);
X	refresh();
X}
X
X
X
Xvoid	printmonster()				/* do a monster list on the terminal */
X{
XFILE	*fp;
Xreg	int	count = 0;
Xchar	instr[100];
X
X	puts(" #  Name                    Str     Brains  Quick   Hits    Exp     Treas   Type    Flock%\n");
X	fp = fopen(monsterfile,"r");
X	while (fgets(instr,100,fp))
X		printf("%2d  %s",count++,instr);
X	fclose(fp);
X}
X
Xvoid	exit1() 				/* exit, but cleanup */
X{
X	move(23,0);
X	refresh();
X	nocrmode();
X	endwin();
X	exit(0);
X	/*NOTREACHED*/
X}
X
Xvoid	init1() 				/* set up for screen updating */
X{
X		/* catch/ingnore signals */
X#ifdef	BSD41
X	sigignore(SIGQUIT);
X	sigignore(SIGALRM);
X	sigignore(SIGTERM);
X	sigignore(SIGTSTP);
X	sigignore(SIGTTIN);
X	sigignore(SIGTTOU);
X	sighold(SIGINT);
X#endif
X#ifdef	BSD42
X	signal(SIGQUIT,interrupt,1);
X	signal(SIGALRM,interrupt,1);
X	signal(SIGTERM,interrupt,1);
X	signal(SIGTSTP,interrupt,1);
X	signal(SIGTTIN,interrupt,1);
X	signal(SIGTTOU,interrupt,1);
X	signal(SIGINT,interrupt,1);
X#endif
X#ifdef	USG3
X	signal(SIGINT,SIG_IGN);
X	signal(SIGQUIT,SIG_IGN);
X	signal(SIGTERM,SIG_IGN);
X	signal(SIGALRM,SIG_IGN);
X#endif
X#ifdef	USG5
X	signal(SIGINT,SIG_IGN);
X	signal(SIGQUIT,SIG_IGN);
X	signal(SIGTERM,SIG_IGN);
X	signal(SIGALRM,SIG_IGN);
X#endif
X	srand((unsigned) time((long *) NULL));	/* prime random numbers */
X	initscr();
X	noecho();
X	crmode();
X	clear();
X	refresh();
X}
X
Xvoid	getstring(cp,mx)				/* get a string from the stdscr at current y,x */
Xreg	char	*cp;
Xreg	int	mx;
X{
Xreg	int	loop = 0, x, y, xorig;
Xint	ch;
X
X	getyx(stdscr,y,xorig);
X	clrtoeol();
X	refresh();
X	while((ch = getch()) != '\n' && loop < mx - 1)
X		switch (ch)
X			{
X			case '\033':	/* escape */
X			case '\010':	/* backspace */
X				if (loop)
X					{
X					--loop;
X					getyx(stdscr,y,x);
X					mvaddch(y,x-1,' ');
X					move(y,x-1);
X					refresh();
X					}
X				break;
X			case '\030':	/* ctrl-x */
X				loop = 0;
X				move(y,xorig);
X				clrtoeol();
X				refresh();
X				break;
X			default:
X				if (ch >= ' ') /* printing char */
X					{
X					addch(ch);
X					cp[loop++] = ch;
X					refresh();
X					}
X			}
X	cp[loop] = '\0';
X}
X
X
Xvoid	showusers()				/* print a list of all characters */
X{
Xstruct	stats	buf;
XFILE	*fp;
X
X	if (fp = fopen(peoplefile,"r"))
X		{
X		puts("Current characters on file are:\n");
X		while (fread((char *) &buf,sizeof(buf),1,fp))
X			if (strcmp("<null>",buf.name))
X				printf("%-20s   Login: %-9s  Level: %6u\n",buf.name,buf.login,buf.lvl);
X		fclose(fp);
X		}
X}
X
Xvoid	kingstuff(stat) 			/* stuff upon entering throne */
Xreg	struct 	stats	*stat;
X{
XFILE	*fp;
Xstruct	stats	buf;
Xstruct	nrgvoid	vbuf;
Xreg	int	loc = 0;
X
X	if (stat->typ < 10)	/* check to see if king -- assumes crown */
X		{
X		fp = fopen(peoplefile,"r");
X		while (fread((char *) &buf,sizeof(buf),1,fp))
X			if (buf.typ > 10 && buf.typ < 20)	/* found old king */
X				if (buf.status != OFF)
X					{
X					mvaddstr(6,0,"The king is playing, so you cannot steal his throne\n");
X					stat->x = stat->y = 9;
X					move(3,0);
X					fclose(fp);
X					return;
X					}
X				else
X					{
X					buf.typ -= 10;
X					if (buf.crn)
X						--buf.crn;
X					fclose(fp);
X					update(&buf,loc);
XKING:				stat->typ = abs(stat->typ) + 10;
X					mvaddstr(6,0,"You have become king!\n");
X					fp = fopen(messfile,"w");
X					fprintf(fp,"All hail the new king!");
X					fclose(fp);
X					/* clear all energy voids */
X					fp = fopen(voidfile,"r");
X					fread((char *) &vbuf,sizeof(vbuf),1,fp);
X					fclose(fp);
X					fp = fopen(voidfile,"w");
X					fwrite((char *) &vbuf,sizeof(vbuf),1,fp);
X					fclose(fp);
X					goto EXIT;
X					}
X			else
X				++loc;
X		fclose(fp);	  /* old king not found -- install new one */
X		goto KING;
X		}
XEXIT:	mvaddstr(3,0,"0:Decree  ");
X}
X
Xvoid	paws(where)				/* wait for input to continue */
Xint	where;
X{
X	mvaddstr(where,0,"-- more --");
X	rgetch();
X}
X
Xvoid	cstat() 				/* examine/change stats of a character */
X{
Xstruct	stats charac;
Xchar	s[60], flag[2];
XFILE	*fp;
Xreg	int	loc = 0;
Xint	c, temp, today;
Xlong	ltemp;
Xdouble	dtemp;
X
X	flag[0] = 'F';	flag[1] = 'T';
X	mvaddstr(10,0,"Which character do you want to look at ? ");
X	getstring(s,60);
X	if (fp = fopen(peoplefile,"r"))
X		while (fread((char *) &charac,sizeof(charac),1,fp))
X			if (!strcmp(s,charac.name))
X				goto FOUND;
X			else
X				++loc;
X	mvaddstr(11,0,"Not found.");
X	exit1();
X	/*NOTREACHED*/
X
XFOUND:	fclose(fp);
X	time(&ltemp);
X	today = localtime(&ltemp)->tm_yday;
X	if (!su)
X		strcpy(charac.pswd,"XXXXXXXX");
X	clear();
XTOP:	mvprintw(0,0,"a:Name         %s\n",charac.name);
X	printw("b:Password     %s\n",charac.pswd);
X	printw(" :Login        %s\n",charac.login);
X	temp = today - charac.lastused;
X	if (temp < 0)
X		temp += 365;
X	printw("c:Used         %d\n",temp);
X	mvprintw(5,0,"d:Experience   %.0f\n",charac.exp);
X	printw("e:Level        %d\n",charac.lvl);
X	printw("f:Strength     %.0f\n",charac.str);
X	printw("g:Sword        %.0f\n",charac.swd);
X	printw("h:Quickness    %d\n",charac.quk);
X	printw("i:Quikslvr     %d\n",charac.quks);
X	printw("j:Energy       %.0f\n",charac.nrg);
X	printw("k:Max-Nrg      %.0f\n",charac.mxn);
X	printw("l:Shield       %.0f\n",charac.shd);
X	printw("m:Magic        %.0f\n",charac.mag);
X	printw("n:Manna        %.0f\n",charac.man);
X	printw("o:Brains       %.0f\n",charac.brn);
X	mvprintw(0,40,"p:X-coord      %.0f\n",charac.x);
X	mvprintw(1,40,"q:Y-coord      %.0f\n",charac.y);
X	if (su)
X		mvprintw(2,40,"r:Wormhole     %d\n",charac.wormhole);
X	else
X		mvprintw(2,40,"r:Wormhole     %c\n",flag[charac.wormhole != 0]);
X	mvprintw(3,40,"s:Type         %d\n",charac.typ);
X	mvprintw(5,40,"t:Sin          %0.3f\n",charac.sin);
X	mvprintw(6,40,"u:Poison       %0.3f\n",charac.psn);
X	mvprintw(7,40,"v:Gold         %.0f\n",charac.gld);
X	mvprintw(8,40,"w:Gem          %.0f\n",charac.gem);
X	mvprintw(9,40,"x:Holy Water   %d\n",charac.hw);
X	mvprintw(10,40,"y:Charms       %d\n",charac.chm);
X	mvprintw(11,40,"z:Crowns       %d\n",charac.crn);
X	mvprintw(12,40,"1:Amulets      %d\n",charac.amu);
X	mvprintw(13,40,"2:Age          %d\n",charac.age);
X	mvprintw(18,5,"3:Virgin %c  4:Blessed %c  5:Ring %c  6:Blind %c  7:Palantir %c",
X		flag[charac.vrg],flag[charac.bls],flag[charac.rng.type != 0],flag[charac.blind],flag[charac.pal]);
X	if (!su)
X		exit1();
X	mvaddstr(15,40,"!:Quit");
X	mvaddstr(16,40,"?:Delete");
X	mvaddstr(19,30,"8:Duration");
X	mvaddstr(21,0,"What would you like to change? ");
X	c = rgetch();
X	switch(c)
X		{
X		case 'p':	/* change x coord */
X			mvprintw(23,0,"x = %f; x = ",charac.x);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.x = dtemp;
X			break;
X		case 'q':	/* change y coord */
X			mvprintw(23,0,"y = %f; y = ",charac.y);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.y = dtemp;
X			break;
X		case 'd':	/* change Experience */
X			mvprintw(23,0,"exp = %f; exp = ",charac.exp);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.exp = dtemp;
X			break;
X		case 'e':	/* change level */
X			mvprintw(23,0,"lvl = %d; lvl;= ",charac.lvl);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.lvl = dtemp;
X			break;
X		case 'h':	/* change quickness */
X			mvprintw(23,0,"quk = %d; quk;= ",charac.quk);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.quk = dtemp;
X			break;
X		case 'f':	/* change strength */
X			mvprintw(23,0,"str = %f; str;= ",charac.str);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.str = dtemp;
X			break;
X		case 't':	/* change Sin */
X			mvprintw(23,0,"sin = %f; sin;= ",charac.sin);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.sin = dtemp;
X			break;
X		case 'n':	/* change manna */
X			mvprintw(23,0,"man = %f; man;= ",charac.man);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.man = dtemp;
X			break;
X		case 'v':	/* change gold */
X			mvprintw(23,0,"gld = %f; gld;= ",charac.gld);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.gld = dtemp;
X			break;
X		case 'j':	/* change energy */
X			mvprintw(23,0,"nrg = %f; nrg;= ",charac.nrg);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.nrg = dtemp;
X			break;
X		case 'k':	/* change Maximum energy */
X			mvprintw(23,0,"mxn = %f; mxn;= ",charac.mxn);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.mxn = dtemp;
X			break;
X		case 'm':	/* change magic */
X			mvprintw(23,0,"mag = %f; mag;= ",charac.mag);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.mag = dtemp;
X			break;
X		case 'o':	/* change brains */
X			mvprintw(23,0,"brn = %f; brn;= ",charac.brn);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.brn = dtemp;
X			break;
X		case 'z':	/* change crowns */
X			mvprintw(23,0,"crn = %d; crn;= ",charac.crn);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.crn = dtemp;
X			break;
X		case '5':	/* change ring type */
X			mvprintw(23,0,"rng-type = %d; rng-type;= ",charac.rng.type);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.rng.type = dtemp;
X			break;
X		case '8':	/* change ring duration */
X			mvprintw(23,0,"rng-duration = %d; rng-duration;= ",charac.rng.duration);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.rng.duration = dtemp;
X			break;
X		case '7':	/* change palantir */
X			mvprintw(23,0,"pal = %d; pal;= ",charac.pal);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				{
X				charac.pal = dtemp;
X				charac.pal = (charac.pal != 0);
X				}
X			break;
X		case 'u':	/* change poison */
X			mvprintw(23,0,"psn = %f; psn;= ",charac.psn);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.psn = dtemp;
X			break;
X		case 'x':	/* change holy water */
X			mvprintw(23,0,"hw = %d; hw;= ",charac.hw);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.hw = dtemp;
X			break;
X		case '1':	/* change amulet */
X			mvprintw(23,0,"amu = %d; amu;= ",charac.amu);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.amu = dtemp;
X			break;
X		case '4':	/* change Blessing */
X			mvprintw(23,0,"bls = %d; bls;= ",charac.bls);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				{
X				charac.bls = dtemp;
X				charac.bls = (charac.bls != 0);
X				}
X			break;
X		case 'y':	/* change Charm */
X			mvprintw(23,0,"chm = %d; chm;= ",charac.chm);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.chm = dtemp;
X			break;
X		case 'w':	/* change Gems */
X			mvprintw(23,0,"gem = %f; gem;= ",charac.gem);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.gem = dtemp;
X			break;
X		case 'i':	/* change Quicksilver */
X			mvprintw(23,0,"quks = %d; quks;= ",charac.quks);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.quks = dtemp;
X			break;
X		case 'g':	/* change swords */
X			mvprintw(23,0,"swd = %f; swd;= ",charac.swd);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.swd = dtemp;
X			break;
X		case 'l':	/* change shields */
X			mvprintw(23,0,"shd = %f; shd;= ",charac.shd);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.shd = dtemp;
X			break;
X		case 's':	/* change type */
X			mvprintw(23,0,"typ = %d; typ;= ",charac.typ);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.typ = dtemp;
X			break;
X		case '3':	/* change virgin */
X			mvprintw(23,0,"vrg = %d; vrg;= ",charac.vrg);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				{
X				charac.vrg = dtemp;
X				charac.vrg = (charac.vrg != 0);
X				}
X			break;
X		case 'c':	/* change last-used */
X			mvprintw(23,0,"last-used = %d; last-used;= ",charac.lastused);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.lastused = dtemp;
X			break;
X		case 'b':		/* change password */
X			mvaddstr(23,0,"New password: ");
X			getstring(s,60);
X			if (*s)
X				strcpy(charac.pswd,s);
X			break;
X		case 'a':		/* change name */
X			mvaddstr(23,0,"New name: ");
X			getstring(s,60);
X			if (*s)
X				strcpy(charac.name,s);
X			break;
X		case 'r':	/* change wormhole */
X			mvprintw(23,0,"wormhole = %d; wormhole;= ",charac.wormhole);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.wormhole = dtemp;
X			break;
X		case '2':	/* change age */
X			mvprintw(23,0,"age = %d; age;= ",charac.age);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				charac.age = dtemp;
X			break;
X		case '6':	/* change blindness */
X			mvprintw(23,0,"blind = %d; blind;= ",charac.blind);
X			dtemp = inflt();
X			if (dtemp != 0.0)
X				{
X				charac.blind = dtemp;
X				charac.blind = (charac.blind != 0);
X				}
X			break;
X		case '!':	/* quit, update */
X			goto LEAVE;
X		case '?':	/* delete char */
X			strcpy(charac.name,"<null>");
X			initchar(&charac);
X			goto LEAVE;
X		}
X	goto TOP;
XLEAVE:	charac.status = OFF;
X	update(&charac,loc);
X}
X
Xunsigned level(expr)			/* calculate level */
Xdouble	expr;
X{
X	if (expr < 1.1e+7)
X		return (pow((expr/1000.0), 0.4875));
X	else
X		return (pow((expr/1250.0), 0.4865));
X}
X
Xvoid	trunc(str)				/* remove blank spaces at the end of str[] */
Xreg	char	*str;
X{
Xreg	int	loop;
X	loop = strlen(str) - 1;
X	while (str[--loop] == ' ')
X		str[loop] = '\0';
X}
X
Xdouble	inflt()				/* get a floating point # from the terminal */
X{
Xchar	aline[80];
Xdouble	res;
X	getstring(aline,80);
X	if (sscanf(aline,"%F",&res) < 1)
X		res = 0;
X	return (res);
X}
X
Xvoid	checkmov(stat)				/* see if beyond PONR */
Xreg	struct	stats	*stat;
X{
X	if (beyond)
X		{
X		stat->x = sgn(stat->x) * max(abs(stat->x),1.1e+6);
X		stat->y = sgn(stat->y) * max(abs(stat->y),1.1e+6);
X		}
X}
Xvoid	scramble(stat)			/* mix up some stats */
Xreg	struct	stats	*stat;
X{
Xdouble	buf[5],	temp;
Xreg	int	first, second;
Xreg	double	*bp;
X
X	bp = buf;
X	*bp++ = stat->str;
X	*bp++ = stat->man;
X	*bp++ = stat->brn;
X	*bp++ = stat->mag;
X	*bp++ = stat->nrg;
X
X	bp = buf;
X	first = roll(0,5);
X	second = roll(0,5);
X	temp = bp[first];
X	bp[first] = bp[second];
X	bp[second] = temp;
X
X	stat->str = *bp++;
X	stat->man = *bp++;
X	stat->brn = *bp++;
X	stat->mag = *bp++;
X	stat->nrg = *bp++;
X}
!EOR!

estes@tty3b.UUCP (8-01-83"Edward E 9723i) (09/08/84)

------------CUT---------------CUT--------------CUT-------------CUT----------
: This is a shar archieve.  Extract with sh, not csh.
: The rest of this file will extract:
: func2.c main.c fight.c
echo extracting - func2.c
sed 's/^X//' > func2.c << '!EOR!'
X/*
X * func2.c	Phantasia support routines
X */
X
X#include "phant.h"
X
Xvoid	decree(stat)				/* king and valar stuff */
Xreg	struct	stats	*stat;
X{
XFILE	*fp;
Xshort	arg;
Xchar	aline[80], *cp;
Xstruct	stats	sbuf;
Xstruct	nrgvoid	vbuf;
Xdouble	temp1 = 0.0, temp2 = 0.0;
Xint	ch;
Xreg	int	loc = 0;
X
X	move(3,0);
X	clrtoeol();
X	if (stat->typ < 20 && !su)	/* king */
X		{
X		addstr("1:Transport  2:Curse  3:Energy Void  4:Bestow  5:Collect Taxes  ");
X		ch = rgetch();
X		move(3,0);
X		clrtoeol();
X		switch (ch)
X			{
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.x = floor(temp1);
X				vbuf.y = floor(temp2);
X				vbuf.active = TRUE;
X				voidupdate(&vbuf,allocvoid());
X				goto EXIT;
X			case '4':
X				arg = GOLD;
X				addstr("How much gold to bestow ? ");
X				temp1 = inflt();
X				if (temp1 > stat->gld || temp1 < 0)
X					{
X					mvaddstr(6,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(6,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 = rgetch();
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 = hypot(stat->x - vbuf.x,stat->y - vbuf.y);
X					temp1 = floor(temp1 + roll(-temp1/10.0,temp1/5.0));
X					mvprintw(6,0,"The palantir says the Grail is about %.0f away.\n",temp1);
X					return;
X					}
X				else
X					{
X					mvaddstr(6,0,"You need a palantir to seek the Grail.\n");
X					return;
X					}
X			case '3':
X				mvaddstr(3,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(3,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(3,0,"Who do you want to %s ? ",cp);
X	getstring(aline,21);
X	trunc(aline);
X	if (strcmp(stat->name,aline))
X		{
X		fp = fopen(peoplefile,"r");
X		while (fread((char *) &sbuf,sizeof(sbuf),1,fp))
X			if (strcmp(aline,sbuf.name))
X				++loc;
X			else
X				{
X				fclose(fp);
X				if (sbuf.tampered)
X					{
X					mvaddstr(6,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(6,0,"It is done.\n");
X					return;
X					}
X				}
X		fclose(fp);
X		mvaddstr(6,0,"There is no one by that name.\n");
X		}
X	else
X		mvaddstr(6,0,"You may not do it to yourself!\n");
X}
X
Xvoid	checktampered(stat)			/* see if decree'd etc. */
Xreg	struct	stats	*stat;
X{
Xstruct	nrgvoid	vbuf;
Xstruct	stats sbuf;
XFILE	*fp;
Xreg	int	loc = 0;
X
X	/* first check for energy voids */
X	fp = fopen(voidfile,"r");
X	while (fread((char *) &vbuf,sizeof(vbuf),1,fp))
X		if (vbuf.active && vbuf.x == stat->x && vbuf.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	/* now check for other things */
X	statread(&sbuf,fileloc);
X	if (sbuf.tampered)
X		tampered(stat,sbuf.tampered,&sbuf);
X}
X
Xvoid	voidupdate(vp,loc)			/* update an energy void */
Xreg	struct nrgvoid	*vp;
Xreg	int	loc;
X{
XFILE	*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
Xint	allocvoid()				/* find a space to put an energy void */
X{
XFILE	*fp;
Xreg	int	loc = 0;
Xstruct	nrgvoid	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
Xvoid	statread(stat,loc)			/* read a charac. structure */
Xreg	struct	stats	*stat;
Xreg	int	loc;
X{
XFILE	*fp;
X
X	fp = fopen(peoplefile,"r");
X	fseek(fp,(long) loc * sizeof(*stat),0);
X	fread((char *) stat,sizeof(*stat),1,fp);
X	fclose(fp);
X}
X
Xvoid	tampered(stat,what,bufp)			/* decree'd, intervened, etc. */
Xreg	struct	stats	*stat, *bufp;
Xshort	what;
X{
Xstruct	nrgvoid	vbuf;
Xreg	int	loc;
Xstruct	stats	sbuf;
XFILE	*fp;
X
X	changed = TRUE;
X	move(6,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->nrg /= 2;
X			stat->gld = floor(stat->gld/1.25) + 0.1;
X			stat->x += 10;
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",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->nrg = 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);
X			break;
X		case MONSTER:
X			addstr("The Valar zapped you with a monster!\n");
X			paws(7);
X			fight(stat,(int) bufp->scratch1);
X			return;
X		case BLESS:
X			addstr("The Valar has blessed you!\n");
X			stat->nrg = (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->nrg = 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->nrg = stat->mxn = stat->x = stat->y = 
X						stat->mag = stat->brn = 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					fp = fopen(peoplefile,"r");
X					loc = 0;
X					while (fread((char *) &sbuf,sizeof(sbuf),1,fp))
X						if (sbuf.typ == 99)
X							{
X							sbuf.tampered = STOLEN;
X							update(&sbuf,loc);
X							break;
X							}
X						else
X							++loc;
X					fclose(fp);
X					}
X				}
X			vbuf.active = TRUE;
X			vbuf.x = roll(-1e6,2e6);
X			vbuf.y = roll(-1e6,2e6);
X			voidupdate(&vbuf,0);
X			break;
X		}
X}
X
Xvoid	adjuststats(stat)				/* make sure things are within limits, etc. */
Xreg	struct	stats	*stat;
X{
Xlong	ltemp;
Xreg	int	temp;
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	temp = abs(stat->x)/400;
X	if (temp > 16)
X		temp = 0;
X	if (stat->y == 0.0 && !throne && !valhala && temp == abs(stat->x)/400 && sgn(stat->x) == (int) pow(-1.0, (double) temp))
X		{
X		if (!wmhl)
X			stat->wormhole = temp;
X		wmhl = TRUE;
X		}
X	else
X		wmhl = FALSE;
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		movelvl(stat);
X	stat->gld = floor(stat->gld) + 0.1;
X	stat->gem = floor(stat->gem) + 0.1;
X	if (stat->rng.type)
X		stat->nrg = 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);
X				break;
X			}	/* DLREG is ok, so do nothing with it */
X	stat->nrg += (stat->mxn+stat->shd)/15+stat->lvl/3+2;
X	stat->nrg = min(stat->nrg,stat->mxn + stat->shd);
X	if (stat->age > stat->degen * 2500)
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
Xvoid	checkinterm(stat)				/* see if other person on same x,y */
Xreg	struct	stats	*stat;
X{
XFILE	*fp;
Xstruct	stats	sbuf;
Xreg	int	foeloc = 0;
X
X	users = 0;
X	fp = fopen(peoplefile,"r");
X	while (fread((char *) &sbuf,sizeof(sbuf),1,fp))
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				fclose(fp);
X				interm(stat,foeloc);
X				return;
X				}
X			}
X		++foeloc;
X		}
X	fclose(fp);
X}
X
Xint	gch(rngtyp)			/* get a character from terminal, but check ring if crazy */
Xshort	rngtyp;
X{
X	refresh();
X	if (abs(rngtyp) != SPOILED)
X		return (getch());
X	else
X		{
X		getch();
X		return (roll(0,5) + '0');
X		}
X}
X
Xint	rngcalc(chartyp)				/* pick a duration of a ring */
Xshort	chartyp;
X{
Xstatic	int	rngtab[] = { 0, 10, 20, 13, 25, 40, 20};
X
X	if (chartyp > 10)
X		chartyp -= 10;
X	return (rngtab[chartyp - 1]);
X}
X
Xvoid	interm(stat,who)				/* interterminal battle routine */
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(fin,foeplace,0);  \
X			fread((char *) foe,BLOCK,1,fin)
X#define updateme()	fseek(fout,myplace,0);  \
X			fwrite((char *) stat,BLOCK,1,fout);  \
X			fflush(fout)
X
XFILE	*fin, *fout;	/* pointers for input, output */
Xdouble	temp, foespeed, oldhits = 0.0, myhits;
Xstruct	stats	sbuf;
Xreg	struct	stats *foe;
Xreg	int	loop, lines = 5;
Xint	ch;
Xlong	myplace, foeplace;
Xshort	oldtags;
Xbool	luckout = FALSE;
Xchar	foename[21];
X
X	fghting = TRUE;
X	mvaddstr(4,0,"Preparing for battle!\n");
X	refresh();
X		/* set up variables, file, etc. */
X	myplace = fileloc * BLOCK;
X	foeplace = who * BLOCK;
X	fin = fopen(peoplefile,"r");
X	setbuf(fin, (char *) NULL);
X	fout = fopen(peoplefile,ACCESS);
X	stat->status = INBATTLE;
X	myhits = stat->nrg;
X	stat->tampered = oldtags = 1;	/* this must be non-zero to prevent a king or valar from trashing it */
X	stat->scratch1 = stat->scratch2 = 0.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,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(3,0,"You have encountered %s   Level: %d\n",foename,foe->lvl);
X	refresh();
X		/* now wait for foe to respond */
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(4,0,"%s is not responding.\n",foename);
X		goto LEAVE;
X		}
X
X	/* otherwise, everything is set to go */
X	move(4,0);
X	clrtoeol();
X		/* check to see who goes first */
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 */
XHITFOE:	printstats(stat);
X	mvprintw(1,26,"%20.0f",myhits);
X	mvaddstr(4,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 = 5,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->scratch2 = 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->scratch2 = RAN;
X				goto LEAVE;
X				}
X			mvprintw(lines++,0,"%s is still after you!",foename);
X			stat->scratch2 = 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->scratch2 = BLEWIT;
X				}
X			else
X				{
X				mvaddstr(lines++,0,"You just lucked out!");
X				stat->scratch1 = foe->nrg + 5;
X				}
X			break;
X		}
X	refresh();
X	stat->scratch1 = floor(stat->scratch1);		/* clean up any mess */
X	if (stat->scratch1 > foe->nrg)
X		stat->scratch2 = 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 (((int) stat->scratch2) == 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		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 */
XWAIT:	printstats(stat);
X	mvprintw(1,26,"%20.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 ((int) foe->scratch2)
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	/* timeout */
X	mvaddstr(23,0,"Timeout: waiting for response.  Do you want to wait ? ");
X	refresh();
X	ch = getch();
X	move(23,0);
X	clrtoeol();
X	if (toupper(ch) == 'Y')
X		goto WAIT;
X	goto LEAVE;
X
X/* routine to decide what happens next */
XBOT:	refresh();
X	if (lines > 21)
X		{
X		paws(lines);
X		move(lines = 5,0);
X		clrtobot();
X		}
X	if (((int) foe->scratch2) == KILLED || myhits < 0.0)
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 */
XLEAVE:	updateme();
X	fclose(fin);
X	fclose(fout);
X	stat->x += roll(5,-10);
X	stat->y += roll(5,-10);
X	stat->nrg = myhits;
X	stat->tampered = OFF;
X	stat->status = PLAYING;
X	changed = TRUE;
X	paws(lines);
X	move(3,0);
X	clrtobot();
X}
X
Xint	interrupt()				/* call when break key is hit */
X{
Xchar	line[81];
Xreg	int	loop;
Xint	x, y, ch;
X
X#ifdef USG3
X	signal(SIGINT,SIG_IGN);
X#endif
X#ifdef USG5
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 = rgetch();
X		if (toupper(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 = rgetch();
X		if (toupper(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 USG3
X	signal(SIGINT,interrupt);
X#endif
X#ifdef USG5
X	signal(SIGINT,interrupt);
X#endif
X}
X
Xint	rgetch()		/* refresh, then get a char. */
X{
X	refresh();
X	return (getch());
X}
X
Xvoid	purge() 	/* remove old players */
X{
XFILE	*fin, *fout;
Xstruct	stats	sbuf;
Xreg	int	loc, today, temp;
Xlong	ltime;
X
X	loc = 0;
X	time(&ltime);
X	today = localtime(&ltime)->tm_yday;
X	fin = fopen(peoplefile,"r");
X	fout = fopen(peoplefile,ACCESS);
X	while(fread((char *) &sbuf,sizeof(sbuf),1,fin))
X		{
X		temp = today - sbuf.lastused;
X		if (temp < 0)
X			temp += 365;
X		if (temp > 9)		/* ten days old --> delete */
X			{
X			initchar(&sbuf);
X			strcpy(sbuf.name,"<null>");
X			fseek(fout,(long) loc * sizeof(sbuf),0);
X			fwrite((char *) &sbuf,sizeof(sbuf),1,fout);
X			}
X		++loc;
X		}
X	fclose(fin);
X	fclose(fout);
X}
!EOR!
echo extracting - main.c
sed 's/^X//' > main.c << '!EOR!'
X/*
X * Phantasia 3.2 -- Interterminal fantasy game
X *
X * Edward A. Estes
X * AT&T Teletype Corp., September 4, 1984
X */
X
X/*
X * This is the program which drives the whole mess.  Hopefully, you will be
X * able to wade throught 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 * 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.
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 between 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.
X */
X
X#include "phant.h"
X
Xdouble	strength, speed;
Xbool	beyond, marsh, throne, valhala, changed, fghting, su, wmhl;
Xint	fileloc, users;
Xjmp_buf	fightenv, mainenv;
Xlong	secs;
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
Xmain(argc,argv)				/* Phantasia main routine */
Xint	argc;
Xchar	*argv[];
X{
Xstruct	stats	charac;
Xchar	aline[200], *login = NULL;
Xdouble	x = 0.0, y = 0.0;
Xint	ch, ch2;
Xreg	int	loop, temp;
XFILE	*fp;
Xbool	shrt = FALSE, examine = FALSE, header = FALSE;
X
X	if ((login = getlogin()) == NULL)
X		login = getpwuid(getuid())->pw_name;
X#ifdef ENEMY
X	/* check hit list of restricted accounts */
X	if ((fp = fopen(enemyfile, "r")) != NULL)
X		{
X		char	enemy[20];
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	setbuf(stdin, (char *) NULL);	/* this may or may not be necessary */
X	su = (getuid() == UID);
X	fghting = FALSE;
X	users = 0;
X	if (argc > 1 && (*++argv)[0] == '-')
X		switch ((*argv)[1])
X			{
X			case 'h':		/* help */
X				printhelp();
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();
X				exit(0);
X				/*NOTREACHED*/
X			case 'p':		/* purge old players */
X				purge();
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();
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(23,27,"Sorry, you can't play now.\n");
X		exit1();
X		/*NOTREACHED*/
X		}
X#endif
X	mvaddstr(23,24,"Do you have a character to run? ");
X	ch = rgetch();
X	if (toupper(ch) == 'Y')
X		fileloc = findchar(&charac);
X	else
X		{
X		initchar(&charac);
X		clear();
X		mvaddstr(5,21,"Which type of character do you want:");
X		mvaddstr(10,4,"1:Magic User  2:Fighter  3:Elf  4:Dwarf  5:Halfling  6:Experimento  ? ");
X		ch = rgetch();
X		do
X			{
X			genchar(&charac,ch);
X			mvprintw(15,14,"Strength:  %2.0f  Manna      : %3.0f  Quickness   :  %2d",
X				charac.str,charac.man,charac.quk);
X			mvprintw(16,14,"Brains  :  %2.0f  Magic Level:  %2.0f  Energy Level:  %2.0f",
X				charac.brn,charac.mag,charac.nrg);
X			if (charac.typ != 6)
X				{
X				mvaddstr(17,14,"Type '1' to keep >");
X				ch2 = rgetch();
X				}
X			else
X				break;
X			}
X		while (ch2 != '1');
X		if (charac.typ == 6)
X			{
X			mvaddstr(19,0,"Enter the X Y coordinates of your experimento ? ");
X			getstring(aline,80);
X			sscanf(aline,"%F %F",&x,&y);
X			charac.x = (abs(x) > 1.2e+6) ? sgn(x)*1.2e+6 : floor(x);
X			charac.y = (abs(y) > 1.2e+6) ? sgn(y)*1.2e+6 : floor(y);
X			}
X		do
X			{
X			mvaddstr(20,0,"Give your character a name [up to 20 characters] ?  ");
X			getstring(aline,80);
X			strncpy(charac.name,aline,20);
X			charac.name[20] = '\0';
X			}
X		while (findname(charac.name));
X		putchar('\n');
X		fflush(stdout);
X		nocrmode();
X		do
X			{
X			strcpy(charac.pswd,getpass("Give your character a password [up to 8 characters] ? "));
X			putchar('\n');
X			strcpy(aline,getpass("One more time to verify ? "));
X			}
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 you character saved,\n");
X		printw("you may quit and mail your reason to '%s'.\n",WIZARD);
X		addstr("Do you want to quit ? ");
X		ch = rgetch();
X		if (toupper(ch) == 'Y')
X			{
X			charac.quk = -100;
X			leave(&charac);
X			/*NOTREACHED*/
X			}
X		death(&charac);
X		}
X	charac.status = PLAYING;
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,-1);
X#endif
X#ifdef	USG3
X	signal(SIGINT,interrupt);
X#endif
X#ifdef	USG5
X	signal(SIGINT,interrupt);
X#endif
X
X/* all set for now */
X
XTOP:	switch (setjmp(mainenv))
X		{
X		case QUIT:
X#ifdef	BSD41
X			sigrelse(SIGINT);
X#endif
X#ifdef	BSD42
X			signal(SIGINT,interrupt,-1);
X#endif
X#ifdef	USG3
X			signal(SIGINT,interrupt);
X#endif
X#ifdef	USG5
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,-1);
X#endif
X#ifdef	USG3
X			signal(SIGINT,interrupt);
X#endif
X#ifdef	USG5
X			signal(SIGINT,interrupt);
X#endif
X			death(&charac);
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(6,0,"You're not allowed in the Lord's Chamber without a crown.\n");
X		changed = TRUE;
X		charac.x = charac.y = 10;
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.nrg < 0 || (charac.lvl >= 10000 && charac.typ != 99))
X		death(&charac);
X	neatstuff(&charac);
X	if (changed)
X		{
X		update(&charac,fileloc);
X		changed = FALSE;
X		goto TOP;
X		}
X	move(5,0);
X	clrtoeol();
X	fp = fopen(messfile,"r");
X	if (fgets(aline,160,fp))
X		addstr(aline);
X	fclose(fp);
X	printstats(&charac);
X	move(3,0);
X	clrtoeol();
X	if (!wmhl)
X		{
X		if (throne)
X			kingstuff(&charac);
X		addstr("1:Move  2:Players  3:Talk  4:Stats  5:Quit  ");
X		if (charac.lvl >= 5 && charac.mag >= 15)
X			addstr("6:Cloak  ");
X		if (charac.lvl >= 10 && charac.mag >= 25)
X			addstr("7:Teleport  ");
X		if (charac.typ > 20)
X			addstr("8:Intervention");
X		ch = gch(charac.rng.type);
X		clrtoeol();
X		move(6,0);
X		clrtobot();
X		if (charac.typ == 99 && (ch == '1' || ch == '7'))
X			ch = ' ';
X		switch (ch2 = toupper(ch))
X			{
X			case 'N':
X				charac.y += maxmove;
X				break;
X			case 'S':
X				charac.y -= maxmove;
X				break;
X			case 'E':
X				charac.x += maxmove;
X				break;
X			case 'W':
X				charac.x -= maxmove;
X				break;
X			default:	/* rest */
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				else
X					{
X					charac.man += circ(charac.x,charac.y)/3+0.5;
X					charac.man += charac.lvl/5+0.5;
X					}
X				rndattack();
X				break;
X			case '1':	/* move */
X				for (loop = 3; loop; --loop)
X					{
X					mvaddstr(5,0,"X Y Coordinates ? ");
X					getstring(aline,80);
X					if (sscanf(aline,"%F %F",&x,&y) < 2)
X						;
X					else
X						if (hypot((double) charac.x - x, (double) 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				talk(charac.name);
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 < 5 || charac.mag < 15)
X					illcmd();
X				else if (charac.status == CLOAKED)
X					charac.status = PLAYING;
X				else if (charac.man < 35)
X					{
X					mvaddstr(6,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 < 10 || charac.mag < 25)
X					illcmd();
X				else 
X					for (loop = 3; loop; --loop)
X						{
X						mvaddstr(5,0,"X Y Coordinates ? ");
X						getstring(aline,80);
X						if (sscanf(aline,"%F %F",&x,&y) == 2)
X							if ((temp = hypot(charac.x-x,charac.y-y))
X									> (charac.lvl+charac.mag)*5+((charac.typ > 20) ? 1e+6 : 0)
X									&& !throne)
X								illmove();
X							else if ((temp = (temp/75+1)*20) > charac.man && !throne)
X								mvaddstr(6,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 '9':	/* monster */
X				if (throne)
X					mvaddstr(6,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 == '1' || ch2 == '7')
X			{
X			checkmov(&charac);
X			rndattack();
X			changed = TRUE;
X			}
X		}
X	else
X		{
X		addstr("F:Forward  B:Back  R:Right  L:Left  Q:Quit  T:Talk  P:Players  S:Stats  ");
X		ch = rgetch();
X		move(6,0);
X		clrtobot();
X		switch (toupper(ch))
X			{
X			default:
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				else
X					charac.man += charac.lvl/5+0.5;
X				break;
X			case 'F':
X				temp = (int) w_h[charac.wormhole].f;
X				goto CHKMOVE;
X			case 'B':
X				temp = (int) w_h[charac.wormhole].b;
X				goto CHKMOVE;
X			case 'R':
X				temp = (int) w_h[charac.wormhole].r;
X				goto CHKMOVE;
X			case 'L':
X				temp = (int) w_h[charac.wormhole].l;
X				goto CHKMOVE;
X			case 'Q':
X				leave(&charac);
X				/*NOTREACHED*/
X			case 'T':
X				talk(charac.name);
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			}
X		goto TOP;
XCHKMOVE:	if (!temp)
X				{
X				charac.y = 0.0;
X				charac.x = pow(-1.0,(double) charac.wormhole) * charac.wormhole * 400 - 1.0;
X				charac.wormhole = 0;
X				changed = TRUE;
X				}
X			else
X				charac.wormhole = temp;
X		}
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	ok_to_play()		/* return FALSE if playing is not allowed at this time */
X{
X#define	MAXUSERS	8	/* max. number of people on system */
Xreg	struct	tm	*tp;
Xreg	int	numusers = 0;
XFILE	*fp;
Xlong	now;
Xstruct	utmp	ubuf;
X
X	if (su)
X		return (TRUE);
X	/* check time of day */
X	time(&now);
X	if (((tp = localtime(&now))->tm_hour > 8 && tp->tm_hour < 12)	/* 8-noon */
X		|| (tp->tm_hour > 13 && tp->tm_hour < 16))		/* 1-4 pm */
X		return (FALSE);
X	/* check # of users */
X	fp = fopen("/etc/utmp","r");
X	while (fread((char *) &ubuf,sizeof(ubuf),1,fp))
X#ifdef	USG5
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	return (TRUE);
X}
X#endif
!EOR!
echo extracting - fight.c
sed 's/^X//' > fight.c << '!EOR!'
X/*
X * fight.c   Phantasia monster fighting routine
X */
X
X/*
X * The code exists here for fight to the finish.  Simply add code to
X * set 'fgttofin = TRUE' as an option.	Everything else is here.
X */
X#include "phant.h"
X
Xvoid	fight(stat,particular)			/* monster fighting routine */
Xreg	struct	stats	*stat;
Xint	particular;
X{
Xbool	fghttofin = FALSE, luckout = FALSE;
Xchar	aline[80];
Xdouble	monhit, mdamage, sdamage, monspd, maxspd, inflict, monstr, temp, shield;
Xint	ch;
Xreg	int	whichm, size, howmany, lines;
Xstruct	mstats	monster;
X
X	fghting = changed = TRUE;
X	shield = 0.0;
X	if (setjmp(fightenv) == 2)
X		shield = roll(100 + (stat->mxn + stat->shd)*6.2,3000);
X	howmany = 0;
X	size = (valhala) ? stat->lvl/5 : circ(stat->x,stat->y);
X	if (particular >= 0)
X		whichm = particular;
X	else if (marsh)
X		whichm = roll(0,15);
X	else if (size > 24)
X		whichm = roll(14,86);
X	else if (size > 15)
X		whichm = roll(0,50) + roll(14,37);
X	else if (size > 8)
X		whichm = roll(0,50) + roll(14,26);
X	else if (size > 3)
X		whichm = roll(14,50);
X	else 
X		whichm = roll(14,25);
X
XCALL:	move(3,0);
X	clrtobot();
X	move(5,0);
X	lines = 6;
X	callmonster(whichm,size,&monster);
X	if (stat->blind)
X		strcpy(monster.name,"a monster");
X	++howmany;
X	if (monster.typ == 1)	/* unicorn */
X		if (stat->vrg)
X			{
X			printw("You just subdued %s, thanx to the virgin.",monster.name);
X			stat->vrg = FALSE;
X			goto FINISH;
X			}
X		else
X			{
X			printw("You just saw %s running away!",monster.name);
X			goto LEAVE;
X			}
X	if (monster.typ == 2 && stat->typ > 20)
X		{
X		strcpy(monster.name,"Morgoth");
X		monster.str = rnd()*(stat->mxn + stat->shd)/1.4 + rnd()*(stat->mxn + stat->shd)/1.5;
X		monster.brn = stat->brn;
X		monster.hit = stat->str*30;
X		monster.typ = 23;
X		monster.spd = speed*1.1 + speed*(stat->typ == 90);
X		monster.flk = monster.trs = monster.exp = 0;
X		mvprintw(4,0,"You've encountered %s, Bane of the Council and Valar.",monster.name);
X		}
X	fghttofin = luckout = FALSE;
X	monstr = monster.str;
X	monhit = monster.hit;
X	mdamage = sdamage = 0;
X	monspd = maxspd = monster.spd;
X	*monster.name = toupper(*monster.name);
X
XTOP:	mvprintw(5,0,"You are being attacked by %s,   EXP: %.0f   (Size: %d)",monster.name,monster.exp,size);
X	printstats(stat);
X	mvprintw(1,26,"%20.0f",stat->nrg + shield);
X	if (monster.typ == 4 && stat->bls && stat->chm)
X		{
X		mvprintw(6,0,"You just overpowered %s!",monster.name);
X		lines = 7;
X		stat->bls = FALSE;
X		--stat->chm;
X		goto FINISH;
X		}
X	monster.spd = min(monster.spd + 1,maxspd);
X	if (rnd()*monster.spd > rnd()*speed && monster.typ != 4 && monster.typ != 16)
X		{
X		if (monster.typ)
X			switch (monster.typ)	/* do special things */
X				{
X				case 5: /* Leanan-Sidhe */
X					if (rnd() > 0.25)
X						goto NORMALHIT;
X					inflict = roll(1,(size - 1)/2);
X					inflict = min(stat->str,inflict);
X					mvprintw(lines++,0,"%s sapped %0.f of your strength!",monster.name,inflict);
X					stat->str -= inflict;
X					strength -= inflict;
X					break;
X				case 6: /* Saruman */
X					if (stat->pal)
X						{
X						mvprintw(lines++,0,"Wormtongue stole your palantir!");
X						stat->pal = FALSE;
X						}
X					else if (rnd() > 0.2)
X						goto NORMALHIT;
X					else if (rnd() > 0.5)
X						{
X						mvprintw(lines++,0,"%s transformed your gems into gold!",monster.name);
X						stat->gld += stat->gem;
X						stat->gem = 0.0;
X						}
X					else
X						{
X						mvprintw(lines++,0,"%s scrambled your stats!",monster.name);
X						scramble(stat);
X						}
X					break;
X				case 7: /* Thaumaturgist */
X					if (rnd() > 0.15)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"%s transported you!",monster.name);
X					stat->x += sgn(stat->x)*roll(50*size,250*size);
X					stat->y += sgn(stat->y)*roll(50*size,250*size);
X					goto LEAVE;
X				case 8: /* Balrog */
X					inflict = roll(10,monster.str);
X					inflict = min(stat->exp,inflict);
X					mvprintw(lines++,0,"%s took away %0.f experience points.",monster.name,inflict);
X					stat->exp -= inflict;
X					break;
X				case 9: /* Vortex */
X					if (rnd() > 0.2)
X						goto NORMALHIT;
X					inflict = roll(0,7.5*size);
X					inflict = min(stat->man,floor(inflict));
X					mvprintw(lines++,0,"%s sucked up %.0f of your manna!",monster.name,inflict);
X					stat->man -= inflict;
X					break;
X				case 10:	/* Nazgul */
X					if (rnd() > 0.3)
X						goto NORMALHIT;
X					if (stat->rng.type && stat->rng.type < 10)
X						{
X						mvaddstr(lines++,0,"Will you relinguish your ring ? ");
X						ch = rgetch();
X						if (toupper(ch) == 'Y')
X							{
X							stat->rng.type = NONE;
X							goto LEAVE;
X							}
X						}
X					mvprintw(lines++,0,"%s neutralized 1/5 of your brain!",monster.name);
X					stat->brn *= 0.8;
X					break;
X				case 11:	/* Tiamat */
X					if (rnd() > 0.6)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"%s took half your gold and gems and flew off.",monster.name);
X					stat->gld = floor(stat->gld/2);
X					stat->gem = floor(stat->gem/2);
X					goto LEAVE;
X				case 12:	/* Kobold */
X					if (rnd() >.7)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"%s stole one gold piece and ran away.",monster.name);
X					stat->gld = max(0,stat->gld-1);
X					goto LEAVE;
X				case 13:	/* Shelob */
X					if (rnd() > 0.5)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"%s has bitten and poisoned you!",monster.name);
X					++stat->psn;
X					break;
X				case 14:	/* Faeries */
X					if (!stat->hw)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"Your holy water killed it!");
X					--stat->hw;
X					goto FINISH;
X				case 15:	/* Lamprey */
X					if (rnd() > 0.7)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"%s bit and poisoned you!",monster.name);
X					stat->psn += 0.25;
X					break;
X				case 17:	/* Bonnacon */
X					if (rnd() > 0.1)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"%s farted and scampered off.",monster.name);
X					stat->nrg /= 2;
X					goto LEAVE;
X				case 18:	/* Smeagol */
X					if (rnd() > 0.5 || !stat->rng.type)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"%s tried to steal your ring, ",monster.name);
X					if (rnd() > 0.1)
X						addstr("but was unsuccessful.");
X					else
X						{
X						addstr("and ran away with it!");
X						stat->rng.type = NONE;
X						goto LEAVE;
X						}
X					break;
X				case 19:	/* Succubus */
X					if (rnd() > 0.3)
X						goto NORMALHIT;
X					inflict = roll(15,size*10);
X					inflict = min(inflict,stat->nrg);
X					mvprintw(lines++,0,"%s sapped %0.f of your energy.",monster.name,inflict);
X					stat->nrg -= inflict;
X					break;
X				case 20:	/* Cerberus */
X					if (rnd() > 0.25)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"%s took all your metal treasures!",monster.name);
X					stat->swd = stat->shd =stat->gld = stat->crn = 0;
X					goto LEAVE;
X				case 21:	/* Ungoliant */
X					if (rnd() > 0.1)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"%s poisoned you, and took one quik.",monster.name);
X					stat->psn += 5;
X					--stat->quk;
X					break;
X				case 22:	/* Jabberwock */
X					if (rnd() > 0.1)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"%s flew away, and left you to contend with one of its friends.",monster.name);
X					whichm = 55 + 22*(rnd() > 0.5);
X					goto CALL;
X				case 24:	/* Troll */
X					if (rnd() > 0.5)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"%s partially regenerated his energy.!",monster.name);
X					monster.hit += floor((monhit*size - monster.hit)/2);
X					monster.str = monstr;
X					mdamage = sdamage = 0;
X					maxspd = monspd;
X					break;
X				case 25:	/* wraith */
X					if (rnd() > 0.3 || stat->blind)
X						goto NORMALHIT;
X					mvprintw(lines++,0,"%s blindeed you!",monster.name);
X					stat->blind = TRUE;
X					break;
X				default:
X					goto NORMALHIT;
X				}
X		else
XNORMALHIT:		{
X			inflict = rnd()*monster.str + 0.5;
X			mvprintw(lines++,0,"%s hit you %.0f times!",monster.name,inflict);
XSPECIALHIT:		if ((shield -= inflict) < 0)
X				{
X				stat->nrg += shield;
X				shield = 0;
X				}
X			}
X		}
X	else
X		{
X		if (fghttofin)
X			goto MELEE;
X		mvaddstr(3,0,"1:Melee  2:Skirmish  3:Evade  4:Spell  5:Nick  ");
X		if (!luckout)
X			if (monster.typ == 23)
X				addstr("6:Ally  ");
X			else
X				addstr("6:Luckout  ");
X		if (stat->rng.type > 0)
X			addstr("7:Use Ring  ");
X		else
X			clrtoeol();
X		ch = gch(stat->rng.type);
X		move(lines = 6,0);
X		clrtobot();
X		switch (ch)
X			{
X			default:
X			case '1':	/* melee */
XMELEE:				inflict = roll(strength/2 + 5,1.3*strength) + (stat->rng.type < 0 ? strength : 0);
X				mdamage += inflict;
X				monster.str = monstr - mdamage/monhit*monstr/4;
X				goto HITMONSTER;
X			case '2':	/* skirmish */
X				inflict = roll(strength/3 + 3,1.1*strength) + (stat->rng.type < 0 ? strength : 0);
X				sdamage += inflict;
X				maxspd = monspd - sdamage/monhit*monspd/4;
X				goto HITMONSTER;
X			case '3':	/* evade */
X				if ((monster.typ == 4 || monster.typ == 16
X				|| rnd()*speed*stat->brn > rnd()*monster.spd*monster.brn)
X				&& (monster.typ != 23))
X					{
X					mvaddstr(lines++,0,"You got away!");
X					stat->x += roll(-2,5);
X					stat->y += roll(-2,5);
X					goto LEAVE;
X					}
X				else
X					mvprintw(lines++,0,"%s is still after you!",monster.name);
X				break;
X			case '4':	/* spell */
X				lines = 7;
X				mvaddstr(3,0,"\n\n");
X				mvaddstr(3,0,"1:All or Nothing");
X				if (stat->mag >= 3)
X					mvaddstr(3,18,"2:Magic Bolt");
X				if (stat->mag >= 7)
X					mvaddstr(3,32,"3:Force Field");
X				if (stat->mag >= 10)
X					mvaddstr(3,47,"4:Transform");
X				if(stat->mag >= 15)
X					mvaddstr(3,60,"5:Increase Might\n");
X				if (stat->mag >= 20)
X					mvaddstr(4,0,"6:Invisibility");
X				if (stat->mag >= 25)
X					mvaddstr(4,18,"7:Transport");
X				if (stat->mag >= 30)
X					mvaddstr(4,32,"8:Paralyze");
X				if (stat->typ > 20)
X					mvaddstr(4,52,"9:Specify");
X				mvaddstr(6,0,"Spell ? ");
X				ch = rgetch();
X				mvaddstr(3,0,"\n\n");
X				if (monster.typ == 23 && ch != '4')
X					illspell();
X				else
X					switch (ch)
X						{
X						case '1':	/* all or nothing */
X							{
X							inflict = (rnd() < 0.25) ? (monster.hit*1.0001 + 1) : 0;
X							if (monster.typ == 4)
X								inflict *= .9;
X							if (stat->man)
X								--stat->man;
X							maxspd *= 2;
X							monspd *= 2;
X							monster.spd = max(1,monster.spd * 2);
X							monstr = monster.str *= 2;
X							goto HITMONSTER;
X							}
X						case '2':	/* magic bolt */
X							if (stat->mag < 3)
X								illspell();
X							else
X								{
X								do
X									{
X									mvaddstr(6,0,"How much manna for bolt? ");
X									getstring(aline,80);
X									sscanf(aline,"%F",&temp);
X									}
X								while (temp < 0 || temp > stat->man);
X								stat->man -= floor(temp);
X								inflict = temp*roll(10,sqrt(stat->mag/3.0 + 1.0));
X								mvaddstr(6,0,"Magic Bolt fired!\n");
X								if (monster.typ == 4)
X									inflict = 0.0;
X								goto HITMONSTER;
X								}
X						case '5':	/* increase might */
X							{
X							if (stat->mag < 15)
X								illspell();
X							else if (stat->man < 55)
X								nomanna();
X							else
X								{
X								stat->man -= 55;
X								strength += (1.2*(stat->str+stat->swd)+5-strength)/2;
X								mvprintw(6,0,"New strength:  %.0f\n",strength);
X								}
X							break;
X							}
X						case '3':	/* force field */
X							{
X							if (stat->mag < 7)
X								illspell();
X							else if (stat->man < 20)
X								nomanna();
X							else
X								{
X								shield = (stat->mxn + stat->shd)*4.2 + 45;
X								stat->man -= 20;
X								mvaddstr(6,0,"Force Field up.\n");
X								}
X							break;
X							}
X						case '4':	/* transform */
X							{
X							if (stat->mag < 10)
X								illspell();
X							else if (stat->man < 35)
X								nomanna();
X							else
X								{
X								stat->man -= 35;
X								whichm = roll(0,100);
X								goto CALL;
X								}
X							break;
X							}
X						case '6':	/* invisible */
X							{
X							if (stat->mag < 20)
X								illspell();
X							else if (stat->man < 45)
X								nomanna();
X							else
X								{
X								stat->man -= 45;
X								speed += (1.2*(stat->quk+stat->quks)+5-speed)/2;
X								mvprintw(6,0,"New quik :  %.0f\n",speed);
X								}
X							break;
X							}
X						case '7':	/* transport */
X							{
X							if (stat->mag < 25)
X								illspell();
X							else if (stat->man < 50)
X								nomanna();
X							else
X								{
X								stat->man -= 50;
X								if (stat->brn + stat->mag < monster.exp/300*rnd())
X									{
X									mvaddstr(6,0,"Transport backfired!\n");
X									stat->x += (250*size*rnd() + 50*size)*sgn(stat->x);
X									stat->y += (250*size*rnd() + 50*size)*sgn(stat->y);
X									goto LEAVE;
X									}
X								else
X									{
X									mvprintw(6,0,"%s is transported.\n",monster.name);
X									monster.trs *= (rnd() > 0.3);
X									goto FINISH;
X									}
X								}
X							break;
X							}
X						case '8':	/* paralyze */
X							{
X							if (stat->mag < 30)
X									illspell();
X							else if (stat->man < 60)
X								nomanna();
X							else
X								{
X								stat->man -= 60;
X								if (stat->mag > monster.exp/1000*rnd())
X									{
X									mvprintw(6,0,"%s is held.\n",monster.name);
X									monster.spd = -2;
X									}
X								else
X									mvaddstr(6,0,"Monster unaffected.\n");
X								}
X							break;
X							}
X						case '9':	/* specify */
X							{
X							if (stat->typ < 20)
X								illspell();
X							else if (stat->man < 1000)
X								nomanna();
X							else
X								{
X								mvaddstr(6,0,"Which monster do you want [0-99] ? ");
X								whichm = inflt();
X								whichm = max(0,min(99,whichm));
X								stat->man -= 1000;
X								goto CALL;
X								}
X							break;
X							}
X						}
X				break;
X			case '5':
X				inflict = 1 + stat->swd;
X				stat->exp += floor(monster.exp/10);
X				monster.exp *= 0.92;
X				maxspd += 2;
X				monster.spd = (monster.spd < 0) ? 0 : monster.spd + 2;
X				if (monster.typ == 4)
X					{
X					mvprintw(lines++,0,"You hit %s %.0f times, and made him mad!",monster.name,inflict);
X					stat->quk /= 2;
X					stat->x += sgn(stat->x)*roll(50*size,250*size);
X					stat->y += sgn(stat->y)*roll(50*size,250*size);
X					stat->y += (250*size*rnd() + 50*size)*sgn(stat->y);
X					goto LEAVE;
X					}
X				else
X					goto HITMONSTER;
X			case '6':	/* luckout */
X				if (luckout)
X					mvaddstr(lines++,0,"You already tried that.");
X				else
X					if (monster.typ == 23)
X						if (rnd() < stat->sin/100)								{
X							mvprintw(lines++,0,"%s accepted!",monster.name);
X							goto LEAVE;
X							}
X						else
X							{
X							luckout = TRUE;
X							mvaddstr(lines++,0,"Nope, he's not interested.");
X							}
X					else
X						if ((rnd() + .333)*stat->brn < (rnd() + .333)*monster.brn)
X							{
X							luckout = TRUE;
X							mvprintw(lines++,0,"You blew it, %s.",stat->name);
X							}
X						else
X							{
X							mvaddstr(lines++,0,"You made it!");
X							goto FINISH;
X							}
X				break;
X			case '\014':	/* clear screen */
X				clear();
X				break;
X			case '7':	/* use ring */
X				if (stat->rng.type > 0)
X					{
X					mvaddstr(lines++,0,"Now using ring.");
X						stat->rng.type = -stat->rng.type;
X						if (abs(stat->rng.type) != DLREG)
X							--stat->rng.duration;
X						goto NORMALHIT;
X					}
X				break;
X			}
X		goto BOT;
XHITMONSTER:		{
X			inflict = floor(inflict);
X			mvprintw(lines++,0,"You hit %s %.0f times!",monster.name,inflict);
X			if ((monster.hit -= inflict) >0)
X				switch (monster.typ)
X					{
X					case 4: /* dark lord */
X						inflict = stat->nrg + shield +1;
X						goto SPECIALHIT;
X					case 16:	/* shrieker */
X						mvaddstr(lines++,0,"Shreeeek!!  You scared it, and it called one of its friends.");
X						paws(lines);
X						whichm = roll(70,30);
X						goto CALL;
X					}
X			else
X				{
X				if (monster.typ == 23)	/* morgoth */
X					mvaddstr(lines++,0,"You have defeated Morgoth, but he may return. . .");
X				else
X					mvprintw(lines++,0,"You killed it.  Good work, %s.",stat->name);
X				goto FINISH;
X				}
X			}
X		}
XBOT:	refresh();
X	if (lines == 23)
X		{
X		paws(23);
X		move(lines = 6,0);
X		clrtobot();
X		}
X	if (stat->nrg <= 0)
X		{
X		paws(lines);
X		death(stat);
X		goto LEAVE;
X		}
X	goto TOP;
XFINISH:	stat->exp += monster.exp;
X	if (rnd() < monster.flk/100.0)	/* flock monster */
X		{
X		paws(lines);
X		fghttofin = FALSE;
X		goto CALL;
X		}
X	else if (size > 1 && monster.trs && rnd() > pow(0.6,(double) (howmany/3 + size/3)))	/* this takes # of flocks and size into account */
X		{
X		paws(lines);
X		treasure(stat,monster.trs,size);
X		}
XLEAVE:	stat->rng.type = abs(stat->rng.type);
X	paws(lines+3);
X	move(4,0);
X	clrtobot();
X	fghting = FALSE;
X}
!EOR!

chuqui@nsc.UUCP (Chuqles) (09/12/84)

> *eek* >[You saved that file which took 7 blocks and it doesn't work?]
> *eek* >[Yup.]
> *eek* >[Ha, ha, ha, ha, ha]
> *eek* >
> *eek* >Well that's what it's like.  The game Phantasia (whoever
> *eek* >posted it) DOES NOT WORK!!!
> *eek* >
> *eek* >ROAR
> *eek* >[In case you don't know, that's a dragon flame]
> *eek* >	 > > > > > > > > > > 
> *eek* >[Did you see that flame whiz by at 9600 baud?]
> *eek* >	 > > > > > > > > > > 
> *eek* >[There's another!]

Well, I hate to say this, but I got the same posting of phantasia that you
did, and it works fine for me over here.... Perhaps you simply don't have
it set up properly? Perhaps you don't know how? 

Please note: This flame will self-destruct before it gets archived-- this
stuff doesn't belong on net.sources, you know.

chuq
-- 
From the spotlight of the center ring:		Chuqles Von Rospach
{amd,decwrl,fortune,hplabs,ihnp4}!nsc!chuqui	nsc!chuqui@decwrl.ARPA

And now... Mutual of Omaha presents "Penguins: Antarctica's little clowns"

greenber@acf4.UUCP (09/13/84)

> /***** acf4:net.sources / ksl@hou2e /  5:05 pm  Sep  6, 1984*/
> The game Phantasia (whoever posted it) DOES NOT WORK!!!


Oh it works okay...you just have to hunt around for the files that
it looks for.  Make sure that all the files in phant.h exist.
The game is good multi-player, but not much on a single user basis.
I prefer rogue.


Ross M. Greenberg  @ NYU   ---->  allegra!cmcl2!acf4!greenber  <----

tlw@hocsf.UUCP (09/17/84)

5