nonh@utzoo.UUCP (Chris Robertson) (10/09/85)
: This is a shell archive. Remove everything up to this line, save the rest
# in a file and then type "/bin/sh file" to extract the following files:
# Makefile fight.c func1.c phant.h
if test -s "Makefile"
then
echo Will not overwrite existing 'Makefile'
else
sed -e "s/^X//" > Makefile << 'TiDDleYwiNKs'
X# Makefile for Phantasia 3.3.1 (modifed by Chris Robertson, Sept. 1985)
X#
X# NOTE: It is important to run 'setup' before trying to run 'phantasia'.
X# 'make install' does this for you.
X
XRM = -rm
XSHAR = shar
XSHARDEST = /tmp
X
XLIBS = -lm -lcurses -ltermcap
X
X# NOTE -- you MUST use separate i/d space on small machines (use '-i')
X
XCFLAGS = -i -O
X
X# FIGHT stuff is separate because fight.c ran the optimizer out of space on
X# at least one C compiler I encountered, so things are set up to allow
X# everything but fight.c to be optimized if necessary --Chris Robertson
X
XFIGHTFLAGS = -i
X
X# set PLOTDEVICE to "> /dev/whatever" as necessary -- for drawing map
X
XPLOTDEVICE = > /dev/tty72
X
X# DEST is where the program and its support files reside
X
XDEST = /usr/games/lib/phant
X
X# BIN is where the accessible-to-everyone binary will live
X
XBIN = /usr/games
X
X# The following are program constants which are implementation dependent.
X#
X# PATH is the same as $DEST. Note that there is no closing quote here.
X# WIZARD is the login of the one who will clean up things.
X# UID is the uid of game wizard.
X# ACCESS is fopen() access to open a file for writing, without
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 barred from playing. The list of logins goes in the file 'enemy'.
X# define SHELL to enable shell escapes (might not want then if games are played
X# in a restricted environment)
X# define NOVOID if your compiler does not support the "void" type (urk!)
X# define BSD41 for 4.1bsd
X# define BSD42 for 4.2bsd -- also for V7 since they are very similar, but you
X# will need to comment out the signal calls with SIGTSTP, SIGTTIN, and
X# SIGTTOU in func1.c, because V7 doesn't have them
X# define SYS3 for System III, or similar
X# define SYS5 for System V
X# define WORM to include wormholes; omit them to save a little space
X# define SMALL on systems with 16-bit address space
X# If you don't have 'strchr()', put '-Dstrchr=index' below.
X
XFLAGS = -DPATH=\"${DEST} -DWIZARD=\"dmc\" -DUID=12 -DWORM\
X-DACCESS=\"a\" -DENEMY -DBSD42 -DSHELL -DNOVOID -DSMALL
X
XOFILES = main.o func0.o func1.o func2.o func3.o
XCFILES = main.c func0.c func1.c func2.c func3.c
X
X# NOTE -- you MUST use separate i/d space on small machines
X
Xphantasia: ${OFILES} fight.o pathdefs.o Makefile
X cc ${CFLAGS} ${OFILES} fight.o pathdefs.o ${LIBS} -o ${BIN}/phant
X size ${BIN}/phant
X chmod 4711 ${BIN}/phant
X
Xall: phantasia setup phant.help
X
Xsetup: phant.h pathdefs.o Makefile
X cc ${CFLAGS} ${FLAGS} setup.c -o setup pathdefs.o -lm
X
Xconvert:
X cc ${CFLAGS} ${FLAGS} convert.c -o ${DEST}/convert
X cp ${DEST}/characs ${DEST}/characs.orig
X cd ${DEST};./convert;mv newcharacs characs
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
X# Note: if your 'make' uses the cshell be sure to use >! not >
X
Xphant.help: phant.nr
X tbl -TX phant.nr | nroff -Ttn300 -man > phant.help
X
X# The link to BIN/phant is done for convenience -- it's shorter to type --CMR
X
Xinstall: phantasia convert setup phant.help
X if test ! -f ${DEST}/characs; then cat /dev/null > ${DEST}/characs;fi
X if test ! -f ${DEST}/enemy; then cat /dev/null > ${DEST}/enemy;fi
X if test ! -f ${DEST}/gold; then cat /dev/null > ${DEST}/gold;fi
X if test ! -f ${DEST}/goldfile; then cat /dev/null > ${DEST}/goldfile;fi
X if test ! -f ${DEST}/lastdead; then cat /dev/null > ${DEST}/lastdead;fi
X if test ! -f ${DEST}/mess; then cat /dev/null > ${DEST}/mess;fi
X if test ! -f ${DEST}/scoreboard; then cat /dev/null > ${DEST}/scoreboard;fi
X if test ! -f ${DEST}/void; then cat /dev/null > ${DEST}/void;fi
X setup
X cp monsters phant.help ${DEST}
X chmod 4711 ${BIN}/phant
X ${RM} -f ${DEST}/phant
X ln ${BIN}/phant phantasia
X
Xclean:
X ${RM} -f *.o phant.help phant.pt?
X
X# Note: if your 'make' uses the cshell be sure to use >! not >
X
Xshar:
X ${SHAR} README phant.nr func0.c > phant.pt1
X ${SHAR} Makefile* fight.c func1.c phant.h > phant.pt2
X ${SHAR} func2.c func3.c main.c monsters pathdefs.c setup.c > phant.pt3
X ${SHAR} map.c convert.c > phant.pt4
X
Xmap: map.o
X cc -n map.o -lplot -o map
X map | plot ${PLOTDEVICE}
X
Xmain.o: phant.h main.c
X cc -c ${CFLAGS} ${FLAGS} main.c
X
Xfight.o: phant.h fight.c
X cc -c ${FIGHTFLAGS} ${FLAGS} fight.c
X
Xfunc0.o: phant.h func0.c
X cc -c ${CFLAGS} ${FLAGS} func0.c
X
Xfunc1.o: phant.h func1.c
X cc -c ${CFLAGS} ${FLAGS} func1.c
X
Xfunc2.o: phant.h func2.c
X cc -c ${CFLAGS} ${FLAGS} func2.c
X
Xfunc3.o: phant.h func3.c
X cc -c ${CFLAGS} ${FLAGS} func3.c
X
Xpathdefs.o: phant.h pathdefs.c
X cc -c ${CFLAGS} ${FLAGS} pathdefs.c
X
X
TiDDleYwiNKs
size="`wc -c Makefile`"
size=`set - $size;echo $1`
echo "x - Makefile, $size characters"
if test "$size" != "4794"
then
echo "Warning: error in transmitting 'Makefile'; should have 4794 characters."
fi
fi
if test -s "fight.c"
then
echo Will not overwrite existing 'fight.c'
else
sed -e "s/^X//" > fight.c << 'TiDDleYwiNKs'
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{
X
X bool checkhit = TRUE, fghttofin = FALSE, luckout = FALSE,
X firsthit = stat->bls;
X char aline[80];
X double monhit, mdamage, sdamage, monspd, maxspd, inflict, monstr, temp,
X shield;
X int ch, whichm, size, howmany, lines;
X struct mstats monster;
X
X fghting = changed = TRUE;
X
X stat->status = INBATTLE;
X update(stat,fileloc);
X
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.mname,"a monster");
X if (monster.mtyp == 1) /* unicorn */
X if (stat->vrg)
X {
X printw("You just subdued %s, thanks to the virgin.\n",
X monster.mname);
X stat->vrg = FALSE;
X if (stat->sin > 1)
X stat->sin -= 1;
X if (stat->psn > 1)
X stat->psn -= 1;
X goto FINISH;
X }
X else
X {
X printw("You just saw %s running away!\n",monster.mname);
X goto LEAVE;
X }
X if (monster.mtyp == 2 && stat->typ > 20)
X {
X strcpy(monster.mname,"Morgoth");
X monster.mstr = rnd()*(stat->mxn + stat->shd)/1.4 + rnd()*(stat->mxn + stat->shd)/1.5;
X monster.mbrn = stat->brn;
X monster.mhit = stat->str*30;
X monster.mtyp = 23;
X monster.mspd = speed*1.1 + speed*(stat->typ == 90);
X monster.mflk = monster.mtrs = monster.mexp = 0;
X mvprintw(4,0,"You've encountered %s, Bane of the Council and Valar.\n",monster.mname);
X }
X fghttofin = luckout = FALSE;
X monstr = monster.mstr;
X monhit = monster.mhit;
X mdamage = sdamage = 0;
X monspd = maxspd = monster.mspd;
X if (speed <= 0)
X {
X monster.mspd += - speed;
X speed = 1;
X }
X move(8,0);
X clrtobot();
X
XTOP: mvprintw(6,0,"You are being attacked by %s, Exp: %.0f (Size: %d)\n",
X monster.mname,monster.mexp,size);
X printstats(stat);
X mesg();
X#ifdef SHELL
X ch='x'; /* set to garbage char to fix up shell escapes */
X#endif
X mvprintw(1,26,"%9.0f",stat->energy + shield);
X if (monster.mtyp == 4 && stat->bls && stat->chm)
X {
X mvprintw(7,0,"You just overpowered %s!",monster.mname);
X lines = 8;
X stat->bls = FALSE;
X --stat->chm;
X goto FINISH;
X }
X monster.mspd = min(monster.mspd + 1,maxspd);
X if (rnd()*monster.mspd > rnd()*speed && monster.mtyp != 4 &&
X monster.mtyp != 16 && !firsthit && checkhit)
X {
X if (monster.mtyp)
X switch (monster.mtyp) /* 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!",
X monster.mname,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 to gold!",
X monster.mname);
X stat->gld += stat->gem;
X stat->gem = 0.0;
X }
X else
X {
X mvprintw(lines++,0,"%s scrambled your stats!",
X monster.mname);
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.mname);
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.mstr);
X inflict = min(stat->exp,inflict);
X mvprintw(lines++,0,"%s took away %.0f experience points.",
X monster.mname,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!",
X monster.mname,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 relinquish 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!",
X monster.mname);
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.mname);
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.",
X monster.mname);
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!",
X monster.mname);
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!",
X monster.mname);
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.",
X monster.mname);
X stat->energy /= 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, ",
X monster.mname);
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->energy);
X mvprintw(lines++,0,"%s sapped %.0f of your energy.",
X monster.mname,inflict);
X stat->energy -= 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!",
X monster.mname);
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 quick.",
X monster.mname);
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.mname);
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.!",
X monster.mname);
X monster.mhit += floor((monhit*size - monster.mhit)/2);
X monster.mstr = 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.mname);
X stat->blind = TRUE;
X break;
X default:
X goto NORMALHIT;
X }
X else
XNORMALHIT:
X {
X inflict = rnd()*monster.mstr + 0.5;
X mvprintw(lines++,0,"%s hit you %.0f times!",monster.mname,inflict);
XSPECIALHIT: if ((shield -= inflict) < 0)
X {
X stat->energy += shield;
X shield = 0;
X }
X }
X }
X else 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.mtyp == 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();
XGET: ch = gch(stat->rng.type);
X if (stat->lvl > 5) /* will re-set after a ^S */
X timeout = TRUE;
X firsthit = FALSE;
X checkhit = TRUE;
X move(8,0);
X clrtobot();
X lines = 9;
X mvaddstr(4,0,"\n\n");
X switch (ch)
X {
X case '\020': /* ^P -- suspend the game temporarily */
X if (timeout)
X timeout = FALSE;
X goto GET;
X /*NOTREACHED*/
X case 'T': /* timeout; lose turn */
X break;
X case ' ':
X case '1': /* melee */
XMELEE: inflict = roll(strength/2 + 5,1.3*strength) +
X (stat->rng.type < 0 ? strength : 0);
X mdamage += inflict;
X monster.mstr = monstr - mdamage/monhit*monstr/4;
X goto HITMONSTER;
X case '2': /* skirmish */
X inflict = roll(strength/3 + 3,1.1*strength) +
X (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.mtyp == 4 || monster.mtyp == 16
X || rnd()*speed*stat->brn > rnd()*monster.mspd*monster.mbrn)
X && (monster.mtyp != 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.mname);
X break;
X case 'M': /* spell */
X case '4':
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.mtyp == 23 && ch != '3')
X illspell();
X else
X switch (ch)
X {
X case '1': /* all or nothing */
X inflict = (rnd() < 0.25) ? (monster.mhit*1.0001 + 1) : 0;
X if (monster.mtyp == 4)
X inflict *= .9;
X if (stat->man)
X --stat->man;
X maxspd *= 2;
X monspd *= 2;
X monster.mspd = max(1,monster.mspd * 2);
X monstr = monster.mstr *= 2;
X goto HITMONSTER;
X break;
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 } 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.mtyp == 4)
X inflict = 0.0;
X goto HITMONSTER;
X }
X break;
X case '5': /* increase might */
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 case '3': /* force field */
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 case '4': /* transform */
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 case '6': /* invisible */
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 quick : %.0f\n",speed);
X }
X break;
X case '7': /* transport */
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.mexp/200*rnd())
X {
X mvaddstr(5,0,"Transport backfired!\n");
X stat->x += (250*size*rnd() +
X 50*size)*sgn(stat->x);
X stat->y += (250*size*rnd() +
X 50*size)*sgn(stat->y);
X goto LEAVE;
X }
X else
X {
X mvprintw(5,0,"%s is transported.\n",
X monster.mname);
X if (rnd() < 0.3)
X monster.mtrs = 0;
X goto FINISH;
X }
X }
X break;
X case '8': /* paralyze */
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.mexp/1000*rnd())
X {
X mvprintw(5,0,"%s is held.\n",monster.mname);
X monster.mspd = -2;
X }
X else
X mvaddstr(5,0,"Monster unaffected.\n");
X }
X break;
X case '9': /* specify */
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 break;
X case '5':
X inflict = 1 + stat->swd;
X stat->exp += floor(monster.mexp/10);
X monster.mexp *= 0.92;
X maxspd += 2;
X monster.mspd = (monster.mspd < 0) ? 0 : monster.mspd + 2;
X if (monster.mtyp == 4)
X {
X mvprintw(lines++,0,"You hit %s %.0f times, and made him mad!",monster.mname,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 'B': /* luckout */
X case '6':
X if (luckout)
X mvaddstr(lines++,0,"You already tried that.");
X else
X if (monster.mtyp == 23)
X if (rnd() < stat->sin/100)
X {
X mvprintw(lines++,0,"%s accepted!",monster.mname);
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.mbrn)
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#ifdef SHELL
X case '!': /* shell escape */
X shellcmd();
X /* FALLTHROUGH */
X#endif
X default:
X checkhit = FALSE; /* only SPACE and digits work for fighting */
X goto TOP;
X }
X goto BOT;
XHITMONSTER: {
X inflict = floor(inflict);
X mvprintw(lines++,0,"You hit %s %.0f times!",monster.mname,inflict);
X if ((monster.mhit -= inflict) >0)
X switch (monster.mtyp)
X {
X case 4: /* dark lord */
X inflict = stat->energy + shield +1;
X goto SPECIALHIT;
X case 16: /* shrieker */
X mvaddstr(lines++,0,"Shrieeek!! You scared it, and it called one of its friends.");
X more(lines);
X whichm = roll(70,30);
X goto CALL;
X }
X else
X {
X if (monster.mtyp == 23) /* morgoth */
X mvaddstr(lines++,0,"You have defeated Morgoth, but he may return...");
X else
X {
X mvprintw(lines++,0,"You killed it. Good work, %s.",stat->name);
X if (monster.mtyp == 3 && (strcmp(monster.mname,"Mimic") != 0))
X mvaddstr(lines++,0,"The body slowly changes shape -- it must have been a Mimic!");
X }
X goto FINISH;
X }
X }
XBOT: refresh();
X if (lines > LINES - 2)
X {
X more(lines);
X move(lines = 8,0);
X clrtobot();
X }
X if (stat->energy <= 0)
X {
X more(lines);
X death(stat, monster.mname);
X goto LEAVE;
X }
X goto TOP;
XFINISH: stat->exp += monster.mexp;
X if (rnd() < monster.mflk/100.0) /* flock monster */
X {
X more(lines);
X fghttofin = FALSE;
X ++howmany;
X goto CALL;
X }
X else if (size > 1 && monster.mtrs && rnd() > 0.2 +
X pow(0.4,(double) (howmany/3.0 + size/3.0)))
X { /* this takes # of flocks and size into account */
X more(lines);
X treasure(stat,monster.mtrs,size);
X }
X else
XLEAVE: more(lines);
X stat->rng.type = abs(stat->rng.type);
X move(4,0);
X clrtobot();
X fghting = FALSE;
X stat->status = PLAYING;
X update(stat,fileloc);
X}
TiDDleYwiNKs
size="`wc -c fight.c`"
size=`set - $size;echo $1`
echo "x - fight.c, $size characters"
if test "$size" != "16937"
then
echo "Warning: error in transmitting 'fight.c'; should have 16937 characters."
fi
fi
if test -s "func1.c"
then
echo Will not overwrite existing 'func1.c'
else
sed -e "s/^X//" > func1.c << 'TiDDleYwiNKs'
X/*
X * func1.c Phantasia support routines
X */
X
X#include "phant.h"
X
Xint
Xfindname(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{
X struct stats sbuf;
X int loc = 0;
X
X if (stat == NULL)
X stat = &sbuf;
X fseek(read_pfile,0L,0);
X while (fread((char *) stat,sizeof(sbuf),1,read_pfile))
X if (!strcmp(stat->name,name))
X return (loc);
X else
X ++loc;
X return (-1);
X}
X
X/****************************************************************/
X
Xint
Xfindspace() /* allocate space for a character in peoplefile */
X{
X struct stats buf;
X reg int loc;
X
X loc = 0;
X fseek(read_pfile,0L,0);
X while (fread((char *) &buf,sizeof(buf),1,read_pfile))
X {
X if (!strcmp(buf.name,"<null>"))
X return (loc);
X else
X ++loc;
X }
X fseek(access_pfile,(long) (loc * sizeof(buf)),0);
X initchar(&buf);
X strcpy(buf.name,"inuse");
X fwrite((char *) &buf,sizeof(buf),1,access_pfile);
X fflush(access_pfile);
X return (loc);
X}
X
X/****************************************************************/
X
Xint
Xfindchar(stat) /* retrieve a character from file */
X
Xreg struct stats *stat;
X{
X reg int loc = 0, loop;
X char name[21];
X
X clear();
X mvprintw(10,0,"Enter 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
X/****************************************************************/
X
Xvoid
Xleave(stat) /* save character in file */
X
Xreg struct stats *stat;
X{
X long ltemp;
X
X if (!stat->lvl)
X strcpy(stat->name,"<null>");
X stat->status = OFF;
X time(<emp);
X stat->age += ltemp - secs;
X update(stat,fileloc);
X exit1();
X /*NOTREACHED*/
X}
X
X/****************************************************************/
X
Xvoid
Xdeath(stat, how) /* remove a player after dying */
X
Xreg struct stats *stat;
Xchar *how;
X{
X FILE *fp;
X char aline[100];
X int ch;
X reg int loop;
X long ltemp;
X float temp;
X float allowed_gold;
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 more(3);
X stat->energy = 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 more(3);
X stat->brn = stat->lvl /25;
X stat->energy = stat->mxn;
X stat->quks = stat->swd = 0;
X stat->typ = 90;
X return;
X }
X
X if (stat->lvl > 9999)
X {
X addstr("Characters greater than level 10K must be retired. Sorry.");
X how = "Old age";
X }
X
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->energy = 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 fseek(mfile,0L,0);
X for (loop = 0; loop <= 13; ++loop)
X fgets(aline,100,mfile);
X ltemp = ftell(mfile);
X fp = fopen(monsterfile,ACCESS);
X fseek(fp,ltemp,0);
X fprintf(fp,"%-20s",stat->name);
X fclose(fp);
X }
X clear();
X move(4,0);
X switch ((int) roll(1,5))
X {
X case 1:
X addstr("Aaackk! You're dead! ");
X break;
X case 2:
X addstr("You have been disemboweled. ");
X break;
X case 3:
X addstr("You've been mashed, mauled, and spat 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 refresh();
X
X /* max 3 chances to live again if good */
X
X if (stat->lvl >= 10 && stat->sin < 1.0 && stat->lives < 3)
X {
X sleep(3);
X timeout = FALSE;
X clear();
X mvaddstr(6,0,"Your soul floats in vast, misty space, lit by shafts of pale sunlight.");
X mvaddstr(8,0,"Time passes slowly. You cannot distinguish seconds from days.");
X refresh();
X sleep(4);
X mvaddstr(10,0,"...suddenly, a Valkyrie in full armor appears before you!");
X mvprintw(12,0,"\"Greetings, %s\", she says, in a clear, ringing voice.",stat->name);
X mvaddstr(13,0,"\"Since your sins are few, you will have a chance to live once more!\"");
X more(15);
X move(15,0);
X clrtoeol();
X if (stat->vrg == TRUE)
X {
X mvaddstr(15,0,"\"But I must have a soul to take with me\", she continues. \"Shall I take the soul");
X mvaddstr(16,0,"of the innocent virgin who accompanies you instead of your own?\" ");
X ch = getans("NY", FALSE);
X if (ch == 'Y')
X {
X mvaddstr(18,0,"The Valkyrie frowns. \"Valhalla has no place for those who sacrifice the");
X mvaddstr(19,0,"innocent to save themselves!\", she says sternly. \"You are dammned.\"");
X refresh();
X more(20);
X clear();
X }
X else
X {
X mvaddstr(18,0,"\"Your sacrifice has won you your soul!\", she cries. \"Live and prosper.\"");
X refresh();
X more(20);
X clear();
X stat->energy = stat->mxn;
X stat->lives++;
X return;
X }
X }
X else
X {
X mvaddstr(16,0,"\"You must live a godly life and give generously to the poor\", she warns.");
X refresh();
X more(18);
X stat->energy = stat->mxn;
X stat->lives++;
X clear();
X mvaddstr(8,0,"You blink, and open your eyes on the real world again.");
X mvaddstr(10,0,"As you stand dazed, you realize a holy friar is approaching you.");
X mvprintw(11,0,"\"Will you help the needy, %s?\" he asks, holding out",stat->name);
X mvaddstr(12,0,"a large wooden box with a slot in the top.");
X mvprintw(14,0,"You have %-9.0f gold pieces.",stat->gld);
X mvaddstr(16,0,"How much gold will you give him? ");
X temp = inflt();
X loop = 0;
X allowed_gold = stat->gld/10;
X while (loop < 4)
X {
X loop++;
X stat->gld = max(0,stat->gld - floor(temp));
X if (stat->gld > allowed_gold)
X {
X move(16,0);
X clrtoeol();
X mvprintw(14,0,"You have %-9.0f gold pieces.",stat->gld);
X mvaddstr(17,0,"The ghostly form of the Valkyrie appears, ready to take your soul away!");
X mvaddstr(18,0,"Hastily, you give the friar some more gold: ");
X temp = inflt();
X move(17,0);
X clrtoeol();
X move(18,0);
X clrtoeol();
X refresh();
X sleep(1);
X }
X else
X {
X if (stat->gem > 0.5)
X {
X move(16,0);
X clrtoeol();
X move(17,0);
X clrtoeol();
X move(18,0);
X clrtoeol();
X mvaddstr(15,0,"He still looks expectant. You give him your gems as well.");
X stat->gem = 0;
X }
X move(16,0);
X clrtoeol();
X mvaddstr(16,0,"The Valkyrie fades away...");
X refresh();
X more(18);
X clear();
X stat->energy = stat->mxn;
X stat->lives++;
X return;
X }
X }
X mvaddstr(17,0,"The Valkyrie solidifies. \"Greed is a deadly sin,\" she says, and pulls your");
X mvaddstr(18,0,"soul from your body...");
X more(19);
X clear();
X }
X }
X scoreboard(stat);
X fp = fopen(lastdead,"w");
X if (*how == 'A')
X *how = tolower(*how);
X fprintf(fp,"%s (%s, run by %s, level %d, killed by %s)", stat->name,
X ptype('l',stat->typ),stat->login,stat->lvl,how);
X fclose(fp);
X fp = fopen(messfile,"w");
X fprintf(fp,"%s was killed by %s.", stat->name,how);
X fclose(fp);
X strcpy(stat->name,"<null>");
X update(stat,fileloc);
X mvaddstr(18,0,"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
X/****************************************************************/
X
Xvoid
Xupdate(stat,place) /* update charac file */
X
Xreg struct stats *stat;
Xreg int place;
X{
X fseek(access_pfile,(long) (place*sizeof(*stat)),0);
X fwrite((char *) stat,sizeof(*stat),1,access_pfile);
X fflush(access_pfile);
X}
X
X/****************************************************************/
X
Xvoid
Xprintplayers(stat) /* show users */
X
Xreg struct stats *stat;
X{
X struct stats buf;
X reg int loop = 0;
X double mloc;
X long ltmp;
X int 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 Status\n\n");
X fseek(read_pfile,0L,0);
X while (fread((char *) &buf,sizeof(buf),1,read_pfile))
X {
X if (strcmp(buf.name, "<null>") == 0)
X continue;
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 {
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 ",
X buf.name,ch,ch,buf.lvl);
X else
X printw("%-20s %8.0f %8.0f %6u ",
X buf.name,buf.x,buf.y,buf.lvl);
X }
X else
X printw("%-20s %24.24s %6u ",
X buf.name,printloc('s',buf.x,buf.y),buf.lvl);
X }
X else if (buf.typ == 99)
X --loop;
X else
X printw("%-20s %24.24s %6u ",
X buf.name,printloc('s',buf.x,buf.y),buf.lvl);
X printw (ptype('s', buf.typ));
X printw (" %-8.8s ", buf.login);
X switch (buf.status)
X {
X case PLAYING:
X printw("In Game\n");
X break;
X case INBATTLE:
X printw("In Battle\n");
X break;
X case OFF:
X printw("Off\n");
X break;
X default:
X printw("\n");
X break;
X }
X ++loop;
X }
X time(<mp);
X printw("\nTotal users = %d %s\n",loop,ctime(<mp));
X refresh();
X}
X
X/****************************************************************/
X
Xvoid
Xtitlestuff() /* print out a header */
X{
X FILE *fp;
X bool cowfound = FALSE, kingfound = FALSE;
X struct stats buf;
X double hiexp, nxtexp;
X int hilvl, nxtlvl;
X reg int loop;
X char instr[120], hiname[21], nxtname[21];
X
X mvaddstr(0,14,"W e l c o m e t o P h a n t a s i a (vers. 3.3.1+)!");
X mvaddstr(1,20,"Modifed by Chris Robertson, September 1985");
X if ((fp = fopen(motd,"r")) != NULL && fgets(instr,80,fp))
X {
X mvaddstr(3,40 - strlen(instr)/2,instr);
X fclose(fp);
X }
X fseek(read_pfile,0L,0);
X while (fread((char *) &buf,sizeof(buf),1,read_pfile))
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(5,40 - strlen(instr)/2,instr);
X kingfound = TRUE;
X break;
X }
X if (!kingfound)
X mvaddstr(5,24,"There is no ruler at this time.");
X fseek(read_pfile,0L,0);
X while (fread((char *) &buf,sizeof(buf),1,read_pfile))
X if (buf.typ == 99)
X {
X sprintf(instr,"The Valar is %s Login: %s",buf.name,buf.login);
X mvaddstr(7,40 - strlen(instr)/2,instr);
X break;
X }
X fseek(read_pfile,0L,0);
X while (fread((char *) &buf,sizeof(buf),1,read_pfile))
X if (buf.typ > 20 && buf.typ < 90)
X {
X if (!cowfound)
X {
X mvaddstr(9,30,"Council of the Wise:");
X loop = 10;
X cowfound = TRUE;
X }
X
X /* This assumes a finite (<=5) number of C.O.W.: */
X
X sprintf(instr,"%s Login: %s",buf.name,buf.login);
X mvaddstr(loop++,40 - strlen(instr)/2,instr);
X }
X fseek(read_pfile,0L,0);
X nxtname[0] = hiname[0] = '\0';
X hiexp = 0.0;
X nxtlvl = hilvl = 0;
X while (fread((char *) &buf,sizeof(buf),1,read_pfile))
X if (buf.exp > hiexp && buf.typ < 20)
X {
X if (strcmp(buf.name, "<null>") == 0)
X continue;
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 if (*hiname)
X if (*nxtname)
X {
X mvaddstr(16,28,"Highest characters are:");
X sprintf(instr,"%s (level %d), and %s (level %d)",
X hiname,hilvl,nxtname,nxtlvl);
X }
X else
X {
X mvaddstr(16,28,"Highest character is:");
X sprintf(instr,"%s (level %d)", hiname,hilvl);
X }
X else
X strcpy(instr, "No current highest characters");
X mvaddstr(18,40 - strlen(instr)/2,instr);
X if ((fp = fopen(lastdead,"r")) != NULL)
X {
X if (fgets(instr,80,fp) != NULL && *instr)
X {
X mvaddstr(20,25,"The last character to die was:");
X mvaddstr(21,40 - strlen(instr)/2,instr);
X }
X fclose(fp);
X }
X refresh();
X}
X
X/****************************************************************/
X
Xvoid
Xprintmonster() /* do a monster list on the terminal */
X{
X FILE *fp;
X reg int count = 0;
X char instr[100];
X
X puts(" # Name Str Brains Quick Hits Exp Treas Type Flk%\n");
X fseek(mfile,0L,0);
X while (fgets(instr,100,mfile))
X printf("%2d %s",count++,instr);
X}
X
X/****************************************************************/
X
Xvoid
Xexit1() /* exit, but cleanup */
X{
X move(23,0);
X refresh();
X nocrmode();
X endwin();
X exit(0);
X /*NOTREACHED*/
X}
X
X/****************************************************************/
X
Xvoid
Xinit1() /* 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 sigset(SIGINT,exit1); /* allow interrupts in startup stuff */
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); commented out for V7; leave in for BSD
X signal(SIGTTIN,SIG_IGN);
X signal(SIGTTOU,SIG_IGN); */
X signal(SIGINT,exit1); /* allow interrupts in startup stuff */
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,exit1); /* allow interrupts in startup stuff */
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,exit1); /* allow interrupts in startup stuff */
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
X/****************************************************************/
X
Xvoid
Xgetstring(cp,mx) /* get a string from the stdscr at current y,x */
X
Xreg char *cp;
Xreg int mx;
X{
X reg int loop = 0, x, y, xorig;
X int 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#ifdef SHELL
X case '!' : /* shell escape at start of string, normal otherwise */
X if (! loop)
X {
X shellcmd();
X refresh();
X continue;
X }
X /* FALLTHROUGH */
X#endif
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/****************************************************************/
X
Xvoid
Xshellcmd() /* do a shell escape */
X{
X#ifdef SHELL
X char command[80];
X char *shell;
X
X clear();
X refresh();
X inshell = TRUE;
X alarm(0);
X echo();
X nocrmode();
X putchar('!');
X gets(command);
X if (*command)
X system(command);
X else
X {
X if((shell = getenv("SHELL")) == NULL)
X shell = "/bin/sh";
X printf("[Type ^D to exit shell]\n");
X system(shell);
X }
X printf("\n[Press RETURN twice to continue]");
X getch();
X crmode();
X noecho();
X inshell = FALSE;
X clear();
X#endif
X}
X
X/****************************************************************/
X
Xvoid
Xshowusers(screen) /* print a list of all characters */
X
Xbool screen;
X{
X struct stats buf;
X
X if (screen)
X {
X clear();
X refresh();
X }
X fseek(read_pfile,0L,0);
X {
X puts("Current characters on file are:\n");
X while (fread((char *) &buf,sizeof(buf),1,read_pfile))
X if (strcmp("<null>",buf.name))
X printf("%-20s Login: %-9s Level: %6d Type: %3s\n",
X buf.name,buf.login,buf.lvl,ptype('s',buf.typ));
X }
X if (screen)
X {
X putchar('\n');
X putchar('\n');
X more(22);
X clear();
X }
X}
X
X/****************************************************************/
X
Xvoid
Xkingstuff(stat) /* stuff upon entering throne */
X
Xreg struct stats *stat;
X{
X FILE *fp;
X struct stats buf;
X struct energyvoid vbuf;
X reg int loc = 0;
X
X if (stat->typ < 10) /* check to see if king -- assumes crown */
X {
X fseek(read_pfile,0L,0);
X while (fread((char *) &buf,sizeof(buf),1,read_pfile))
X {
X if (buf.typ > 10 && buf.typ < 20) /* found old king */
X {
X if (buf.x == 0.0 && buf.y == 0.0)
X {
X mvaddstr(4,0,"The king is on his throne, so you cannot steal it right now!");
X stat->x = stat->y = 9;
X move(6,0);
X return;
X }
X else 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 return;
X }
X else
X {
X buf.typ -= 10;
X if (buf.crn)
X --buf.crn;
X update(&buf,loc);
XKING: stat->typ = 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, %s!",stat->name);
X fclose(fp);
X
X /* clear all energy voids */
X
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 }
X else
X ++loc;
X }
X goto KING; /* old king not found -- install new one */
X }
XEXIT: mvaddstr(6,0,"0:Decree ");
X}
X
X/****************************************************************/
X
Xvoid
Xmore(where) /* wait for input to continue */
X
Xint where;
X{
X mvaddstr(where,0,"-- More --");
X getans(" \n", FALSE);
X}
X
X/****************************************************************/
X
Xvoid
Xcstat(stat) /* examine/change stats of a character */
X
Xreg struct stats *stat;
X{
X struct stats charac;
X char s[60], flag[2];
X reg int loc = 0;
X int c, temp;
X long today, ltemp;
X double dtemp;
X
X flag[0] = 'F', flag[1] = 'T';
X for (;;)
X {
X clear();
X if (stat != NULL)
X charac = *stat; /* copy in su's in-memory stats */
X else
X {
X addstr("Current characters on file are:\n");
X fseek(read_pfile,0L,0);
X while (fread((char *) &charac,sizeof(charac),1,read_pfile))
X if (strcmp("<null>",charac.name))
X printw("%-20s Login: %-9s\n",charac.name,charac.login);
X addstr("\n\nWhich character do you want to look at? ");
X refresh();
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
X time(<emp);
X today = localtime(<emp)->tm_yday;
X if (!su)
X strcpy(charac.pswd,"XXXXXXXX");
X clear();
X TOP: 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: Quicksilver %d\n",charac.quks);
X printw ("j: Energy %.0f\n",charac.energy);
X printw ("k: Max-Energy %.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 (%s)\n",charac.typ,
X ptype('l',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 %ld\n",charac.age);
X mvprintw (14,40,"S: Status %d\n",charac.status);
X mvprintw (18,3,"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],
X flag[charac.blind],flag[charac.pal]);
X if (!su)
X exit1();
X if (stat == NULL)
X {
X mvaddstr(16,40,"U: Update character");
X mvaddstr(16,62,"D: Delete");
X }
X mvprintw(19,3, "9: Lives: %d",charac.lives);
X mvaddstr(19,34,"8: Duration");
X if (stat == NULL)
X mvaddstr(21,0,"What would you like to change? (RUBOUT to quit) ");
X else
X mvaddstr(21,0,"What would you like to change? ('Q' to quit) ");
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,"Level = %d; Level = ",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,"Quickness = %d; Quickness= ",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,"Strength = %f; Strength = ",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,"Mana = %f; Mana = ",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,"Gold = %f; Gold = ",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,"Energy = %f; Energy = ",charac.energy);
X dtemp = inflt();
X if (dtemp != 0.0)
X charac.energy = dtemp;
X break;
X case 'k': /* change Maximum energy */
X mvprintw(23,0,"Max energy = %f; Max energy = ",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,"Magic level = %f; Magic level = ",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,"Brains = %f; Brains = ",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,"Crown = %d; Crown = ",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,"Ring type = %d; Ring 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,"Ring duration = %d; Ring duration = ",
X 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,"Palantir = %d; Palantir = ",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 '9': /* change lives */
X mvprintw(23,0,"Lives = %d; Lives = ",charac.lives);
X dtemp = inflt();
X if (dtemp >= 0.0)
X charac.lives = dtemp;
X break;
X case 'S': /* change status */
X mvprintw(23,0,"Status = %d; Status = ",charac.status);
X dtemp = inflt();
X if (dtemp >= 0.0)
X charac.status = dtemp;
X break;
X case 'u': /* change poison */
X mvprintw(23,0,"Posion = %f; Posion = ",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,"Holy Water = %d; Holy Water = ",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,"Amulet = %d; Amulet = ",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,"Blessing = %d; Blessing = ",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,"Charm = %d; Charm = ",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,"Quicksilver = %d; Quicksilver = ",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,"Sword = %f; Sword = ",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,"Shield = %f; Shield = ",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,"Type = %d; Type = ",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,"Virgin = %d; Virgin = ",charac.vrg);
X dtemp = inflt();
X if (dtemp > 0.0)
X charac.vrg = TRUE;
X else
X charac.vrg = FALSE;
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 'U': /* update buffer stats */
X if (stat == NULL)
X goto LEAVE;
X case 'D': /* delete char */
X strcpy(charac.name,"<null>");
X initchar(&charac);
X goto LEAVE;
X case 'Q': /* return to play for su altering own stats */
X *stat = charac;
X clear();
X return;
X }
X goto TOP;
XLEAVE: charac.status = OFF;
X update(&charac,loc);
X }
X}
X
X/****************************************************************/
X
Xint
Xlevel(expr) /* calculate level */
X
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
X/****************************************************************/
X
Xvoid
Xtrunc(str) /* remove blank spaces at the end of str[] */
X
Xreg char *str;
X{
X reg int loop;
X
X loop = strlen(str);
X while (str[--loop] == ' ')
X str[loop] = '\0';
X}
X
X/****************************************************************/
X
Xdouble
Xinflt() /* get a floating point # from the terminal */
X{
X char aline[80];
X double res;
X
X getstring(aline,80);
X if (sscanf(aline,"%F",&res) < 1)
X res = 0.0;
X return (res);
X}
X
X/****************************************************************/
X
Xvoid
Xcheckmov(stat) /* see if beyond PONR */
X
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}
X
X/****************************************************************/
X
Xvoid
Xscramble(stat) /* mix up some stats */
X
Xreg struct stats *stat;
X{
X double buf[6], temp1, temp2;
X reg int first, second;
X reg 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->energy;
X *bp = stat->sin;
X
X bp = buf;
X first = roll(0,5);
X second = roll(0,5);
X temp1 = bp[first];
X
X /* this expression is split to prevent a compiler loop on some compilers */
X
X temp2 = bp[second];
X bp[first] = temp2;
X bp[second] = temp1;
X
X stat->str = *bp++;
X stat->man = *bp++;
X stat->brn = *bp++;
X stat->mag = *bp++;
X stat->energy = *bp++;
X stat->sin = *bp;
X}
TiDDleYwiNKs
size="`wc -c func1.c`"
size=`set - $size;echo $1`
echo "x - func1.c, $size characters"
if test "$size" != "30525"
then
echo "Warning: error in transmitting 'func1.c'; should have 30525 characters."
fi
fi
if test -s "phant.h"
then
echo Will not overwrite existing 'phant.h'
else
sed -e "s/^X//" > phant.h << 'TiDDleYwiNKs'
X/*
X * phant.h Include file for Phantasia
X */
X
X#include <setjmp.h>
X#include <curses.h>
X#include <time.h>
X#include <pwd.h>
X#include <signal.h>
X#include <math.h>
X
X#ifdef NOVOID
X#define void int
X#endif
X
X/* ring constants */
X
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
X#define toupper(CH) ((CH) > 96 ? (CH) ^ 32 : (CH)) /* upper/lower */
X#define tolower(CH) ((CH) | 32) /* upper only */
X#ifndef SMALL
X#define rnd() ((rand () % 1000)/1000.0)
X#endif
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 maxmove (charac.lvl * 1.5 + 1)
X#ifndef SMALL
X#define illcmd() mvaddstr(5,0,"Illegal command.\n")
X#define illmove() mvaddstr(5,0,"Too far.\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#define illspell() mvaddstr(5,0,"Illegal spell.\n")
X#endif
X#define randattack() if ((float) rnd() < 0.2 && charac.status \
X == PLAYING && !throne) 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
X/* status constants */
X
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
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 */
X
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 energy; /* 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 short lives; /* # of times resurrected -- max 3 lives unless Valar */
X};
X
Xstruct mstats /* monster stats */
X{
X char mname[20]; /* name */
X double mstr; /* strength */
X double mbrn; /* brains */
X double mspd; /* speed */
X double mhit; /* hits (energy) */
X double mexp; /* experience */
X int mtrs; /* treasure type */
X int mtyp; /* special type */
X int mflk; /* % flock */
X};
X
Xstruct energyvoid /* energy void */
X{
X bool active; /* active or not */
X double v_x,v_y; /* coordinates */
X};
X
X#ifdef WORM
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 s_name[21];
X char s_login[10];
X int s_level;
X short s_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 */
X
Xunsigned sleep();
Xlong time(), ftell();
Xchar *getlogin(), *getpass(), *ctime(), *strchr();
Xstruct passwd *getpwuid();
Xchar *strcpy(), *strncpy();
X
X/* function and global variable declarations */
X
Xvoid adjuststats(), callmonster(), checkinterm(), checkmov(),
X checktampered(), cstat(), death(), decree(), error(), exit1(), fight(),
X genchar(), getstring(), init1(), initchar(), interm(), kingstuff(),
X leave(), mesg(), movelvl(), neatstuff(), more(), printmonster(),
X printplayers(), printstats(), purge(), shellcmd (), scoreboard(),
X scramble(), showall(), show_sb(), showusers(), statread(), tampered(),
X titlestuff(), trade(), treasure(), trunc(), update(), voidupdate();
X
Xint allocvoid(), findchar(), findname(), findspace(), getans(), gch(),
X interrupt(), ill_sig(), rngcalc(), level();
X
Xdouble dist(), inflt();
Xchar *printloc(), *ptype();
X
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,
X inshell, timeout;
X
X#ifdef WORM
Xextern struct worm_hole w_h[];
X#endif
X
Xextern long secs;
Xextern int fileloc, users;
Xextern FILE *read_pfile, *access_pfile; /* pointers to peoplefile */
Xextern FILE *mfile; /* pointer to monsterfile */
X
X#ifdef SMALL
Xdouble rnd();
Xvoid illcmd(), illmove(), nomana(), somebetter(), illspell();
X#endif
TiDDleYwiNKs
size="`wc -c phant.h`"
size=`set - $size;echo $1`
echo "x - phant.h, $size characters"
if test "$size" != "5883"
then
echo "Warning: error in transmitting 'phant.h'; should have 5883 characters."
fi
fi