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