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: # func2.c func3.c main.c monsters pathdefs.c setup.c if test -s "func2.c" then echo Will not overwrite existing 'func2.c' else sed -e "s/^X//" > func2.c << 'TiDDleYwiNKs' X/* X * func2.c Phantasia support routines X */ X X#include "phant.h" X Xvoid Xdecree(stat) /* king and valar stuff */ X Xreg struct stats *stat; X{ X FILE *fp; X short arg; X char aline[80], *cp; X struct stats sbuf; X struct energyvoid vbuf; X double temp1 = 0.0, temp2 = 0.0; X int ch; X reg int loc; X X move(6,0); X clrtoeol(); X if (stat->typ < 20 && !su) /* king */ X { X addstr("0:Census 1:Transport 2:Curse 3:Energy Void 4:Bestow 5:Collect Taxes "); X ch = getans(" ", TRUE); X move(6,0); X clrtoeol(); X move(4,0); X switch (ch) X { X case '0': X showusers(TRUE); X return; X case '1': X arg = TRANSPORT; X cp = "transport"; X break; X case '2': X arg = CURSED; X cp = "curse"; X break; X case '3': X addstr("Enter the X Y coordinates of void: "); X getstring(aline,30); X sscanf(aline,"%F %F",&temp1,&temp2); X vbuf.v_x = floor(temp1); X vbuf.v_y = floor(temp2); X vbuf.active = TRUE; X if ((loc = allocvoid()) > 20) X mvaddstr(5,0,"Sorry, void creation limit reached.\n"); X else X voidupdate(&vbuf,loc); X goto EXIT; X case '4': X arg = GOLD; X addstr("Amount of gold to bestow: "); X temp1 = inflt(); X if (temp1 > stat->gld || temp1 < 0) X { X mvaddstr(5,0,"You don't have that !\n"); X return; X } X stat->gld -= floor(temp1); X cp = "give gold to"; X break; X case '5': X fp = fopen(goldfile,"r"); X fread((char *) &temp1,sizeof(double),1,fp); X fclose(fp); X mvprintw(4,0,"You have collected %.0f in gold.\n",temp1); X stat->gld += floor(temp1); X fp = fopen(goldfile,"w"); X temp1 = 0.0; X fwrite((char *) &temp1,sizeof(double),1,fp); X fclose(fp); X return; X default: X return; X } X } X else /* council of wise, valar, etc. */ X { X addstr("1:Heal "); X if (stat->pal || su) X addstr("2:Seek Grail "); X if (stat->typ == 99 || su) X addstr("3:Throw Monster 4:Relocate 5:Bless "); X if (su) X addstr("6:Vaporize "); X ch = getans(" ", TRUE); X if (!su && ch > '2' && stat->typ != 99) X { X illcmd(); X return; X } X switch (ch) X { X case '1': X arg = HEAL; X cp = "heal"; X break; X case '2': X if (stat->pal) X { X fp = fopen(voidfile,"r"); X fread((char *) &vbuf,sizeof(vbuf),1,fp); X fclose(fp); X temp1 = dist(stat->x, vbuf.v_x, stat->y, vbuf.v_y); X temp1 = floor(temp1 + roll(-temp1/10.0,temp1/5.0)); X mvprintw(5,0,"The palantir says the Grail is about %.0f away.\n",temp1); X return; X } X else X { X mvaddstr(5,0,"You need a palantir to seek the Grail.\n"); X return; X } X case '3': X mvaddstr(4,0,"Which monster [0-99]? "); X temp1 = inflt(); X temp1 = max(0,min(99,temp1)); X cp = "throw a monster at"; X arg = MONSTER; X break; X case '4': X mvaddstr(4,0,"New X Y coordinates: "); X getstring(aline,30); X sscanf(aline,"%F %F",&temp1,&temp2); X cp = "relocate"; X arg = MOVED; X break; X case '5': X arg = BLESS; X cp = "bless"; X break; X case '6': X if (su) X { X cp = "vaporize"; X arg = VAPORIZED; X break; X } X default: X return; X } X } X mvprintw(4,0,"Who do you want to %s? ",cp); X getstring(aline,21); X trunc(aline); X if (strcmp(stat->name,aline)) X { X if ((loc = findname(aline,&sbuf)) >= 0) X { X if (sbuf.tampered) X { X mvaddstr(5,0,"That person has something pending already.\n"); X return; X } X else X { X sbuf.tampered = arg; X sbuf.scratch1 = floor(temp1); X sbuf.scratch2 = floor(temp2); X update(&sbuf,loc); XEXIT: mvaddstr(5,0,"It is done.\n"); X return; X } X } X else X mvaddstr(5,0,"There is no one by that name.\n"); X } X else X mvaddstr(5,0,"You may not do it to yourself!\n"); X} X X/****************************************************************/ X Xvoid Xchecktampered(stat) /* see if decree'd etc. */ X Xreg struct stats *stat; X{ X struct energyvoid vbuf; X struct stats sbuf; X FILE *fp; X reg int loc = 0; X X /* first check for energy voids */ X X if ((fp = fopen(voidfile,"r")) == NULL) X { X error(voidfile); X /*NOTREACHED*/ X } X while (fread((char *) &vbuf,sizeof(vbuf),1,fp)) X if (vbuf.active && vbuf.v_x == stat->x && vbuf.v_y == stat->y) X { X fclose(fp); X if (loc) X { X vbuf.active = FALSE; X voidupdate(&vbuf,loc); X tampered(stat,NRGVOID,&sbuf); X } X else if (stat->status != CLOAKED) X tampered(stat,GRAIL,&sbuf); X break; X } X else X ++loc; X fclose(fp); X X /* now check for other things */ X X statread(&sbuf,fileloc); X if (sbuf.tampered) X tampered(stat,sbuf.tampered,&sbuf); X} X X/****************************************************************/ X Xvoid Xvoidupdate(vp,loc) /* update an energy void */ X Xreg struct energyvoid *vp; Xreg int loc; X{ X FILE *fp; X X fp = fopen(voidfile,ACCESS); X fseek(fp,(long) (loc*sizeof(*vp)),0); X fwrite((char *) vp,sizeof(*vp),1,fp); X fclose(fp); X} X X/****************************************************************/ X Xint Xallocvoid() /* find a space to put an energy void */ X{ X FILE *fp; X reg int loc = 0; X struct energyvoid vbuf; X X fp = fopen(voidfile,"r"); X while (fread((char *) &vbuf,sizeof(vbuf),1,fp)) X if (vbuf.active) X ++loc; X else X { X fclose(fp); X return (loc); X } X fclose(fp); X return (loc); X} X X/****************************************************************/ X Xvoid Xstatread(stat,loc) /* read a charac. structure */ X Xreg struct stats *stat; Xreg int loc; X{ X fseek(read_pfile,(long) (loc * sizeof(*stat)),0); X fread((char *) stat,sizeof(*stat),1,read_pfile); X} X X/****************************************************************/ X Xvoid Xtampered(stat,what,bufp) /* decree'd, intervened, etc. */ X Xreg struct stats *stat, *bufp; Xshort what; X{ X struct energyvoid vbuf; X reg int loc; X struct stats sbuf; X X changed = TRUE; X move(4,0); X stat->tampered = OFF; X switch ((int) what) X { X case NRGVOID: X addstr("You've hit an energy void !\n"); X stat->man /= 3; X stat->energy /= 2; X stat->gld = floor(stat->gld/1.25) + 0.1; X stat->x += roll(-12,25); X stat->y += roll(-12,25); X break; X case TRANSPORT: X addstr("The king transported you ! "); X if (stat->chm) X { X addstr("But your charm save you...\n"); X --stat->chm; X } X else X { X stat->x += roll(-50,100) * circ(stat->x,stat->y); X stat->y += roll(-50,100) * circ(stat->x,stat->y); X addch('\n'); X } X break; X case GOLD: X printw("The king has bestowed %.0f gold pieces on you !\n", X bufp->scratch1); X stat->gld += bufp->scratch1; X break; X case CURSED: X addstr("You've been cursed ! "); X if (stat->bls) X { X addstr("But your blessing saved you...\n"); X stat->bls = FALSE; X } X else X { X addch('\n'); X stat->psn += 2; X stat->energy = 10; X stat->mxn *= 0.95; X stat->status = PLAYING; X } X break; X case VAPORIZED: X addstr("Woops! You've been vaporized!\n"); X death(stat, "Vaporization"); X break; X case MONSTER: X addstr("The Valar zapped you with a monster!\n"); X more(7); X fight(stat,(int) bufp->scratch1); X return; X case BLESS: X addstr("The Valar has blessed you!\n"); X stat->energy = (stat->mxn *= 1.05) + stat->shd; X stat->man += 500; X stat->str += 0.5; X stat->brn += 0.5; X stat->mag += 0.5; X stat->psn = min(0.5,stat->psn); X break; X case MOVED: X addstr("You've been relocated...\n"); X stat->x = bufp->scratch1; X stat->y = bufp->scratch2; X break; X case HEAL: X addstr("You've been healed!\n"); X stat->psn -= 0.25; X stat->energy = stat->mxn + stat->shd; X break; X case STOLEN: X addstr("You've been bumped off as Valar!\n"); X stat->typ = 20 + roll(1,6); X break; X case GRAIL: X addstr("You have found The Holy Grail!!\n"); X if (stat->typ < 20) X { X addstr("However, you are not experienced enough to behold it.\n"); X stat->sin *= stat->sin; X stat->man += 1000; X } X else if (stat->typ == 99 || stat->typ == 90) X { X addstr("You have made it to the position of Valar once already.\n"); X addstr("The Grail is of no more use to you now.\n"); X } X else X { X addstr("It is now time to see if you are worthy to behold it...\n"); X refresh(); X sleep(4); X if (rnd() / 2.0 < stat->sin) X { X addstr("You blew this one!\n"); X stat->str = stat->man = stat->quk = stat->energy = stat->mxn X = stat->x = stat->y = stat->mag = stat->brn X = stat->exp = 1; X stat->lvl = 0; X } X else X { X addstr("You made to position of Valar!\n"); X stat->typ = 99; X fseek(read_pfile,0L,0); X loc = 0; X while (fread((char *) &sbuf,sizeof(sbuf),1,read_pfile)) X if (sbuf.typ == 99) X { X sbuf.tampered = STOLEN; X update(&sbuf,loc); X break; X } X else X ++loc; X } X default: X break; X } X vbuf.active = TRUE; X vbuf.v_x = roll(-1e6,2e6); X vbuf.v_y = roll(-1e6,2e6); X voidupdate(&vbuf,0); X break; X } X} X X/****************************************************************/ X Xvoid Xadjuststats(stat) /* make sure things are within limits, etc. */ X Xreg struct stats *stat; X{ X long ltemp; X reg int temp; X X stat->x = floor(stat->x); X stat->y = floor(stat->y); X valhala = (stat->typ == 99); X throne = (stat->x == 0.0 && stat->y == 0.0); X#ifdef WORM X temp = abs(stat->x)/400; X if (temp > 16) X temp = 0; X X /* wormholes are at y = 0 and x = -400, +800, -1200, +1600, ... */ X X if (stat->y == 0.0 && !throne && !valhala && temp <= 16 && X ((sgn(stat->x) == -1 && temp % 2 == 1) || X (sgn(stat->x) == 1 && temp % 2 == 0))) X { X if (!wmhl) X stat->wormhole = temp; X wmhl = TRUE; X } X else X wmhl = FALSE; X#endif X speed = stat->quk + stat->quks - spdcalc(stat->lvl,stat->gld,stat->gem); X strength = stat->str + stat->swd - strcalc(stat->str,stat->psn); X time(<emp); X stat->age += (ltemp - secs); X secs = ltemp; X stat->quks = min(99,stat->quks); X stat->man = min(stat->man,stat->lvl*15 + 5000); X stat->chm = min(stat->chm,stat->lvl + 10); X /* stat->typ = (stat->crn && stat->typ < 10)? -abs(stat->typ) : abs(stat->typ); */ X if (level(stat->exp) > stat->lvl) X { X movelvl(stat); X if (stat->lvl > 5) X timeout = TRUE; X } X stat->gld = floor(stat->gld) + 0.1; X stat->gem = floor(stat->gem) + 0.1; X if (stat->rng.type) X stat->energy = stat->mxn + stat->shd; X if (stat->rng.type && stat->rng.duration <= 0) /* clean up rings */ X switch (stat->rng.type) X { X case DLBAD: X case NAZBAD: X stat->rng.type = SPOILED; X stat->rng.duration = roll(10,25); X break; X case NAZREG: X stat->rng.type = NONE; X break; X case SPOILED: X death(stat, "A cursed ring"); X break; X } /* DLREG is ok, so do nothing with it */ X if (stat->age > stat->degen * 5000) X { X ++stat->degen; X if (stat->quk > 23) X --stat->quk; X stat->str *= 0.97; X stat->brn *= 0.95; X stat->mag *= 0.97; X stat->mxn *= 0.95; X if (stat->quks) X --stat->quks; X stat->swd *= 0.93; X stat->shd *= 0.95; X } X} X X/****************************************************************/ X Xvoid Xcheckinterm(stat) /* see if other person on same x,y */ X Xreg struct stats *stat; X{ X struct stats sbuf; X reg int foeloc = 0; X X users = 0; X fseek(read_pfile,0L,0); X while (fread((char *) &sbuf,sizeof(sbuf),1,read_pfile)) X { X if (sbuf.status && (sbuf.status != CLOAKED || sbuf.typ != 99)) X { X ++users; X if (stat->x == sbuf.x && stat->y == sbuf.y X && foeloc != fileloc && sbuf.typ != 99 X && stat->typ !=99 && !stat->wormhole && !sbuf.wormhole) X { X interm(stat,foeloc); X return; X } X } X ++foeloc; X } X} X X/****************************************************************/ X Xint Xgch(rngtyp) /* get a character from terminal, but check ring if crazy */ X Xshort rngtyp; X{ X refresh(); X if (abs(rngtyp) != SPOILED) X return (getans("T ", TRUE)); X else X { X getans(" ", TRUE); X return (roll(0,5) + '0'); X } X} X X/****************************************************************/ X Xint Xrngcalc(chartyp) /* pick a duration of a ring */ X Xshort chartyp; X{ X static int rngtab[] = { 0, 10, 20, 13, 25, 40, 20}; X X if (chartyp > 10) X chartyp -= 10; X return (rngtab[chartyp - 1]); X} X X/****************************************************************/ X Xvoid Xinterm(stat,who) /* interterminal battle routine */ X Xreg struct stats *stat; Xint who; X{ X#define MAXWAIT 20 X#define BLOCK sizeof(struct stats) X#define RAN 1 X#define STUCK 2 X#define BLEWIT 3 X#define KILLED 4 X#define readfoe() fseek(read_pfile,foeplace,0);fread((char *) foe,BLOCK,1,\ X read_pfile) X#define updateme() fseek(access_pfile,myplace,0);fwrite((char *) stat,BLOCK,\ X 1,access_pfile);fflush(access_pfile) X X double temp, foespeed, oldhits = 0.0, myhits; X struct stats sbuf; X reg struct stats *foe; X reg int loop, lines = 8; X int ch; X long myplace, foeplace; X short oldtags; X bool luckout = FALSE; X char foename[21]; X X fghting = TRUE; X mvaddstr(4,0,"Preparing for battle!\n"); X refresh(); X X /* set up variables, file, etc. */ X X myplace = fileloc * BLOCK; X foeplace = who * BLOCK; X fseek(read_pfile,0L,0); X setbuf(read_pfile, (char *) NULL); X stat->status = INBATTLE; X myhits = stat->energy; X X /* stats.tampered must be non-zero to stop a king or valar trashing it */ X X stat->tampered = oldtags = 1; X stat->scratch1 = 0.0; X stat->istat = 0; X updateme(); X foe = &sbuf; X readfoe(); X foespeed = foe->quk + foe->quks - spdcalc(foe->lvl,foe->gld,foe->gem); X if (abs(stat->lvl - foe->lvl) > 20) /* see if greatly mismatched */ X { X temp = ((double) (stat->lvl - foe->lvl))/((double) max(stat->lvl, X foe->lvl)); X if (temp > 0.5) /* this one outweighs his/her foe */ X foespeed *= 2.0; X else if (temp < -0.5) /* foe outweighs this one */ X speed *= 2.0; X } X if (stat->blind) X strcpy(foename,"someone"); X else X strcpy(foename,foe->name); X mvprintw(6,0,"You have encountered %s Level: %d\n",foename,foe->lvl); X refresh(); X X /* now wait for foe to respond */ X X for (loop = 1.5*MAXWAIT; foe->status != INBATTLE && loop; --loop) X { X readfoe(); X sleep(1); X } X if (foe->status != INBATTLE) X { X mvprintw(5,0,"%s is not responding.\n",foename); X goto LEAVE; X } X X /* otherwise, everything is set to go */ X X move(4,0); X clrtoeol(); X X /* check to see who goes first */ X X if (speed > foespeed) X goto HITFOE; X else if (foespeed > speed) X goto WAIT; X else if (stat->lvl > foe->lvl) X goto HITFOE; X else if (foe->lvl > stat->lvl) X goto WAIT; X else /* no one is faster */ X { X printw("You can't fight %s yet.",foename); X goto LEAVE; X } X X/* routine to hit, etc */ X XHITFOE: printstats(stat); X mesg(); X mvprintw(1,26,"%9.0f",myhits); X mvaddstr(7,0,"1:Fight 2:Run Away! 3:Power Blast "); X if (luckout) X clrtoeol(); X else X addstr("4:Luckout "); X ch = gch(stat->rng.type); X move(lines = 8,0); X clrtobot(); X switch (ch) X { X default: /* fight */ X temp = roll(2,strength); XHIT: mvprintw(lines++,0,"You hit %s %.0f times!",foename,temp); X stat->sin += 0.5; X stat->scratch1 += temp; X stat->istat = FALSE; X break; X case '2': /* run away */ X --stat->scratch1; /* this value changes to indicate action */ X if (rnd() > 0.25) X { X mvaddstr(lines++,0,"You got away!"); X stat->istat = RAN; X goto LEAVE; X } X mvprintw(lines++,0,"%s is still after you!",foename); X stat->istat = STUCK; X break; X case '3': /* power blast */ X temp = min(stat->man,stat->lvl*5); X stat->man -= temp; X temp = (rnd() + 0.5) * temp * stat->mag * 0.2 + 2; X mvprintw(lines++,0,"You blasted %s !",foename); X goto HIT; X case '4': /* luckout */ X if (luckout || rnd() > 0.1) X { X luckout = TRUE; X mvaddstr(lines++,0,"Not this time..."); X --stat->scratch1; X stat->istat = BLEWIT; X } X else X { X mvaddstr(lines++,0,"You just lucked out!"); X stat->scratch1 = foe->energy + 5; X } X break; X } X refresh(); X stat->scratch1 = floor(stat->scratch1); /* clean up any mess */ X if (stat->scratch1 > foe->energy) X stat->istat = KILLED; X else if (rnd() * speed < rnd() * foespeed) X { /* foe's turn */ X ++stat->tampered; X updateme(); X goto WAIT; X } X updateme(); X X if (stat->istat == KILLED) X { X mvprintw(lines++,0,"You killed %s!",foename); X stat->exp += foe->exp; X stat->crn += (stat->lvl < 1000)? foe->crn : 0; X stat->amu += foe->amu; X stat->chm += foe->chm; X stat->gld += foe->gld; X stat->gem += foe->gem; X stat->swd = max(stat->swd,foe->swd); X stat->shd = max(stat->shd,foe->shd); X stat->quks = max(stat->quks,foe->quks); X if (foe->vrg == TRUE) X { X mvaddstr(lines++,0,"You have rescued a virgin. Will you be honourable? "); X if ((ch = getans("YN",FALSE)) == 'Y') X stat->vrg = TRUE; X else X { X ++stat->sin; X stat->exp += 8000; X } X } X sleep(3); /* give other person time to die */ X goto LEAVE; X } X goto HITFOE; /* otherwise, my turn again */ X X/* routine to wait for foe to do something */ X XWAIT: printstats(stat); X mesg(); X mvprintw(1,26,"%9.0f",myhits); X mvaddstr(4,0,"Waiting...\n"); X refresh(); X for (loop = MAXWAIT; loop; --loop) X { X readfoe(); X if (foe->scratch1 != oldhits) X switch (foe->istat) X { X case RAN: X mvprintw(lines++,0,"%s ran away!",foename); X goto LEAVE; X case STUCK: X mvprintw(lines++,0,"%s tried to run away.",foename); X goto BOT; X case BLEWIT: X mvprintw(lines++,0,"%s tried to luckout!",foename); X goto BOT; X default: X temp = foe->scratch1 - oldhits; X mvprintw(lines++,0,"%s hit you %.0f times!",foename,temp); X myhits -= temp; X goto BOT; X } X sleep(1); X } X X /* timeout */ X X mvaddstr(22,0,"Timeout: waiting for response. Do you want to wait? "); X refresh(); X ch = getans("NY", FALSE); X move(22,0); X clrtobot(); X if (ch == 'Y') X goto WAIT; X goto LEAVE; X X/* routine to decide what happens next */ X XBOT: refresh(); X if (lines > 21) X { X more(lines); X move(lines = 8,0); X clrtobot(); X } X if (foe->istat == KILLED || myhits < 0.0) X { X updateme(); X death(stat,foename); X } X if (foe->istat == KILLED) X { X myhits = -2; X goto LEAVE; /* main will pick up death */ X } X oldhits = foe->scratch1; X if (foe->tampered != oldtags) X { X oldtags = foe->tampered; X goto HITFOE; X } X goto WAIT; X X/* routine to clean up things and leave */ X XLEAVE: updateme(); X stat->x += roll(5,-10); X stat->y += roll(5,-10); X stat->energy = myhits; X stat->tampered = OFF; X stat->status = PLAYING; X changed = TRUE; X more(lines); X move(4,0); X clrtobot(); X} X X/****************************************************************/ X Xint Xinterrupt() /* call when break key is hit */ X{ X char line[81]; X reg int loop; X int x, y, ch; X X#ifdef SYS3 X signal(SIGINT,SIG_IGN); X#endif X#ifdef SYS5 X signal(SIGINT,SIG_IGN); X#endif X getyx(stdscr,y,x); X for (loop = 79; loop >= 0; --loop) /* snarf line */ X { X move(4,loop); X line[loop] = inch(); X } X line[80] = '\0'; X clrtoeol(); X if (fghting) X { X move(4,0); X clrtoeol(); X addstr("Quitting now will automatically kill your character. Still want to? "); X ch = getans("NY", FALSE); X if (ch == 'Y') X longjmp(mainenv,DIE); X } X else X { X move(4,0); X clrtoeol(); X addstr("Do you really want to quit? "); X ch = getans("NY", FALSE); X if (ch == 'Y') X longjmp(mainenv,QUIT); X } X mvaddstr(4,0,line); /* return screen to previous state */ X move(y,x); X refresh(); X#ifdef SYS3 X signal(SIGINT,interrupt); X#endif X#ifdef SYS5 X signal(SIGINT,interrupt); X#endif X} X X/****************************************************************/ X Xvoid Xpurge() /* remove old players */ X{ X struct stats sbuf; X reg int loc, today, temp; X long ltime; X X loc = 0; X time(<ime); X today = localtime(<ime)->tm_yday; X fseek(read_pfile,0L,0); X while(fread((char *) &sbuf,sizeof(sbuf),1,read_pfile)) X { X temp = today - sbuf.lastused; X if (temp < 0) X temp += 365; X if (temp > 21) /* more than three weeks old --> delete */ X { X initchar(&sbuf); X strcpy(sbuf.name,"<null>"); X fseek(access_pfile,(long) (loc * sizeof(sbuf)),0); X fwrite((char *) &sbuf,sizeof(sbuf),1,access_pfile); X fflush(access_pfile); X } X ++loc; X } X} TiDDleYwiNKs size="`wc -c func2.c`" size=`set - $size;echo $1` echo "x - func2.c, $size characters" if test "$size" != "19688" then echo "Warning: error in transmitting 'func2.c'; should have 19688 characters." fi fi if test -s "func3.c" then echo Will not overwrite existing 'func3.c' else sed -e "s/^X//" > func3.c << 'TiDDleYwiNKs' X/* X * func3.c Phantasia support routines X */ X#include "phant.h" X Xjmp_buf btimeout; Xint catchalarm(); X Xint Xgetans(choices, def) /* get a one character option from keyboard */ X Xchar *choices; Xbool def; X{ X int ch, loop, oldx, oldy; X char *cptr; X char command[80]; X X getyx(stdscr, oldy, oldx); X alarm(0); X X for (loop = 9; loop; --loop) X if (setjmp(btimeout)) X if (def) X return(*choices); X else if (loop > 1) X goto YELL; X else X break; X else X { X clrtoeol(); X refresh(); X#ifdef BSD41 X sigset(SIGALRM, catchalarm); X#else X signal(SIGALRM, catchalarm); X#endif X if (!inshell) /* wait forever during a shell escape */ X if (timeout) X alarm(7); X else X alarm(600); X ch = getch(); X#ifdef SHELL X if (ch == '!') /* shell escape */ X { X shellcmd(); X refresh(); X getans(choices, def); X } X#endif X alarm(0); X if ((cptr = strchr(choices, toupper(ch))) != NULL) X return(*cptr); X else if (def) X return(toupper(ch)); X else if (!def && loop > 1) X { XYELL: mvprintw(oldy+1,0,"Please choose one of : [%s]\n", choices); X move(oldy, oldx); X clrtoeol(); X continue; X } X else X break; X } X return(*choices); X} X X/****************************************************************/ X Xint Xcatchalarm() X{ X longjmp(btimeout, 1); X} X X/****************************************************************/ X Xvoid Xerror(whichfile) X Xchar *whichfile; X{ X extern int errno; X X clear(); X printw("An unrecoverable error has occurred reading %s. (errno = %d)\n", X whichfile, errno); X addstr("Please run 'setup' to determine the problem.\n"); X exit1(); X /*NOTREACHED*/ X} X X/****************************************************************/ X Xvoid Xmesg() X{ X FILE *fp; X char s[100]; X X move(3,0); X clrtoeol(); X if ((fp = fopen(messfile, "r")) != NULL) X { X if (fgets(s,100,fp)) X addstr(s); X fclose(fp); X } X} X X/****************************************************************/ X Xdouble Xdist(x1, x2, y1, y2) X Xdouble x1, x2, y1, y2; X{ X double deltax, deltay; X X deltax = x1 - x2; X deltay = y1 - y2; X return(sqrt(deltax * deltax + deltay * deltay)); X} X X/****************************************************************/ X Xvoid Xscoreboard(stat) /* enter login into scoreboard */ X Xreg struct stats *stat; X{ X static struct sb_ent sbuf; X FILE *fp; X reg int loc = 0; X bool found = FALSE; X X if ((fp = fopen(sbfile, "r")) != NULL) X { X while (fread((char *) &sbuf, sizeof(sbuf), 1, fp)) X if (!strcmp(stat->login, sbuf.s_login)) X { X found = TRUE; X break; X } X else X ++loc; X fclose(fp); X } X X /* X * At this point, 'loc' will either indicate a point beyond X * the end of file, or the place where the previous entry X * was found. X */ X X if ((!found) || stat->lvl > sbuf.s_level) X { X strcpy(sbuf.s_login, stat->login); X strcpy(sbuf.s_name, stat->name); X sbuf.s_level = stat->lvl; X sbuf.s_type = stat->typ; X } X if ((fp = fopen(sbfile, ACCESS)) == NULL) X { X error(sbfile); X /*NOTREACHED*/ X } X fseek(fp, (long) (loc * sizeof(sbuf)), 0); X fwrite((char *) &sbuf, sizeof(sbuf), 1, fp); X fclose(fp); X} X X/****************************************************************/ X Xvoid Xshow_sb() /* printout the scoreboard */ X{ X static struct sb_ent sbuf; X FILE *fp; X X if ((fp = fopen(sbfile, "r")) != NULL) X while (fread((char *) &sbuf, sizeof(sbuf), 1, fp)) X printf("%-20s Login: %-9s Level: %6d Type: %3s\n", X sbuf.s_name, sbuf.s_login, sbuf.s_level, ptype('s',sbuf.s_type)); X} X X/****************************************************************/ X Xint Xill_sig(whichsig) /* come here on bad signals */ X Xint whichsig; X{ X clear(); X printw("Error: caught signal # %d.\n", whichsig); X exit1(); X /*NOTREACHED*/ X} TiDDleYwiNKs size="`wc -c func3.c`" size=`set - $size;echo $1` echo "x - func3.c, $size characters" if test "$size" != "3649" then echo "Warning: error in transmitting 'func3.c'; should have 3649 characters." fi fi if test -s "main.c" then echo Will not overwrite existing 'main.c' else sed -e "s/^X//" > main.c << 'TiDDleYwiNKs' X/* X * Phantasia 3.3.1 -- Interterminal fantasy game X * X * Edward A. Estes X * AT&T, August 28, 1985 X */ X X/* X * This version of Phantasia has been heavily hacked by Chris Robertson, X * September 1985. Changes include: X * - lots of cosmetics in the display (alignment, words not numbers, etc.) X * - added a shell escape X * - added HJKL keys for movement (== WSNE) for rogue, vi fans X * - timeout may be temporarily suspended with ^P (for answering phone etc.) X * - only SPACE BAR == melee in fighting so you aren't killed by typeahead X * - M == magic and B == luckout when fighting (commonest answers now X * easier to type) X * - speeded response by keeping the peoplefile and monsterfile always open X * - "more" accepts a RETURN as well as SPACE BAR X * - added "is in <wherever>" for non-visible or non-playing characters X * - neatened up the source code (set up indents, etc. for 4-char tabstop) X * - threw away RAND because it bombed on at least 2 systems, redid algorithm X * - characters are purged less frequently (3 weeks) X * - updated help file appropriately X * X * All complaints and suggestions to {decvax, linus, ihnp4}!utzoo!nonh X * and DON'T BUG Ted Estes for things I did, please. X */ X X/* DISCLAIMER: X * X * This game is distributed for free as is. It is not guaranteed to work X * in every conceivable environment. It is not even guaranteed to work X * in ANY environment. X * X * This game is distributed without notice of copyright, therefore it X * may be used in any manner the recipient sees fit. However, the X * author assumes no responsibility for maintaining or revising this X * game, in its original form, or any derivatives thereof. X * X * The author shall not be responsible for any loss, cost, or damage, X * including consequential damage, caused by reliance on this material. X * X * The author makes no warranties, express or implied, including warranties X * of merchantability or fitness for a particular purpose or use. X * X * AT&T is in no way connected with this game. X */ X X/* X * This is the program which drives the whole mess. Hopefully, you will be X * able to wade through the garbage if you have to fix something. X * Several undocumented items exist. The program checks uid and sets the X * boolean flag 'su' (super user) if the person is allowed special powers. X * This only happens if the game is invoked with '-S' as an option. X * The 'su' may execute any of the valar/council options. Also, X * a 'vaporize' option exists to kill anybody at will. The 'su' can select X * character type 7, which starts out with the maximum possible in each X * category. (The resulting character is an experimento.) The 'su' may X * also change the stats of other characters with the -x option (this won't X * work if they are currently playing! --CMR), or his own stats during play X * by typing 'A' instead of a movement command. X */ X X/* X * The program allocates as much file space as it needs to store characters, X * so the possibility exists for the character file to grow without bound. X * The file is purged upon normal entry to try to avoid that problem. X * A similar problem exists for energy voids. To alleviate the problem here, X * the void file is cleared with every new king. X */ X X/* X * The support functions are split among various files with no apparent X * order. Use of 'ctags' is recommended to find a particular function. X */ X X/* X * Put one line of text into the file 'motd' for announcements, etc. X */ X X/* X * If ENEMY is defined, a list of restricted login names is checked X * in the file 'enemy'. These names are listed, one per line, with X * no trailing blanks. These logins cannot play. X */ X X/* X * The scoreboard file is updated when someone dies, and keeps track X * of the highest character to date for that login. X * Being purged from the character file does not cause the scoreboard X * to be updated. X */ X X#include "phant.h" X Xdouble strength, speed; Xbool beyond, marsh, throne, valhala, changed, fghting, su, wmhl, X inshell, timeout; Xint fileloc, users; Xjmp_buf fightenv, mainenv; Xlong secs; XFILE *read_pfile, *access_pfile; /* pointers to peoplefile */ XFILE *mfile; /* pointer to monsterfile */ X X#ifdef WORM X/* X * worm hole map -- This table is carefully set up so that one can always X * return the way he/she came by inverting the initial path. X */ Xstruct worm_hole w_h[] = X { X 0,0,0,0, 35,22,2,0, 2,2,0,1, 59,34,64,0, X 54,47,0,60, 50,62,0,56, 19,31,25,0, 0,35,41,41, X 0,46,40,23, 24,0,29,30, 44,57,56,0, 0,44,39,40, X 61,41,0,42, 32,0,17,18, 57,0,63,64, 0,33,26,34, X 48,0,54,55, 28,23,22,13, 63,25,13,19, 34,6,18,20, X 27,26,19,21, 15,27,20,27, 1,28,34,17, 17,29,8,24, X 29,9,23,25, 18,30,24,6, 20,32,27,15, 21,20,21,26, X 22,17,46,29, 23,24,28,9, 25,38,9,31, 6,39,30,32, X 26,13,31,33, 15,40,32,35, 3,19,15,22, 7,1,33,36, X 37,37,35,37, 36,36,36,38, 30,42,37,39, 31,43,38,11, X 33,45,11,8, 12,48,7,7, 38,49,12,43, 39,51,42,44, X 11,10,43,45, 40,52,44,46, 8,53,45,28, 4,54,51,48, X 41,16,47,49, 42,55,48,50, 62,5,49,51, 43,56,50,47, X 45,58,53,53, 46,59,52,52, 47,4,55,16, 49,61,16,54, X 51,63,5,10, 10,14,59,58, 52,64,57,59, 53,3,58,57, X 60,60,4,61, 55,12,60,62, 5,50,61,63, 56,18,62,14, X 58,33,14,3 X }; X#endif X Xmain(argc,argv) /* Phantasia main routine */ X Xint argc; Xchar *argv[]; X{ X static struct stats charac; X char aline[200], *login = NULL; X double x = 0.0, y = 0.0; X int ch, ch2, loop, temp; X FILE *fp; X bool shrt = FALSE, examine = FALSE, header = FALSE; X X inshell = FALSE; X if ((login = getlogin()) == NULL) X login = getpwuid(getuid())->pw_name; X#ifdef ENEMY X X /* check hit list of restricted accounts */ X X if ((fp = fopen(enemyfile, "r")) != NULL) X { X char enemy[25]; X X while (fscanf(fp, "%s", enemy) != EOF) X if (!strcmp(login,enemy)) X { X printf ("The Phantasia privileges for the account '%s' have been revoked.\n", login); X printf ("Mail comments to %s.\n", WIZARD); X exit (0); X } X fclose (fp); X } X#endif X X /* get file pointers for peoplefile -- one read, one access */ X X if((read_pfile = fopen(peoplefile,"r")) == NULL) X { X error(peoplefile); X exit1(); X } X if((access_pfile = fopen(peoplefile,ACCESS)) == NULL) X { X error(peoplefile); X exit1(); X } X X /* fp for monsterfile */ X X if ((mfile = fopen(monsterfile,"r")) == NULL) X { X error(monsterfile); X exit1(); X } X X setbuf(stdin, (char *) NULL); /* this may or may not be necessary */ X su = FALSE; X fghting = FALSE; X timeout = FALSE; X users = 0; X while (--argc && (*++argv)[0] == '-') X switch ((*argv)[1]) X { X case 'h': /* help */ X if ((fp = fopen(helpfile, "r")) != NULL) X { X while (fgets(aline, 200, fp)) X fputs(aline, stdout); X fclose(fp); X } X exit(0); X /*NOTREACHED*/ X case 's': /* short */ X shrt = TRUE; X break; X case 'x': /* examine */ X examine = TRUE; X break; X case 'H': /* Header */ X header = TRUE; X break; X case 'm': /* monsters */ X printmonster(); X exit(0); X /*NOTREACHED*/ X case 'a': /* all users */ X showusers(FALSE); X exit(0); X /*NOTREACHED*/ X case 'p': /* purge old players */ X purge(); X exit(0); X /*NOTREACHED*/ X case 'S': X su = (getuid() == UID); X break; X case 'b': X show_sb(); X exit(0); X /*NOTREACHED*/ X } X if (!isatty(0)) /* don't let non-tty's play */ X exit(0); X init1(); /* set up for screen stuff */ X if (examine) X { X cstat(NULL); X exit1(); X /*NOTREACHED*/ X } X if (!shrt) X { X titlestuff(); X purge(); /* clean up old characters */ X } X if (header) X { X exit1(); X /*NOTREACHED*/ X } X#ifdef OK_TO_PLAY X if (!ok_to_play()) X { X mvaddstr(22,27,"Sorry, you can't play now.\n"); X exit1(); X /*NOTREACHED*/ X } X#endif X mvaddstr(22,24,"Do you have a character to run? "); X ch = getans("NY", FALSE); X if (ch == 'Y') X fileloc = findchar(&charac); X else X { X initchar(&charac); X clear(); X mvaddstr(4,21,"Which type of character do you want:"); X mvaddstr(8,0,"1: Magic User 2: Fighter 3: Elf 4: Dwarf 5:Halfling 6: Experimento "); X ch = getans("1234567", FALSE); X do X { X genchar(&charac,ch); X mvprintw(12,14,"Strength: %2.0f Quickness: %2d Mana: %3.0f", charac.str,charac.quk,charac.man); X mvprintw(13,14,"Energy Level: %2.0f Brains: %2.0f Magic Level: %2.0f", charac.energy,charac.brn,charac.mag); X if (charac.typ != 6) X { X mvaddstr(14,14,"Type '1' to keep > "); X ch2 = getans(" ", TRUE); X } X else X break; X } while (ch2 != '1'); X if (charac.typ == 6) X for (;;) X { X mvaddstr(16,0,"Enter X Y coordinates for your experimento: "); X getstring(aline,80); X sscanf(aline,"%F %F",&charac.x,&charac.y); X if (abs(charac.x) > 1.2e6 || abs(charac.y) > 1.2e6) X mvaddstr(17,0,"Invalid coordinates. Try again.\n"); X else X break; X } X for (;;) X { X mvaddstr(18,0,"Give your character a name [max 20 characters]: "); X getstring(aline,80); X strncpy(charac.name,aline,20); X charac.name[20] = '\0'; X trunc(charac.name); X if (charac.name[0] == '\0') X mvaddstr(19,0,"Invalid name."); X else if (findname(charac.name, (struct stats *) NULL) >= 0) X mvaddstr(19,0,"Name already in use."); X else X break; X addstr(" Pick another.\n"); X } X putchar('\n'); X fflush(stdout); X nocrmode(); X do X { X strcpy(charac.pswd,getpass("Give your character a password [max 8 characters]: ")); X putchar('\n'); X strcpy(aline,getpass("One more time to verify: ")); X } while (strcmp(charac.pswd,aline)); X fileloc = findspace(); X } X crmode(); X if (charac.status) X { X clear(); X addstr("Your character did not exit normally last time.\n"); X addstr("If you think you have good cause to have your character "); X printw("saved,\nyou may quit and mail your reason to '%s'.\n",WIZARD); X addstr("Otherwise, continuing spells certain death.\n"); X addstr("Do you want to quit? "); X ch = getans("YN", FALSE); X if (ch== 'Y') X { X charac.tampered = charac.quk; /* store this away */ X charac.quk = -100; X leave(&charac); X /*NOTREACHED*/ X } X death(&charac, "Stupidity"); X } X charac.status = PLAYING; X if (charac.lvl > 5) X timeout = TRUE; X strcpy(charac.login,login); X time(&secs); X charac.lastused = localtime(&secs)->tm_yday; X update(&charac,fileloc); X clear(); X#ifdef BSD41 X sigset(SIGINT,interrupt); X#endif X#ifdef BSD42 X signal(SIGINT,interrupt); X#endif X#ifdef SYS3 X signal(SIGINT,interrupt); X#endif X#ifdef SYS5 X signal(SIGINT,interrupt); X#endif X X /* all set for now */ X X XTOP: X switch (setjmp(mainenv)) X { X case QUIT: X#ifdef BSD41 X sigrelse(SIGINT); X#endif X#ifdef BSD42 X signal(SIGINT,interrupt); X#endif X#ifdef SYS3 X signal(SIGINT,interrupt); X#endif X#ifdef SYS5 X signal(SIGINT,interrupt); X#endif X leave(&charac); X /*NOTREACHED*/ X case DIE: X#ifdef BSD41 X sigrelse(SIGINT); X#endif X#ifdef BSD42 X signal(SIGINT,interrupt); X#endif X#ifdef SYS3 X signal(SIGINT,interrupt); X#endif X#ifdef SYS5 X signal(SIGINT,interrupt); X#endif X death(&charac, "Bailing out"); X break; X } X#ifdef OK_TO_PLAY X if (!ok_to_play()) X { X mvaddstr(6,0,"Whoops! Can't play now.\n"); X leave(&charac); X /*NOTREACHED*/ X } X#endif X fghting = FALSE; X adjuststats(&charac); X if (throne && !charac.crn && (charac.typ < 10 || charac.typ > 20)) X { X mvaddstr(5,0,"You're not allowed in the Lord's Chamber without a crown.\n"); X changed = TRUE; X charac.x = charac.y = 10 + roll(8, 5); X } X if (charac.status != CLOAKED && abs(charac.x) == abs(charac.y) && X floor(sqrt(fabs(charac.x/100.0))) == sqrt(fabs(charac.x/100.0)) && !throne) X { X trade(&charac); X clear(); X } X checktampered(&charac); X checkinterm(&charac); X if (charac.energy < 0 || (charac.lvl >= 10000 && charac.typ != 99)) X death(&charac, "Interterminal battle"); X neatstuff(&charac); X if (changed) X { X update(&charac,fileloc); X changed = FALSE; X goto TOP; X } X mesg(); X ch='U'; X printstats(&charac); X move(6,0); X#ifdef WORM X if (!wmhl) X#endif X { X if (throne) X kingstuff(&charac); X addstr("1:Move 2:Players 3:Talk 4:Stats 5:Quit "); X if (charac.lvl >= 7 && charac.mag >= 20) X addstr("6:Cloak "); X if (charac.lvl >= 12 && charac.mag >= 40) X addstr("7:Teleport "); X if (charac.typ > 20) X addstr("8:Intervene "); X ch = gch(charac.rng.type); X if (charac.lvl > 5) /* will re-set after a ^P */ X timeout = TRUE; X mvaddstr(4,0,"\n\n"); X if (charac.status == CLOAKED) X if (charac.man > 3.0) X charac.man -= 3; X else X { X charac.status = PLAYING; X changed = TRUE; X } X move(7,0); X /* clrtobot(); */ X if (charac.typ == 99 && (ch == '1' || ch == '7')) X ch = ' '; X switch (ch2 = ch) X { X case 'A': /* for altering your char if you're su */ X if (su) X { X cstat(&charac); X goto TOP; X } X /*FALLTHROUGH*/ X case '\020': /* ^P -- suspend the game temporarily */ X if (timeout) X timeout = FALSE; X goto TOP; X /*NOTREACHED*/ X case 'K': X case 'N': X charac.y += maxmove; X break; X case 'J': X case 'S': X charac.y -= maxmove; X break; X case 'L': X case 'E': X charac.x += maxmove; X break; X case 'H': X case 'W': X charac.x -= maxmove; X break; X default: /* rest */ X charac.energy += (charac.mxn+charac.shd)/15+charac.lvl/3+2; X charac.energy = min(charac.energy,charac.mxn + charac.shd); X if (charac.status != CLOAKED) X { X charac.man += circ(charac.x,charac.y)/4; X charac.man += charac.lvl/6; X randattack(); X } X break; X case '1': /* move */ X for (loop = 3; loop; --loop) X { X mvaddstr(4,0,"X Y Coordinates: "); X getstring(aline,80); X if (sscanf(aline,"%F %F",&x,&y) != 2) X mvaddstr(5,0,"Try again\n"); X else if (dist(charac.x, x, charac.y, y) > maxmove) X illmove(); X else X { X charac.x = x; X charac.y = y; X break; X } X } X break; X case '2': /* players */ X printplayers(&charac); X break; X case '3': /* message */ X mvaddstr(4,0,"Message: "); X getstring(aline, 80); X fp = fopen(messfile, "w"); X if (*aline) X fprintf(fp, "%s: %s", charac.name, aline); X fclose(fp); X break; X case '4': /* stats */ X showall(&charac); X break; X case '5': /* good-bye */ X leave(&charac); X /*NOTREACHED*/ X case '6': /* cloak */ X if (charac.lvl < 7 || charac.mag < 20) X illcmd(); X else if (charac.status == CLOAKED) X charac.status = PLAYING; X else if (charac.man < 35) X { X mvaddstr(5,0,"No power left.\n"); X refresh(); X } X else X { X changed = TRUE; X charac.man -= 35; X charac.status = CLOAKED; X } X break; X case '7': /* teleport */ X if (charac.lvl < 12 || charac.mag < 40) X illcmd(); X else for (loop = 3; loop; --loop) X { X mvaddstr(4,0,"X Y Coordinates: "); X getstring(aline,80); X if (sscanf(aline,"%F %F",&x,&y) == 2) X if ((temp = dist(charac.x,x,charac.y,y)) > (charac.lvl X + charac.mag)*20+((charac.typ > 30) ? 1e+6 : 0) X && !throne) X illmove(); X else if ((temp = (temp/75+1)*20) > charac.man X && !throne) X mvaddstr(5,0,"Not enough power for that distance.\n"); X else X { X charac.x = x; X charac.y = y; X if (!throne) X charac.man -= temp; X break; X } X } X break; X case 'C': X case '9': /* monster */ X if (throne) X mvaddstr(5,0,"No monsters in the chamber!\n"); X else if (charac.typ != 99) X { X charac.status = PLAYING; X changed = TRUE; X charac.sin += 1e-6; X fight(&charac,-1); X } X break; X case '0': /* decree */ X if (su || charac.typ > 10 && charac.typ < 20 && throne) X decree(&charac); X else X illcmd(); X break; X case '8': /* intervention */ X if (su || charac.typ > 20) X valarstuff(&charac); X else X illcmd(); X break; X case '\014': /* redo screen */ X clear(); X } X if (ch2 == 'E' || ch2 == 'W' || ch2 == 'N' || ch2 == 'S' X || ch2 == 'L' || ch2 == 'H' || ch2 == 'K' || ch2 == 'J' X || ch2 == '1' || ch2 == '7') X { X checkmov(&charac); X randattack(); X changed = TRUE; X } X } X#ifdef WORM X else X { X addstr("F: Forward B: Back R: Right L: Left Q: Quit T: Talk P: Players S: Stats "); X ch = getans(" ", TRUE); X move(6,0); X /* clrtobot(); */ X if (charac.status == CLOAKED) X if (charac.man > 3.0) X charac.man -= 3; X else X { X charac.status = PLAYING; X changed = TRUE; X } X switch (ch) X { X case 'A': /* for altering your char if you're su */ X if (su) X { X cstat(&charac); X goto TOP; X } X /*FALLTHROUGH*/ X default: /* rest */ X charac.energy += (charac.mxn+charac.shd)/15+charac.lvl/3+2; X charac.energy = min(charac.energy,charac.mxn + charac.shd); X if (charac.status != CLOAKED) X charac.man += charac.lvl/5; X break; X case '\020': /* ^P -- suspend the game temporarily */ X if (timeout) X timeout = FALSE; X goto TOP; X /*NOTREACHED*/ X case 'F': X temp = w_h[charac.wormhole].f; X goto CHKMOVE; X case 'B': X temp = w_h[charac.wormhole].b; X goto CHKMOVE; X case 'R': X temp = w_h[charac.wormhole].r; X goto CHKMOVE; X case 'L': X temp = w_h[charac.wormhole].l; X goto CHKMOVE; X case 'Q': X leave(&charac); X /*NOTREACHED*/ X case 'T': X mvaddstr(4,0,"Message: "); X getstring(aline, 80); X fp = fopen(messfile, "w"); X if (*aline) X fprintf(fp, "%s: %s", charac.name, aline); X fclose(fp); X break; X case 'P': X printplayers(&charac); X break; X case 'S': X showall(&charac); X break; X case '\014': /* redo screen */ X clear(); X break; X } X goto TOP; XCHKMOVE: X if (!temp) X { X charac.y = 0.0; X charac.x = pow(-1.0,(double) charac.wormhole) * charac.wormhole X * 400 - 1.0; X charac.wormhole = 0; X changed = TRUE; X } X else X charac.wormhole = temp; X } X#endif X goto TOP; X} X X/* X * This function is provided to allow one to restrict access to the game. X * Tailor this routine as appropriate. X */ X X#ifdef OK_TO_PLAY X#include <sys/types.h> X#include <utmp.h> /* used for counting users on system */ X Xbool Xok_to_play() /* return FALSE if playing is not allowed at this time */ X{ X#define MAXUSERS 30 /* max. number of people on system */ X reg struct tm *tp; X reg int numusers = 0; X FILE *fp; X long now; X struct utmp ubuf; X X if (su) X return (TRUE); X X /* check time of day */ X X time(&now); X tp = localtime(&now); X if (((tp->tm_hour > 8 && tp->tm_hour < 12) /* 8-noon */ X || (tp->tm_hour > 12 && tp->tm_hour < 16)) /* 1-4 pm */ X && (tp->tm_wday != 0 && tp->tm_wday != 6)) /* not a weekend */ X return (FALSE); X X /* check # of users */ X X if ((fp = fopen("/etc/utmp","r")) != NULL) X { X while (fread((char *) &ubuf,sizeof(ubuf),1,fp)) X#ifdef SYS5 X if (ubuf.ut_type == USER_PROCESS) X#else X if (*ubuf.ut_name) X#endif X ++numusers; X fclose(fp); X if (numusers > MAXUSERS) X return (FALSE); X } X return (TRUE); X} X#endif TiDDleYwiNKs size="`wc -c main.c`" size=`set - $size;echo $1` echo "x - main.c, $size characters" if test "$size" != "18696" then echo "Warning: error in transmitting 'main.c'; should have 18696 characters." fi fi if test -s "monsters" then echo Will not overwrite existing 'monsters' else sed -e "s/^X//" > monsters << 'TiDDleYwiNKs' Xa Water Leaper 12 14 16 24 59 0 0 62 Xa Leech 4 19 29 30 66 0 0 73 Xan Urisk 13 30 15 46 127 1 0 3 XShellycoat 28 21 18 63 226 2 0 0 Xa Naiad 21 62 27 58 378 2 0 11 Xa Nixie 22 58 28 108 604 3 0 6 Xa Glaistig 21 106 25 127 1002 3 0 0 Xa Mermaid 18 116 22 108 809 3 0 0 Xa Merman 24 115 23 109 808 4 0 0 Xa Siren 22 128 31 89 915 4 0 24 Xa Lamprey 14 67 33 156 1562 4 15 37 Xa Kopoacinth 26 36 26 206 2006 5 0 20 Xa Kelpie 61 25 24 223 4025 5 0 0 Xan Aspidchelone 114 104 19 898 10041 7 0 2 Xan Idiot 13 14 16 28 49 0 0 0 Xsome Green Slime 1 5 45 100 57 0 0 26 Xa Pixie 11 29 23 26 64 0 0 32 Xa Serpent 10 18 25 25 79 0 0 10 Xa Cluricaun 12 27 20 30 81 0 14 5 Xan Imp 22 30 14 40 92 0 0 1 Xa Centipede 3 8 18 15 33 0 0 61 Xa Beetle 2 11 21 26 44 0 0 48 Xa Fir Darrig 18 22 17 35 107 0 14 1 XModnar 15 23 20 40 101 7 2 12 Xa Gnome 7 45 26 23 111 0 0 21 Xa Sprite 9 37 25 31 132 1 0 43 Xa Mimic 11 55 29 47 213 1 3 2 Xa Kobold 13 10 14 21 121 1 12 68 Xa Spider 6 11 28 28 124 1 0 57 Xan Uldra 14 37 21 32 93 1 0 6 Xa Gnoll 20 25 15 40 166 1 0 61 Xa Bogie 23 28 19 57 189 1 0 57 Xa Fachan 9 40 15 45 139 1 14 10 Xa Moron 3 1 10 10 28 0 0 50 Xan Orc 25 13 16 26 141 1 0 92 Xa Ghillie Dhu 12 16 13 28 104 2 14 2 Xa Bogle 19 15 16 35 157 2 14 15 Xa Shrieker 2 62 27 9 213 2 16 0 Xa Carrion Crawler 12 20 20 65 142 2 0 42 Xa Trow 15 17 23 51 136 2 0 36 Xa Warg 20 10 17 45 152 2 0 88 Xa Stirge 2 6 35 25 153 2 0 95 Xa Crebain 5 11 31 31 82 2 0 81 Xa Killmoulis 30 19 8 75 175 3 14 22 Xa Hob-goblin 35 20 15 72 246 3 0 18 Xa Unicorn 27 57 27 57 627 3 1 0 Xa Fenoderee 16 6 21 65 222 3 0 42 Xan Ogre 42 14 16 115 409 3 0 19 Xa Dodo 62 12 11 76 563 3 0 3 Xa Hydra 14 27 33 99 599 3 0 27 Xa Hamadryad 23 47 26 62 426 3 0 12 Xa Bwca 21 17 19 55 387 3 14 1 Xan Owlbear 35 16 18 100 623 4 0 22 XBlack Annis 37 52 15 65 786 4 0 2 Xa Jello Blob 100 25 7 264 1257 4 0 13 Xa Jubjub Bird 45 23 12 114 1191 4 0 0 Xa Wichtlein 13 40 25 61 800 4 0 8 Xa Cocodrill 39 28 24 206 1438 4 0 38 Xa Troll 75 12 20 185 1013 4 24 29 Xa Bonnacon 89 26 9 255 1661 4 17 14 Xa Gargoyle 22 21 29 200 1753 5 0 7 Xa Chaladrius 8 49 37 172 1929 5 0 20 Xa Gwyllion 27 73 20 65 1888 5 0 4 Xa Cinomulgus 23 2 10 199 263 5 0 18 Xa Peridexion 26 32 24 98 1300 5 0 2 XSmeagol 41 33 27 373 2487 5 18 0 Xa Wraith 52 102 22 200 3112 5 25 13 Xa Snotgurgle 143 19 26 525 4752 6 0 3 Xa Phooka 42 63 21 300 4125 5 0 12 Xa Vortex 101 30 31 500 6992 6 9 4 XShelob 147 64 28 628 5003 7 13 0 Xa Thaumaturgist 35 200 23 400 7628 6 7 0 XSmaug 251 76 26 1022 9877 7 0 0 Xa Cold-drake 301 102 24 1222 10888 7 0 0 Xa Red Dragon 342 141 23 1299 11649 8 0 0 XScatha the Worm 406 208 20 1790 11999 8 0 0 XTiamat 506 381 29 2000 13001 9 11 0 Xa Bandersnatch 105 98 22 450 7981 6 0 3 Xa Harpy 103 49 24 263 7582 6 0 2 Xa Tigris 182 38 17 809 7777 6 0 3 Xa Gryphon 201 45 19 813 8888 7 0 1 Xa Coblynau 205 46 18 585 8333 6 0 2 Xa Chimaera 173 109 28 947 12006 7 0 0 Xa Jack-in-Irons 222 36 12 1000 9119 7 0 0 XSaruman 55 373 17 1500 17101 11 6 0 Xa Balrog 500 100 25 705 8103 7 8 0 XArgus 201 87 14 1500 10010 8 0 0 Xa Titan 302 1483 12 1625 11011 8 0 0 XCacus 256 43 19 1750 12012 8 0 0 XBegion 403 154 10 1875 13013 8 0 0 XGrendel 197 262 23 2000 14014 8 0 0 Xa Nazgul 250 251 26 1011 9988 12 10 9 Xa Succubus 186 1049 27 2007 19984 9 19 0 XRed Cap 143 50 35 1965 23456 9 0 0 Xa Nuckelavee 300 75 20 2185 11111 8 0 0 XCerberus 236 96 29 2600 25862 9 20 0 Xa Jabberwock 185 136 25 2265 23256 9 22 0 XUngoliant 399 2398 37 2784 27849 10 21 0 XLeanan-Sidhe 486 5432 46 3000 30004 9 5 0 Xthe Dark Lord 9999 9999 31 19999 30005 13 4 0 TiDDleYwiNKs size="`wc -c monsters`" size=`set - $size;echo $1` echo "x - monsters, $size characters" if test "$size" != "7442" then echo "Warning: error in transmitting 'monsters'; should have 7442 characters." fi fi if test -s "pathdefs.c" then echo Will not overwrite existing 'pathdefs.c' else sed -e "s/^X//" > pathdefs.c << 'TiDDleYwiNKs' X/* X * pathdefs.c X * X * Edit these values to put things in different places. X */ X X#include "phant.h" X Xchar monsterfile[] = PATH/monsters", X peoplefile[] = PATH/characs", X gameprog[] = PATH/phantasia", X messfile[] = PATH/mess", X lastdead[] = PATH/lastdead", X helpfile[] = PATH/phant.help", X motd[] = PATH/motd", X goldfile[] = PATH/gold", X voidfile[] = PATH/void", X#ifdef ENEMY X enemyfile[] = PATH/enemy", X#endif X sbfile[] = PATH/scoreboard"; TiDDleYwiNKs size="`wc -c pathdefs.c`" size=`set - $size;echo $1` echo "x - pathdefs.c, $size characters" if test "$size" != "450" then echo "Warning: error in transmitting 'pathdefs.c'; should have 450 characters." fi fi if test -s "setup.c" then echo Will not overwrite existing 'setup.c' else sed -e "s/^X//" > setup.c << 'TiDDleYwiNKs' X/* X * setup.c Program to set up all files for Phantasia X * X * This program tries to verify the parameters specified in X * the Makefile. Since Phantasia assumes its files exist, X * simple errors can result in core dumps. X * X * This program tries to check against this. X * X * Note that this is not fool-proof, and that this could X * be much more clever in checking everything. X * Hopefully, someone will enhance this someday. X */ X X#include "phant.h" X#include <sys/types.h> X#include <sys/stat.h> X X#ifdef SMALL X#define rnd() ((rand () % 1000)/1000.0) X#endif X Xmain(argc,argv) /* program to init. files for Phantasia */ X Xint argc; Xchar **argv; X{ X FILE *fp; X struct stats sbuf; X struct energyvoid grail; X struct stat fbuf; X register int loop; X char stbuf[128]; X long ltmp; X X srand((int) time(NULL)); /* prime random numbers */ X umask(077); X X /* check where Phantasia lives */ X X if (stat(PATH",&fbuf) < 0) X { X perror(PATH"); X exit(1); X /*NOTREACHED*/ X } X if (fbuf.st_mode & S_IFDIR == 0) X Error("%s is not a directory.\n",PATH"); X X /* try to create data files */ X X if ((fp = fopen(goldfile,"w")) == NULL) X Error("cannot create %s.\n",goldfile); X else X fclose(fp); X if ((fp = fopen(motd,"w")) == NULL) X Error("cannot create %s.\n",motd); X else X fclose(fp); X if ((fp = fopen(messfile,"w")) == NULL) X Error("cannot create %s.\n",messfile); X else X fclose(fp); X X /* do not reset character file if it already exists */ X X if (stat(peoplefile,&fbuf) < 0) X { X buildchar(&sbuf); X strcpy(sbuf.name,"<null>"); X if ((fp = fopen(peoplefile,"w")) == NULL) X Error("cannot create %s.\n",peoplefile); X else X { X fwrite(&sbuf,sizeof(sbuf),1,fp); X fclose(fp); X } X } X grail.active = TRUE; X grail.v_x = roll(-1.0e6,2.0e6); X grail.v_y = roll(-1.0e6,2.0e6); X if ((fp = fopen(voidfile,"w")) == NULL) X Error("cannot create %s.\n",voidfile); X else X { X fwrite(&grail,sizeof(grail),1,fp); X fclose(fp); X } X if ((fp = fopen(lastdead,"w")) == NULL) X Error("cannot create %s.\n",lastdead); X else X fclose(fp); X#ifdef ENEMY X if ((fp = fopen(enemyfile,"w")) == NULL) X Error("cannot create %s.\n",enemyfile); X else X fclose(fp); X#endif X if ((fp = fopen(sbfile,"w")) == NULL) X Error("cannot create %s.\n",sbfile); X else X fclose(fp); X if (getuid() != UID) X fprintf(stderr,"Warning: UID (%d) is not equal to current uid.\n",UID); X exit(0); X} X Xbuildchar(stat) /* put in some default values */ X/* Note that this function is almost the same as initchar(). X It is used to insure that unexpected values will not be found in a X new character file. */ Xstruct stats *stat; X{ X stat->x = roll(-125,251); X stat->y = roll(-125,251); X stat->exp = stat->lvl = stat->sin = 0; X stat->crn = stat->psn = 0; X stat->rng.type = NONE; X stat->rng.duration = 0; X stat->pal = FALSE; X stat->hw = stat->amu = stat->bls = 0; X stat->chm = 0; X stat->gem = 0.1; X stat->gld = roll(25,50) + roll(0,25) + 0.1; X stat->quks = stat->swd = stat->shd = 0; X stat->vrg = FALSE; X stat->typ = 0; X} X XError(str,file) /* print an error message, and exit */ Xchar *str, *file; X{ X fprintf(stderr,"Error: "); X fprintf(stderr,str,file); X exit(1); X /*NOTREACHED*/ X} TiDDleYwiNKs size="`wc -c setup.c`" size=`set - $size;echo $1` echo "x - setup.c, $size characters" if test "$size" != "3123" then echo "Warning: error in transmitting 'setup.c'; should have 3123 characters." fi fi