Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1 6/24/83; site ttrda.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxj!mhuxn!ihnp4!nwuxg!cuuxc!cuuxb!ltuxa!ttrdc!ttrda!estes
From: estes@ttrda.UUCP (Edward Estes )
Newsgroups: net.sources.games
Subject: Phantasia 3.3 (part 2 of 3)
Message-ID: <126@ttrda.UUCP>
Date: Tue, 16-Jul-85 01:35:45 EDT
Article-I.D.: ttrda.126
Posted: Tue Jul 16 01:35:45 1985
Date-Received: Thu, 11-Jul-85 08:15:17 EDT
Organization: AT&T Teletype Corp., Skokie, IL
Lines: 1955

: This is a shar archieve.  Extract with sh, not csh.
: The rest of this file will extract:
: Makefile.noxst Makefile.xstr fight.c func1.c phant.h
echo extracting - Makefile.noxst
sed 's/^X//' > Makefile.noxst << '!EOR!'
X# Makefile for Phantasia 3.3
X#
X# Use this makefile if you don't have 'xstr'.  Use the other makefile if you do.
X# To create game:
X#
X# 1)  Set up a directory where the game and its support files will live.
X#        (It is suggested that the source be kept somewhere else.)
X# 2)  Set up the variables in Makefile to reflect your particular situation.
X# 3)  Check out ok_to_play() at the end of main.c if you want to include
X#        code to restrict access at certain times.
X# 4)  'make install' and watch it fly.  It is important to run 'setup' before
X#	 trying to run 'phantasia'.  The install procedure does this for you.
X
XRM =		-rm
X
X# Add '-ljobs' to LIBS if 4.1bsd; add -ltermlib if not SVR2
XLIBS =		-lm -lcurses
X# May need '-I/usr/include/sys' for 4.2bsd
XCFLAGS =	-O
X
X# DEST is where the program and its support files reside
XDEST =		/a2/estes/phant
X
X# The following are program constants which are implementation dependent.
X#
X# PATH is the same as $DEST.
X# WIZARD is the login of the one who will clean up things.
X# UID is the uid of game wizard.
X# RAND is one more than the largest number generated by rand().
X#	Possible values for this are:
X#		32768.0		(for 15 bit rand())
X#		65536.0		(for 16 bit rand())
X#		2147483648.0	(for 31 bit rand())
X# ACCESS is fopen() access to open a file for writing, but no
X#	clearing the file,  e.g. "a", or "r+".  (Use "r+" if you have it.)
X# define OK_TO_PLAY to restrict playing access.  Also see function ok_to_play()
X#	in main.c, and tailor to your own needs.
X# define ENEMY to include code for checking of a 'hit list' of resricted 
X#	accounts.  The list of logins goes in the file 'enemy'.
X# define BSD41 for 4.1bsd
X# define BSD42 for 4.2bsd
X# define SYS3 for System III, or similar
X# define SYS5 for System V
X# define SMALL to save a little space (omits wormholes)
X# If you don't have 'strchr()', put '-Dstrchr=index' below.
XFLAGS = 	-DPATH=\"${DEST} \
X		-DWIZARD=\"estes\" \
X		-DUID=419 \
X		-DRAND=32767.0 \
X		-DACCESS=\"r+\" \
X		-DOK_TO_PLAY \
X		-DENEMY \
X		-DSYS5
X
XOFILES =	main.o fight.o func0.o func1.o func2.o func3.o
X
Xall:		phantasia setup phant.help
X
X# need separate i/d space on small machines
Xphantasia:	${OFILES} pathdefs.o
X		${CC} ${OFILES} strings.o pathdefs.o ${LIBS} -o phantasia
X
X${OFILES}:	phant.h
X		${CC} -c ${CFLAGS} ${FLAGS} $*.c
X
Xpathdefs.o:	phant.h
X		${CC} -c ${CFLAGS} ${FLAGS} pathdefs.c
X
Xsetup:		phant.h pathdefs.o
X		${CC} ${CFLAGS} ${FLAGS} setup.c -o setup pathdefs.o -lm
X
Xlint:
X		lint ${CFLAGS} ${FLAGS} func?.c main.c fight.c pathdefs.c ${LIBS}
X
X# the flags below on tbl and nroff are to make a line printable version
Xphant.help:	phant.nr
X		tbl -TX phant.nr | nroff -man -Ttn300 > phant.help
X
Xinstall:	all
X		cp phantasia monsters phant.help ${DEST}
X		chmod 755 ${DEST}
X		chmod 4711 ${DEST}/phantasia
X		chmod 644 ${DEST}/phant.help
X		setup
X
Xclean:
X		${RM} -f *.o phantasia phant.help
!EOR!
echo extracting - Makefile.xstr
sed 's/^X//' > Makefile.xstr << '!EOR!'
X# Makefile for Phantasia 3.3
X#
X# Use this makefile if you have 'xstr'.  Use the other makefile if you don't.
X#
X# To create game:
X#
X# 1)  Set up a directory where the game and its support files will live.
X#        (It is suggested that the source be kept somewhere else.)
X# 2)  Set up the variables in Makefile to reflect your particular situation.
X# 3)  Check out ok_to_play() at the end of main.c if you want to include
X#        code to restrict access at certain times.
X# 4)  'make install' and watch it fly.  It is important to run 'setup' before
X#	 trying to run 'phantasia'.  The install procedure does this for you.
X
XXSTR =		/a2/estes/bin/xstr
XRM =		-rm
X
X# Add '-ljobs' to LIBS if 4.1bsd; add -ltermlib if not SVR2
XLIBS =		-lm -lcurses
X# May need '-I/usr/include/sys' for 4.2bsd
XCFLAGS =	-O
X
X# DEST is where the program and its support files reside
XDEST =		/a2/estes/phant
X
X# The following are program constants which are implementation dependent.
X#
X# PATH is the same as $DEST.
X# WIZARD is the login of the one who will clean up things.
X# UID is the uid of game wizard.
X# RAND is one more than the largest number generated by rand().
X#	Possible values for this are:
X#		32768.0		(for 15 bit rand())
X#		65536.0		(for 16 bit rand())
X#		2147483648.0	(for 31 bit rand())
X# ACCESS is fopen() access to open a file for writing, but no
X#	clearing the file,  e.g. "a", or "r+".  (Use "r+" if you have it.)
X# define OK_TO_PLAY to restrict playing access.  Also see function ok_to_play()
X#	in main.c, and tailor to your own needs.
X# define ENEMY to include code for checking of a 'hit list' of resricted 
X#	accounts.  The list of logins goes in the file 'enemy'.
X# define BSD41 for 4.1bsd
X# define BSD42 for 4.2bsd
X# define SYS3 for System III, or similar
X# define SYS5 for System V
X# define SMALL to save a little space (omits wormholes)
X# If you don't have 'strchr()', put '-Dstrchr=index' below.
XFLAGS = 	-DPATH=\"${DEST} \
X		-DWIZARD=\"estes\" \
X		-DUID=419 \
X		-DRAND=32767.0 \
X		-DACCESS=\"r+\" \
X		-DOK_TO_PLAY \
X		-DENEMY \
X		-DSYS5
X
XOFILES =	main.o fight.o func0.o func1.o func2.o func3.o
X
Xall:		phantasia setup phant.help
X
X# need separate i/d space on small machines
Xphantasia:	${OFILES} strings.o pathdefs.o
X		${CC} ${OFILES} strings.o pathdefs.o ${LIBS} -o phantasia
X
X${OFILES}:	phant.h
X		${CC} -E ${CFLAGS} ${FLAGS} $*.c | ${XSTR} -c -
X		${CC} -c ${CFLAGS} x.c
X		mv x.o $*.o
X
Xpathdefs.o:	phant.h
X		${CC} -c ${CFLAGS} ${FLAGS} pathdefs.c
X
Xstrings.o:	strings
X		${XSTR}
X		${CC} -c xs.c
X		mv xs.o strings.o
X
Xsetup:		phant.h pathdefs.o
X		${CC} ${CFLAGS} ${FLAGS} setup.c -o setup pathdefs.o -lm
X
Xlint:
X		lint ${CFLAGS} ${FLAGS} func?.c main.c fight.c pathdefs.c ${LIBS}
X
X# the flags below on tbl and nroff are to make a line printable version
Xphant.help:	phant.nr
X		tbl -TX phant.nr | nroff -man -Ttn300 > phant.help
X
Xinstall:	all
X		cp phantasia monsters phant.help ${DEST}
X		chmod 755 ${DEST}
X		chmod 4711 ${DEST}/phantasia
X		chmod 644 ${DEST}/phant.help
X		setup
X
Xclean:
X		${RM} -f *.o phantasia phant.help strings x.c xs.c
!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 */
Xstruct	stats	*stat;
Xint particular;
X{
Xbool	fghttofin = FALSE, luckout = FALSE, firsthit = stat->bls;
Xchar	aline[80];
Xdouble	monhit, mdamage, sdamage, monspd, maxspd, inflict, monstr, temp, shield;
Xint ch;
Xint 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 = 1;
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    move(6,0);
X    clrtobot();
X
XCALL: move(6,0);
X    lines = 9;
X    callmonster(whichm,size,&monster);
X    if (stat->blind)
X	strcpy(monster.name,"a monster");
X    if (monster.typ == 1)   /* unicorn */
X	if (stat->vrg)
X	    {
X	    printw("You just subdued %s, thanx to the virgin.\n",monster.name);
X	    stat->vrg = FALSE;
X	    goto FINISH;
X	    }
X	else
X	    {
X	    printw("You just saw %s running away!\n",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.\n",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    if (speed <= 0)
X	{
X	monster.spd += - speed;
X	speed = 1;
X	}
X    *monster.name = toupper(*monster.name);
X    move(8,0);
X    clrtobot();
X
XTOP:	mvprintw(6,0,"You are being attacked by %s,   EXP: %.0f   (Size: %d)\n",monster.name,monster.exp,size);
X    printstats(stat);
X    mesg();
X    mvprintw(1,26,"%20.0f",stat->nrg + shield);
X    if (monster.typ == 4 && stat->bls && stat->chm)
X	{
X	mvprintw(7,0,"You just overpowered %s!",monster.name);
X	lines = 8;
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	    && !firsthit)
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 %.0f 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 mana!",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 = getans("YN", FALSE);
X			if (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 %.0f 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 blinded 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(7,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	firsthit = FALSE;
X	move(8,0);
X	clrtobot();
X	lines = 9;
X	mvaddstr(4,0,"\n\n");
X	switch (ch)
X	    {
X	    case 'T':	/* timeout; lose turn */
X		break;
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		mvaddstr(7,0,"\n\n");
X		mvaddstr(7,0,"1:All or Nothing  ");
X		if (stat->mag >= 5)
X		    addstr("2:Magic Bolt  ");
X		if (stat->mag >= 15)
X		    addstr("3:Force Field  ");
X		if (stat->mag >= 25)
X		    addstr("4:Transform  ");
X		if(stat->mag >= 35)
X		    addstr("5:Increase Might\n");
X		if (stat->mag >= 45)
X		    mvaddstr(8,0,"6:Invisibility  ");
X		if (stat->mag >= 60)
X		    addstr("7:Transport  ");
X		if (stat->mag >= 75)
X		    addstr("8:Paralyze  ");
X		if (stat->typ > 20)
X		    addstr("9:Specify");
X		mvaddstr(4,0,"Spell ? ");
X		ch = getans(" ", TRUE);
X		mvaddstr(7,0,"\n\n");
X		if (monster.typ == 23 && ch != '3')
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 < 5)
X				illspell();
X			    else
X				{
X				do
X				    {
X				    mvaddstr(4,0,"How much mana 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(5,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 < 45)
X				illspell();
X			    else if (stat->man < 75)
X				nomana();
X			    else
X				{
X				stat->man -= 75;
X				strength += (1.2*(stat->str+stat->swd)+5-strength)/2;
X				mvprintw(5,0,"New strength:  %.0f\n",strength);
X				}
X			    break;
X			    }
X			case '3':   /* force field */
X			    {
X			    if (stat->mag < 15)
X				illspell();
X			    else if (stat->man < 30)
X				nomana();
X			    else
X				{
X				shield = (stat->mxn + stat->shd)*4.2 + 45;
X				stat->man -= 30;
X				mvaddstr(5,0,"Force Field up.\n");
X				}
X			    break;
X			    }
X			case '4':   /* transform */
X			    {
X			    if (stat->mag < 25)
X				illspell();
X			    else if (stat->man < 50)
X				nomana();
X			    else
X				{
X				stat->man -= 50;
X				whichm = roll(0,100);
X				goto CALL;
X				}
X			    break;
X			    }
X			case '6':   /* invisible */
X			    {
X			    if (stat->mag < 45)
X				illspell();
X			    else if (stat->man < 90)
X				nomana();
X			    else
X				{
X				stat->man -= 90;
X				speed += (1.2*(stat->quk+stat->quks)+5-speed)/2;
X				mvprintw(5,0,"New quik :  %.0f\n",speed);
X				}
X			    break;
X			    }
X			case '7':   /* transport */
X			    {
X			    if (stat->mag < 60)
X				illspell();
X			    else if (stat->man < 125)
X				nomana();
X			    else
X				{
X				stat->man -= 125;
X				if (stat->brn + stat->mag < monster.exp/200*rnd())
X				    {
X				    mvaddstr(5,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(5,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 < 75)
X				    illspell();
X			    else if (stat->man < 150)
X				nomana();
X			    else
X				{
X				stat->man -= 150;
X				if (stat->mag > monster.exp/1000*rnd())
X				    {
X				    mvprintw(5,0,"%s is held.\n",monster.name);
X				    monster.spd = -2;
X				    }
X				else
X				    mvaddstr(5,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				nomana();
X			    else
X				{
X				mvaddstr(5,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 HITMONSTER;
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 > LINES - 2)
X	{
X	paws(lines);
X	move(lines = 8,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	++howmany;
X	goto CALL;
X	}
X    else if (size > 1 && monster.trs && rnd() > 0.2 + pow(0.4,(double) (howmany/3.0 + size/3.0)))   /* this takes # of flocks and size into account */
X	{
X	paws(lines);
X	treasure(stat,monster.trs,size);
X	}
X    else
XLEAVE:	    paws(lines);
X    stat->rng.type = abs(stat->rng.type);
X    move(4,0);
X    clrtobot();
X    fghting = FALSE;
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
Xint findname(name,stat) 	    /* return location of character 'name' */
Xreg char    *name;		    /* return -1 if not found, fill structure */
Xreg struct stats *stat; 	    /* if pointer is non-null */
X{
XFILE	*fp;
Xstruct	stats	sbuf;
Xint	loc = 0;
X
X    if (stat == NULL)
X	stat = &sbuf;
X    fp = fopen(peoplefile,"r");
X    while (fread((char *) stat,sizeof(sbuf),1,fp))
X	if (!strcmp(stat->name,name))
X	    {
X	    fclose(fp);
X	    return (loc);
X	    }
X	else
X	    ++loc;
X    fclose(fp);
X    return (-1);
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,""))
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];
X
X    clear();
X    mvprintw(10,0,"What was your character's name ? ");
X    getstring(name,21);
X    trunc(name);
X    if ((loc = findname(name, stat)) >= 0)
X	{
X	move(11,0);
X	refresh();
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    else
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,"");
X    stat->status = OFF;
X    time(<emp);
X    stat->age += ltemp - secs;
X    update(stat,fileloc);
X    exit1();
X    /*NOTREACHED*/
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    scoreboard(stat);
X    fp = fopen(lastdead,"w");
X    fprintf(fp,"%s   Login:  %s  Level: %d  Type: %d",stat->name,stat->login,stat->lvl,stat->typ);
X    fclose(fp);
X    initchar(stat);
X    strcpy(stat->name,"");
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 = getans("NY", FALSE);
X    if (ch == 'Y')
X	{
X	endwin();
X	execl(gameprog, "phantasia", "-s", (su ? "-S": (char *) NULL), 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	mloc;
Xlong	ltmp;
Xint ch;
X
X    if (stat->blind)
X	{
X	mvaddstr(8,0,"You can't see anyone.\n");
X	return;
X	}
X    mloc = circ(stat->x,stat->y);
X    mvaddstr(8,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 || 
X		mloc >= 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(<mp);
X    printw("Total users = %d    %s\n",loop,ctime(<mp));
X    refresh();
X}
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.3)!");
X    if ((fp = fopen(motd,"r")) != NULL && fgets(instr,80,fp))
X	{
X	mvaddstr(2,40 - strlen(instr)/2,instr);
X	fclose(fp);
X	}
X    if ((fp = fopen(peoplefile,"r")) == NULL)
X	{
X	error(peoplefile);
X	/*NOTREACHED*/
X	}
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 (<=5) 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(15,28,"Highest characters are:");
X    sprintf(instr,"%s  Level:%d   and   %s  Level:%d",hiname,hilvl,nxtname,nxtlvl);
X    mvaddstr(17,40 - strlen(instr)/2,instr);
X    if ((fp = fopen(lastdead,"r")) != NULL)
X	{
X	fgets(aline,80,fp);
X	sprintf(instr,"The last character to die is %s",aline);
X	mvaddstr(19,40 - strlen(instr)/2,instr);
X	fclose(fp);
X	}
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    sigset(SIGHUP,ill_sig);
X    sigset(SIGTRAP,ill_sig);
X    sigset(SIGIOT,ill_sig);
X    sigset(SIGEMT,ill_sig);
X    sigset(SIGFPE,ill_sig);
X    sigset(SIGBUS,ill_sig);
X    sigset(SIGSEGV,ill_sig);
X    sigset(SIGSYS,ill_sig);
X    sigset(SIGPIPE,ill_sig);
X#endif
X#ifdef	BSD42
X    signal(SIGQUIT,SIG_IGN);
X    signal(SIGALRM,SIG_IGN);
X    signal(SIGTERM,SIG_IGN);
X    signal(SIGTSTP,SIG_IGN);
X    signal(SIGTTIN,SIG_IGN);
X    signal(SIGTTOU,SIG_IGN);
X    signal(SIGINT,SIG_IGN);
X    signal(SIGHUP,ill_sig);
X    signal(SIGTRAP,ill_sig);
X    signal(SIGIOT,ill_sig);
X    signal(SIGEMT,ill_sig);
X    signal(SIGFPE,ill_sig);
X    signal(SIGBUS,ill_sig);
X    signal(SIGSEGV,ill_sig);
X    signal(SIGSYS,ill_sig);
X    signal(SIGPIPE,ill_sig);
X#endif
X#ifdef	SYS3
X    signal(SIGINT,SIG_IGN);
X    signal(SIGQUIT,SIG_IGN);
X    signal(SIGTERM,SIG_IGN);
X    signal(SIGALRM,SIG_IGN);
X    signal(SIGHUP,ill_sig);
X    signal(SIGTRAP,ill_sig);
X    signal(SIGIOT,ill_sig);
X    signal(SIGEMT,ill_sig);
X    signal(SIGFPE,ill_sig);
X    signal(SIGBUS,ill_sig);
X    signal(SIGSEGV,ill_sig);
X    signal(SIGSYS,ill_sig);
X    signal(SIGPIPE,ill_sig);
X#endif
X#ifdef	SYS5
X    signal(SIGINT,SIG_IGN);
X    signal(SIGQUIT,SIG_IGN);
X    signal(SIGTERM,SIG_IGN);
X    signal(SIGALRM,SIG_IGN);
X    signal(SIGHUP,ill_sig);
X    signal(SIGTRAP,ill_sig);
X    signal(SIGIOT,ill_sig);
X    signal(SIGEMT,ill_sig);
X    signal(SIGFPE,ill_sig);
X    signal(SIGBUS,ill_sig);
X    signal(SIGSEGV,ill_sig);
X    signal(SIGSYS,ill_sig);
X    signal(SIGPIPE,ill_sig);
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(screen)	    /* print a list of all characters */
Xbool	screen;
X{
Xstruct	stats	buf;
XFILE	*fp;
X
X    if (screen)
X	{
X	clear();
X	refresh();
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("",buf.name))
X		printf("%-20s   Login: %-9s  Level: %6d  Type: %3d\n",buf.name,buf.login,buf.lvl,buf.typ);
X	fclose(fp);
X	}
X    if (screen)
X	{
X	putchar('\n');
X	putchar('\n');
X	paws(22);
X	clear();
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(4,0,"The king is playing, so you cannot steal his throne\n");
X		    stat->x = stat->y = 9;
X		    move(6,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(4,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(6,0,"0:Decree  ");
X}
X
Xvoid	paws(where)		/* wait for input to continue */
Xint where;
X{
X    mvaddstr(where,0,"-- more --");
X    getans(" ", FALSE);
X}
X
Xvoid	cstat() 		/* examine/change stats of a character */
X{
Xstruct	stats charac;
Xchar	s[60], flag[2];
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    trunc(s);
X    if ((loc = findname(s, &charac)) < 0)
X	{
X	mvaddstr(11,0,"Not found.");
X	exit1();
X	/*NOTREACHED*/
X	}
X
X    time(<emp);
X    today = localtime(<emp)->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",charac.quk);
X    if (charac.quk < 0)
X	printw("(%d)\n",charac.tampered);
X    else
X	addch('\n');
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:Mana         %.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    refresh();
X    c = getch();
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 mana */
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,"");
X	    initchar(&charac);
X	    goto LEAVE;
X	}
X    goto TOP;
XLEAVE:	charac.status = OFF;
X    update(&charac,loc);
X}
X
Xint 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);
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.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[6], 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    *bp = stat->sin;
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    stat->sin = *bp;
X}
!EOR!
echo extracting - phant.h
sed 's/^X//' > phant.h << '!EOR!'
X/*
X * phant.h  Include file for Phantasia
X */
X
X#include 
X#include 
X#include 
X#include 
X#include 
X#include 
X
X/* ring constants */
X#define NONE	0
X#define NAZBAD	1
X#define NAZREG	2
X#define DLREG	3
X#define DLBAD	4
X#define SPOILED 5
X
X/* some functions and pseudo-functions */
X#define toupper(CH) ((CH) > 96 ? (CH) ^ 32 : (CH))  /* may be upper or lower */
X#define tolower(CH) ((CH) | 32) 	/* must be upper */
X#define rnd()	    (((double) rand()) / ((double) (RAND)))
X#define roll(BASE,INTERVAL) floor((BASE) + (INTERVAL) * rnd())
X#define sgn(x)	((x) < 0 ? -1 : ((x) > 0 ? 1 :0))
X#define abs(x)	((x) < 0 ? -(x) : (x))
X#define circ(x,y)   floor(dist(x, 0.0, y, 0.0) /125 + 1)
X#define max(A,B)    ((A) > (B) ? (A) : (B))
X#define min(A,B)    ((A) < (B) ? (A) : (B))
X#define valarstuff(ARG) decree(ARG)
X#define illcmd()    mvaddstr(5,0,"Illegal command.\n")
X#define maxmove     (charac.lvl * 1.5 + 1)
X#define illmove()   mvaddstr(5,0,"Too far.\n")
X#define rndattack() if (rnd() < 0.2 && charac.status == PLAYING && !throne) \
X		fight(&charac,-1)
X#define strcalc(STR,SICK)   max(0,min(0.9 * STR, SICK * STR/20))
X#define spdcalc(LVL,GLD,GEM)	max(0,((GLD + GEM/2) - 1000)/200.0 - LVL)
X#define illspell()  mvaddstr(5,0,"Illegal spell.\n")
X#define nomana()    mvaddstr(5,0,"Not enough mana for that spell.\n")
X#define somebetter()	addstr("But you already have something better.\n")
X
X/* status constants */
X#define OFF 0
X#define PLAYING 1
X#define CLOAKED 2
X#define INBATTLE    3
X#define DIE 4
X#define QUIT	5
X
X/* tampered constants */
X#define NRGVOID 1
X#define GRAIL	2
X#define TRANSPORT   3
X#define GOLD	4
X#define CURSED	5
X#define MONSTER 6
X#define BLESS	7
X#define MOVED	8
X#define HEAL	9
X#define VAPORIZED   10
X#define STOLEN	11
X
X/* structure definitions */
Xstruct	stats	    /* player stats */
X    {
X    char    name[21];	/* name */
X    char    pswd[9];	/* password */
X    char    login[10];	/* login */
X    double  x;	    /* x coord */
X    double  y;	    /* y coord */
X    double  exp;	/* experience */
X    int lvl;	    /* level */
X    short   quk;	/* quick */
X    double  str;	/* strength */
X    double  sin;	/* sin */
X    double  man;	/* mana */
X    double  gld;	/* gold */
X    double  nrg;	/* energy */
X    double  mxn;	/* max. energy */
X    double  mag;	/* magic level */
X    double  brn;	/* brains */
X    short   crn;	/* crowns */
X    struct
X	{
X	short	type;
X	short	duration;
X	}   rng;    /* ring stuff */
X    bool    pal;	/* palantir */
X    double  psn;	/* poison */
X    short   hw;     /* holy water */
X    short   amu;	/* amulets */
X    bool    bls;	/* blessing */
X    short   chm;	/* charms */
X    double  gem;	/* gems */
X    short   quks;	/* quicksilver */
X    double  swd;	/* sword */
X    double  shd;	/* shield */
X    short   typ;	/* character type */
X    bool    vrg;	/* virgin */
X    short   lastused;	/* day of year last used */
X    short   status;	/* playing, cloaked, etc. */
X    short   tampered;	/* decree'd, etc. flag */
X    double  scratch1, scratch2; /* var's for above */
X    bool    blind;	/* blindness */
X    int wormhole;   /* # of wormhole, 0 = none */
X    long    age;	/* age in seconds */
X    short   degen;	/* age/2500 last degenerated */
X    short   istat;	/* used for inter-terminal battle */
X    };
X
Xstruct	mstats	    /* monster stats */
X    {
X    char    name[26];	/* name */
X    double  str;	/* strength */
X    double  brn;	/* brains */
X    double  spd;	/* speed */
X    double  hit;	/* hits (energy) */
X    double  exp;	/* experience */
X    int trs;	    /* treasure type */
X    int typ;	    /* special type */
X    int flk;	    /* % flock */
X    };
X
Xstruct	nrgvoid     /* energy void */
X    {
X    bool    active;	/* active or not */
X    double  x,y;	/* coordinates */
X    };
X
X#ifndef SMALL
Xstruct	worm_hole   /* worm hole */
X    {
X    char    f, b, l, r; /* forward, back, left, right */
X    };
X#endif
X
Xstruct	sb_ent			/* scoreboard entry */
X    {
X    char    name[21];
X    char    login[10];
X    int     level;
X    short   type;
X    };
X
X/* files */
Xextern char monsterfile[],
X	    peoplefile[],
X	    gameprog[],
X	    messfile[],
X	    lastdead[],
X	    helpfile[],
X	    motd[],
X	    goldfile[],
X	    voidfile[],
X	    enemyfile[],
X	    sbfile[];
X
X/* library functions and system calls */
Xunsigned sleep();
Xlong	time(), ftell();
Xchar	*getlogin(), *getpass(), *ctime(), *strchr();
Xstruct	passwd	*getpwuid();
Xchar	*strcpy(), *strncpy();
X
X/* function and global variable declarations */
Xvoid	adjuststats(), callmonster(), checkinterm(), checkmov(), checktampered(),
X    cstat(), death(), decree(), error(), exit1(), fight(), genchar(), getstring(),
X    init1(), initchar(), interm(), kingstuff(), leave(), mesg(), movelvl(),
X    neatstuff(), paws(), printmonster(), printplayers(), printstats(), purge(),
X    scoreboard(), scramble(), showall(), show_sb(), showusers(), statread(),
X    tampered(), titlestuff(), trade(), treasure(), trunc(), update(), voidupdate();
Xint allocvoid(), findchar(), findname(),  findspace(), getans(), gch(), interrupt(),
X    ill_sig(), rngcalc(), level();
Xdouble	dist(), inflt();
Xchar	*printloc();
X#ifdef	OK_TO_PLAY
Xbool	ok_to_play();
X#endif
X
Xextern	jmp_buf fightenv, mainenv;
Xextern	double	strength, speed;
Xextern	bool	beyond, marsh, throne, valhala, changed, fghting, su, wmhl, timeout;
X#ifndef SMALL
Xextern	struct worm_hole    w_h[];
X#endif
Xextern	long	secs;
Xextern	int fileloc, users;
!EOR!