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!