Initial revision

git-svn-id: file:///srv/svn/joey/bsdgames-trunk@5086 a4a2c43b-8ac3-0310-8836-e0e880c912e2
This commit is contained in:
joey
1999-09-08 23:56:51 +00:00
commit 03272d67da
623 changed files with 243457 additions and 0 deletions

26
phantasia/COPYRIGHT Normal file
View File

@@ -0,0 +1,26 @@
$NetBSD: COPYRIGHT,v 1.2 1995/03/24 03:58:08 cgd Exp $
This entire subtree is explicitly not copyrighted.
The following notice applies to all files found here. None of
these files contain AT&T proprietary source code.
_____________________________________________________________________________
/* DISCLAIMER:
*
* This game is distributed for free as is. It is not guaranteed to work
* in every conceivable environment. It is not even guaranteed to work
* in ANY environment.
*
* This game is distributed without notice of copyright, therefore it
* may be used in any manner the recipient sees fit. However, the
* author assumes no responsibility for maintaining or revising this
* game, in its original form, or any derivitives thereof.
*
* The author shall not be responsible for any loss, cost, or damage,
* including consequential damage, caused by reliance on this material.
*
* The author makes no warranties, express or implied, including warranties
* of merchantability or fitness for a particular purpose or use.
*
* AT&T is in no way connected with this game.
*/

37
phantasia/Makefile.bsd Normal file
View File

@@ -0,0 +1,37 @@
# $NetBSD: Makefile,v 1.16 1998/02/18 22:37:32 jtc Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= phantasia
SRCS= fight.c gamesupport.c interplayer.c io.c main.c misc.c phantglobs.c
DPADD= ${LIBM} ${LIBCURSES}
LDADD= -lm -lcurses
HIDEGAME=hidegame
SETGIDGAME=yes
USETBL=
MAN= phantasia.6
CLEANFILES+=map setup setup.o host_phantglobs.o
all: setup phantasia
setup: host_phantglobs.o setup.o monsters.asc ${LIBM}
${HOST_CC} host_phantglobs.o setup.o -o ${.TARGET} -lm
host_phantglobs.o: ${.CURDIR}/phantglobs.c
${HOST_COMPILE.c} -o host_phantglobs.o ${.CURDIR}/phantglobs.c
setup.o: ${.CURDIR}/setup.c
${HOST_COMPILE.c} ${.CURDIR}/setup.c
afterinstall:
./setup -m ${.CURDIR}/monsters.asc
chown games:games ${DESTDIR}/var/games/phantasia/*
# Make Phantasia map. Change the map commands reflect your installation.
# PLOTDEVICE is used for plotting the map. Change as appropriate.
map: map.c
${CC} -O ${.CURDIR}/map.c -lplot -o ${.TARGET}
./map | plot > /dev/tty
.include <bsd.prog.mk>

14
phantasia/Makefrag Normal file
View File

@@ -0,0 +1,14 @@
# Makefrag - makefile fragment for phantasia
phantasia_DIRS := $(GAMESDIR) $(MAN6DIR) $(PHANTASIA_DIR)
phantasia_VFILES := gold lastdead mess monsters motd characs scoreboard void
phantasia_all: phantasia/phantasia phantasia/setup phantasia/monsters.asc phantasia/phantasia.6
phantasia_install: phantasia_all
$(INSTALL_SCORE_GAME) phantasia/phantasia $(INSTALL_PREFIX)$(GAMESDIR)/phantasia
$(HIDE_GAME) phantasia
DESTDIR=$(INSTALL_PREFIX) phantasia/setup -m phantasia/monsters.asc
(set -e; for f in $(phantasia_VFILES); do $(INSTALL_SCORE_FILE) \
$(PHANTASIA_DIR)/$$f; done)
$(INSTALL_MANUAL) phantasia/phantasia.6

6
phantasia/OWNER Normal file
View File

@@ -0,0 +1,6 @@
Edward Estes
AT&T
5555 Touhy Ave.
Skokie, IL 60077
(312) 982-3969
ihnp4!ttrde!estes

84
phantasia/README Normal file
View File

@@ -0,0 +1,84 @@
$NetBSD: README,v 1.2 1995/03/24 03:58:29 cgd Exp $
June 25, 1986
This is a much modified version of Phantasia. It is intended to fix
all reported bug fixes, enhance the game, and speed up the game.
I have to thank Chris Robertson for many ideas which have made the game
faster, and more user-friendly. Most of her changes/additions are
incorporated in this latest versions, although perhaps not in the exact
manner of her design. I left out a few items which were not in keeping
with the spirit of the game. (For example, I didn't like the extra lives
and the pausing of the game. I think it's too easy even WITHOUT that stuff.)
CHANGES:
- Wormholes have been deleted (I never liked them anyway).
- The source code has been greatly enhanced for speed, size, readability,
and maintainability.
fight.c should no longer cause optimizers to run out of space.
- A few loopholes have been tightened to make the game more enjoyable.
(Except for those who are in the habit of exercising those loopholes.)
- Chris' map is enclosed.
- The "charac" file is not compatible with older versions of Phantasia
(3.3.1 and 3.3.1+). A 'convert' program is provided to convert your
old file to the new format. See Makefile for details.
- Movements can be made with HJKL for WSNE, respectively.
- Players may examine others while playing ('x') option.
- Monsters are now stored in a binary data base, to speed calling
monsters, and to ease formatting of monster listings.
- Taxes are collected on all gold and gems.
- Dead players can be resurrected by the 'wizard'.
- 'setup' is smarter, although not as smart as it should be.
- Players can change their names and passwords
PORTABILTY:
I have tried to make this as non-machine/system specific as possible.
All identifiers are unique to 7 characters or less, dual case.
The code WILL NOT fit on a 16-bit machine without separate I/D.
Stdio MUST support fopen() with mode "r+". I think this is true
for all Version 7 and later.
'curses' library functions are required.
All problems/solutions with portability should be reported to me,
and fixes will be included in subsequent versions of this software.
Please send me any bugs, (of which I am sure there are many), you may find,
but PLEASE be specific. I cannot correct a bug which is described as:
"When I choose a character type, it blows up."
(What blows up? What exactly was printed at the terminal?
Which character type was chosen? Etc. . . ?)
Also, please tell me which version of UN*X you are running, and upon
which type of hardware.
I will also do my best to help anyone with problems just trying to
get the game running. Again, I need to know which version of UN*X
and what type of CPU. Also, a copy of the output from 'make'
would be extremely useful.
Any and all ideas/suggestions/additions are more than welcome. If
you feel strongly enough about it, write the change and send it to me,
and I will do my best to incorporate it in the next version of Phantasia.
Otherwise, I will give serious thought to adding it myself.
Follow the directions in the Makefile CAREFULLY to set up the game.
Read the comments at the beginning of 'main.c', if you haven't already.
Enjoy.
Ted Estes
AT&T Information Systems
Skokie, IL 60077
...!ihnp4!ttrdc!ttrda!estes

1394
phantasia/fight.c Normal file

File diff suppressed because it is too large Load Diff

549
phantasia/gamesupport.c Normal file
View File

@@ -0,0 +1,549 @@
/* $NetBSD: gamesupport.c,v 1.4 1997/10/13 02:18:16 lukem Exp $ */
/*
* gamesupport.c - auxiliary routines for support of Phantasia
*/
#include "include.h"
void
changestats(ingameflag)
bool ingameflag;
{
static char flag[2] = /* for printing values of bools */
{'F', 'T'};
struct player *playerp; /* pointer to structure to alter */
char *prompt; /* pointer to prompt string */
int c; /* input */
int today; /* day of year of today */
int temp; /* temporary variable */
long loc; /* location in player file */
time_t now; /* time now */
double dtemp; /* temporary variable */
bool *bptr; /* pointer to bool item to change */
double *dptr; /* pointer to double item to change */
short *sptr; /* pointer to short item to change */
clear();
for (;;)
/* get name of player to examine/alter */
{
mvaddstr(5, 0, "Which character do you want to look at ? ");
getstring(Databuf, SZ_DATABUF);
truncstring(Databuf);
if (Databuf[0] == '\0')
userlist(ingameflag);
else
break;
}
loc = -1L;
if (!ingameflag)
/* use 'Player' structure */
playerp = &Player;
else
if (strcmp(Databuf, Player.p_name) == 0)
/* alter/examine current player */
{
playerp = &Player;
loc = Fileloc;
} else
/* use 'Other' structure */
playerp = &Other;
/* find player on file */
if (loc < 0L && (loc = findname(Databuf, playerp)) < 0L)
/* didn't find player */
{
clear();
mvaddstr(11, 0, "Not found.");
return;
}
time(&now);
today = localtime(&now)->tm_yday;
clear();
for (;;)
/* print player structure, and prompt for action */
{
mvprintw(0, 0, "A:Name %s\n", playerp->p_name);
if (Wizard)
printw("B:Password %s\n", playerp->p_password);
else
addstr("B:Password XXXXXXXX\n");
printw(" :Login %s\n", playerp->p_login);
printw("C:Experience %.0f\n", playerp->p_experience);
printw("D:Level %.0f\n", playerp->p_level);
printw("E:Strength %.0f\n", playerp->p_strength);
printw("F:Sword %.0f\n", playerp->p_sword);
printw(" :Might %.0f\n", playerp->p_might);
printw("G:Energy %.0f\n", playerp->p_energy);
printw("H:Max-Energy %.0f\n", playerp->p_maxenergy);
printw("I:Shield %.0f\n", playerp->p_shield);
printw("J:Quickness %.0f\n", playerp->p_quickness);
printw("K:Quicksilver %.0f\n", playerp->p_quksilver);
printw(" :Speed %.0f\n", playerp->p_speed);
printw("L:Magic Level %.0f\n", playerp->p_magiclvl);
printw("M:Mana %.0f\n", playerp->p_mana);
printw("N:Brains %.0f\n", playerp->p_brains);
if (Wizard || playerp->p_specialtype != SC_VALAR)
mvaddstr(0, 40, descrstatus(playerp));
mvprintw(1, 40, "O:Poison %0.3f\n", playerp->p_poison);
mvprintw(2, 40, "P:Gold %.0f\n", playerp->p_gold);
mvprintw(3, 40, "Q:Gem %.0f\n", playerp->p_gems);
mvprintw(4, 40, "R:Sin %0.3f\n", playerp->p_sin);
if (Wizard) {
mvprintw(5, 40, "S:X-coord %.0f\n", playerp->p_x);
mvprintw(6, 40, "T:Y-coord %.0f\n", playerp->p_y);
} else {
mvaddstr(5, 40, "S:X-coord ?\n");
mvaddstr(6, 40, "T:Y-coord ?\n");
}
mvprintw(7, 40, "U:Age %ld\n", playerp->p_age);
mvprintw(8, 40, "V:Degenerated %d\n", playerp->p_degenerated);
mvprintw(9, 40, "W:Type %d (%s)\n",
playerp->p_type, descrtype(playerp, FALSE) + 1);
mvprintw(10, 40, "X:Special Type %d\n", playerp->p_specialtype);
mvprintw(11, 40, "Y:Lives %d\n", playerp->p_lives);
mvprintw(12, 40, "Z:Crowns %d\n", playerp->p_crowns);
mvprintw(13, 40, "0:Charms %d\n", playerp->p_charms);
mvprintw(14, 40, "1:Amulets %d\n", playerp->p_amulets);
mvprintw(15, 40, "2:Holy Water %d\n", playerp->p_holywater);
temp = today - playerp->p_lastused;
if (temp < 0)
/* last year */
temp += 365;
mvprintw(16, 40, "3:Lastused %d (%d)\n", playerp->p_lastused, temp);
mvprintw(18, 8, "4:Palantir %c 5:Blessing %c 6:Virgin %c 7:Blind %c",
flag[(int)playerp->p_palantir],
flag[(int)playerp->p_blessing],
flag[(int)playerp->p_virgin],
flag[(int)playerp->p_blindness]);
if (!Wizard)
mvprintw(19, 8, "8:Ring %c",
flag[playerp->p_ring.ring_type != R_NONE]);
else
mvprintw(19, 8, "8:Ring %d 9:Duration %d",
playerp->p_ring.ring_type, playerp->p_ring.ring_duration);
if (!Wizard
/* not wizard */
&& (ingameflag || strcmp(Login, playerp->p_login) != 0))
/* in game or not examining own character */
{
if (ingameflag) {
more(LINES - 1);
clear();
return;
} else
cleanup(TRUE);
/* NOTREACHED */
}
mvaddstr(20, 0, "!:Quit ?:Delete");
mvaddstr(21, 0, "What would you like to change ? ");
if (Wizard)
c = getanswer(" ", TRUE);
else
/* examining own player; allow to change name and
* password */
c = getanswer("!BA", FALSE);
switch (c) {
case 'A': /* change name */
case 'B': /* change password */
if (!Wizard)
/* prompt for password */
{
mvaddstr(23, 0, "Password ? ");
Echo = FALSE;
getstring(Databuf, 9);
Echo = TRUE;
if (strcmp(Databuf, playerp->p_password) != 0)
continue;
}
if (c == 'A')
/* get new name */
{
mvaddstr(23, 0, "New name: ");
getstring(Databuf, SZ_NAME);
truncstring(Databuf);
if (Databuf[0] != '\0')
if (Wizard || findname(Databuf, &Other) < 0L)
strcpy(playerp->p_name, Databuf);
} else
/* get new password */
{
if (!Wizard)
Echo = FALSE;
do
/* get two copies of new password
* until they match */
{
/* get first copy */
mvaddstr(23, 0, "New password ? ");
getstring(Databuf, SZ_PASSWORD);
if (Databuf[0] == '\0')
break;
/* get second copy */
mvaddstr(23, 0, "One more time ? ");
getstring(playerp->p_password, SZ_PASSWORD);
}
while (strcmp(playerp->p_password, Databuf) != 0);
Echo = TRUE;
}
continue;
case 'C': /* change experience */
prompt = "experience";
dptr = &playerp->p_experience;
goto DALTER;
case 'D': /* change level */
prompt = "level";
dptr = &playerp->p_level;
goto DALTER;
case 'E': /* change strength */
prompt = "strength";
dptr = &playerp->p_strength;
goto DALTER;
case 'F': /* change swords */
prompt = "sword";
dptr = &playerp->p_sword;
goto DALTER;
case 'G': /* change energy */
prompt = "energy";
dptr = &playerp->p_energy;
goto DALTER;
case 'H': /* change maximum energy */
prompt = "max energy";
dptr = &playerp->p_maxenergy;
goto DALTER;
case 'I': /* change shields */
prompt = "shield";
dptr = &playerp->p_shield;
goto DALTER;
case 'J': /* change quickness */
prompt = "quickness";
dptr = &playerp->p_quickness;
goto DALTER;
case 'K': /* change quicksilver */
prompt = "quicksilver";
dptr = &playerp->p_quksilver;
goto DALTER;
case 'L': /* change magic */
prompt = "magic level";
dptr = &playerp->p_magiclvl;
goto DALTER;
case 'M': /* change mana */
prompt = "mana";
dptr = &playerp->p_mana;
goto DALTER;
case 'N': /* change brains */
prompt = "brains";
dptr = &playerp->p_brains;
goto DALTER;
case 'O': /* change poison */
prompt = "poison";
dptr = &playerp->p_poison;
goto DALTER;
case 'P': /* change gold */
prompt = "gold";
dptr = &playerp->p_gold;
goto DALTER;
case 'Q': /* change gems */
prompt = "gems";
dptr = &playerp->p_gems;
goto DALTER;
case 'R': /* change sin */
prompt = "sin";
dptr = &playerp->p_sin;
goto DALTER;
case 'S': /* change x coord */
prompt = "x";
dptr = &playerp->p_x;
goto DALTER;
case 'T': /* change y coord */
prompt = "y";
dptr = &playerp->p_y;
goto DALTER;
case 'U': /* change age */
mvprintw(23, 0, "age = %ld; age = ", playerp->p_age);
dtemp = infloat();
if (dtemp != 0.0)
playerp->p_age = (long) dtemp;
continue;
case 'V': /* change degen */
mvprintw(23, 0, "degen = %d; degen = ", playerp->p_degenerated);
dtemp = infloat();
if (dtemp != 0.0)
playerp->p_degenerated = (int) dtemp;
continue;
case 'W': /* change type */
prompt = "type";
sptr = &playerp->p_type;
goto SALTER;
case 'X': /* change special type */
prompt = "special type";
sptr = &playerp->p_specialtype;
goto SALTER;
case 'Y': /* change lives */
prompt = "lives";
sptr = &playerp->p_lives;
goto SALTER;
case 'Z': /* change crowns */
prompt = "crowns";
sptr = &playerp->p_crowns;
goto SALTER;
case '0': /* change charms */
prompt = "charm";
sptr = &playerp->p_charms;
goto SALTER;
case '1': /* change amulet */
prompt = "amulet";
sptr = &playerp->p_amulets;
goto SALTER;
case '2': /* change holy water */
prompt = "holy water";
sptr = &playerp->p_holywater;
goto SALTER;
case '3': /* change last-used */
prompt = "last-used";
sptr = &playerp->p_lastused;
goto SALTER;
case '4': /* change palantir */
prompt = "palantir";
bptr = &playerp->p_palantir;
goto BALTER;
case '5': /* change blessing */
prompt = "blessing";
bptr = &playerp->p_blessing;
goto BALTER;
case '6': /* change virgin */
prompt = "virgin";
bptr = &playerp->p_virgin;
goto BALTER;
case '7': /* change blindness */
prompt = "blindness";
bptr = &playerp->p_blindness;
goto BALTER;
case '8': /* change ring type */
prompt = "ring-type";
sptr = &playerp->p_ring.ring_type;
goto SALTER;
case '9': /* change ring duration */
prompt = "ring-duration";
sptr = &playerp->p_ring.ring_duration;
goto SALTER;
case '!': /* quit, update */
if (Wizard &&
(!ingameflag || playerp != &Player))
/* turn off status if not modifying self */
{
playerp->p_status = S_OFF;
playerp->p_tampered = T_OFF;
}
writerecord(playerp, loc);
clear();
return;
case '?': /* delete player */
if (ingameflag && playerp == &Player)
/* cannot delete self */
continue;
freerecord(playerp, loc);
clear();
return;
default:
continue;
}
DALTER:
mvprintw(23, 0, "%s = %f; %s = ", prompt, *dptr, prompt);
dtemp = infloat();
if (dtemp != 0.0)
*dptr = dtemp;
continue;
SALTER:
mvprintw(23, 0, "%s = %d; %s = ", prompt, *sptr, prompt);
dtemp = infloat();
if (dtemp != 0.0)
*sptr = (short) dtemp;
continue;
BALTER:
mvprintw(23, 0, "%s = %c; %s = ", prompt, flag[(int)*bptr],
prompt);
c = getanswer("\nTF", TRUE);
if (c == 'T')
*bptr = TRUE;
else
if (c == 'F')
*bptr = FALSE;
continue;
}
}
void
monstlist()
{
int count = 0; /* count in file */
puts(" #) Name Str Brain Quick Energy Exper Treas Type Flock%\n");
fseek(Monstfp, 0L, 0);
while (fread((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp) == 1)
printf("%2d) %-20.20s%4.0f %4.0f %2.0f %5.0f %5.0f %2d %2d %3.0f\n", count++,
Curmonster.m_name, Curmonster.m_strength, Curmonster.m_brains,
Curmonster.m_speed, Curmonster.m_energy, Curmonster.m_experience,
Curmonster.m_treasuretype, Curmonster.m_type, Curmonster.m_flock);
}
void
scorelist()
{
struct scoreboard sbuf; /* for reading entries */
FILE *fp; /* to open the file */
if ((fp = fopen(_PATH_SCORE, "r")) != NULL) {
while (fread((char *) &sbuf, SZ_SCORESTRUCT, 1, fp) == 1)
printf("%-20s (%-9s) Level: %6.0f Type: %s\n",
sbuf.sb_name, sbuf.sb_login, sbuf.sb_level, sbuf.sb_type);
fclose(fp);
}
}
void
activelist()
{
fseek(Playersfp, 0L, 0);
printf("Current characters on file are:\n\n");
while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
if (Other.p_status != S_NOTUSED)
printf("%-20s (%-9s) Level: %6.0f %s (%s)\n",
Other.p_name, Other.p_login, Other.p_level,
descrtype(&Other, FALSE), descrstatus(&Other));
}
void
purgeoldplayers()
{
int today; /* day of year for today */
int daysold; /* how many days since the character has been
* used */
time_t ltime; /* time in seconds */
long loc = 0L; /* location in file */
time(&ltime);
today = localtime(&ltime)->tm_yday;
for (;;) {
fseek(Playersfp, loc, 0);
if (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) != 1)
break;
daysold = today - Other.p_lastused;
if (daysold < 0)
daysold += 365;
if (daysold > N_DAYSOLD)
/* player hasn't been used in a while; delete */
freerecord(&Other, loc);
loc += SZ_PLAYERSTRUCT;
}
}
void
enterscore()
{
struct scoreboard sbuf; /* buffer to read in scoreboard entries */
FILE *fp; /* to open scoreboard file */
long loc = 0L; /* location in scoreboard file */
bool found = FALSE; /* set if we found an entry for this login */
if ((fp = fopen(_PATH_SCORE, "r+")) != NULL) {
while (fread((char *) &sbuf, SZ_SCORESTRUCT, 1, fp) == 1)
if (strcmp(Player.p_login, sbuf.sb_login) == 0) {
found = TRUE;
break;
} else
loc += SZ_SCORESTRUCT;
} else {
error(_PATH_SCORE);
/* NOTREACHED */
}
/*
* At this point, 'loc' will either indicate a point beyond
* the end of file, or the place where the previous entry
* was found.
*/
if ((!found) || Player.p_level > sbuf.sb_level)
/* put new entry in for this login */
{
strcpy(sbuf.sb_login, Player.p_login);
strcpy(sbuf.sb_name, Player.p_name);
sbuf.sb_level = Player.p_level;
strcpy(sbuf.sb_type, descrtype(&Player, TRUE));
}
/* update entry */
fseek(fp, loc, 0);
fwrite((char *) &sbuf, SZ_SCORESTRUCT, 1, fp);
fclose(fp);
}

22
phantasia/include.h Normal file
View File

@@ -0,0 +1,22 @@
/* $NetBSD: include.h,v 1.4 1997/10/13 02:18:19 lukem Exp $ */
/*
* include.h - includes all important files for Phantasia
*/
#include <ctype.h>
#include <curses.h>
#include <errno.h>
#include <math.h>
#include <setjmp.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "macros.h"
#include "phantdefs.h"
#include "phantstruct.h"
#include "phantglobs.h"
#include "pathnames.h"

887
phantasia/interplayer.c Normal file
View File

@@ -0,0 +1,887 @@
/* $NetBSD: interplayer.c,v 1.3 1997/10/13 02:18:22 lukem Exp $ */
/*
* interplayer.c - player to player routines for Phantasia
*/
#include "include.h"
void
checkbattle()
{
long foeloc = 0L; /* location in file of person to fight */
Users = 0;
fseek(Playersfp, 0L, 0);
while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) {
if (Other.p_status != S_OFF
&& Other.p_status != S_NOTUSED
&& Other.p_status != S_HUNGUP
&& (Other.p_status != S_CLOAKED || Other.p_specialtype != SC_VALAR))
/* player is on and not a cloaked valar */
{
++Users;
if (Player.p_x == Other.p_x
&& Player.p_y == Other.p_y
/* same coordinates */
&& foeloc != Fileloc
/* not self */
&& Player.p_status == S_PLAYING
&& (Other.p_status == S_PLAYING || Other.p_status == S_INBATTLE)
/* both are playing */
&& Other.p_specialtype != SC_VALAR
&& Player.p_specialtype != SC_VALAR)
/* neither is valar */
{
battleplayer(foeloc);
return;
}
}
foeloc += SZ_PLAYERSTRUCT;
}
}
void
battleplayer(foeplace)
long foeplace;
{
double dtemp; /* for temporary calculations */
double oldhits = 0.0; /* previous damage inflicted by foe */
int loop; /* for timing out */
int ch; /* input */
short oldtampered; /* old value of foe's p_tampered */
Lines = 8;
Luckout = FALSE;
mvaddstr(4, 0, "Preparing for battle!\n");
refresh();
#ifdef SYS5
flushinp();
#endif
/* set up variables, file, etc. */
Player.p_status = S_INBATTLE;
Shield = Player.p_energy;
/* if p_tampered is not 0, someone else may try to change it (king,
* etc.) */
Player.p_tampered = oldtampered = 1;
Player.p_1scratch = 0.0;
Player.p_istat = I_OFF;
readrecord(&Other, foeplace);
if (fabs(Player.p_level - Other.p_level) > 20.0)
/* see if players are greatly mismatched */
{
dtemp = (Player.p_level - Other.p_level) / MAX(Player.p_level, Other.p_level);
if (dtemp < -0.5)
/* foe outweighs this one */
Player.p_speed *= 2.0;
}
writerecord(&Player, Fileloc); /* write out all our info */
if (Player.p_blindness)
Enemyname = "someone";
else
Enemyname = Other.p_name;
mvprintw(6, 0, "You have encountered %s Level: %.0f\n", Enemyname, Other.p_level);
refresh();
for (loop = 0; Other.p_status != S_INBATTLE && loop < 30; ++loop)
/* wait for foe to respond */
{
readrecord(&Other, foeplace);
sleep(1);
}
if (Other.p_status != S_INBATTLE)
/* foe did not respond */
{
mvprintw(5, 0, "%s is not responding.\n", Enemyname);
goto LEAVE;
}
/* else, we are ready to battle */
move(4, 0);
clrtoeol();
/*
* determine who is first master
* if neither player is faster, check level
* if neither level is greater, battle is not allowed
* (this should never happen, but we have to handle it)
*/
if (Player.p_speed > Other.p_speed)
Foestrikes = FALSE;
else
if (Other.p_speed > Player.p_speed)
Foestrikes = TRUE;
else
if (Player.p_level > Other.p_level)
Foestrikes = FALSE;
else
if (Other.p_level > Player.p_level)
Foestrikes = TRUE;
else
/* no one is faster */
{
printw("You can't fight %s yet.", Enemyname);
goto LEAVE;
}
for (;;) {
displaystats();
readmessage();
mvprintw(1, 26, "%20.0f", Shield); /* overprint energy */
if (!Foestrikes)
/* take action against foe */
myturn();
else
/* wait for foe to take action */
{
mvaddstr(4, 0, "Waiting...\n");
clrtoeol();
refresh();
for (loop = 0; loop < 20; ++loop)
/* wait for foe to act */
{
readrecord(&Other, foeplace);
if (Other.p_1scratch != oldhits)
/* p_1scratch changes to indicate
* action */
break;
else
/* wait and try again */
{
sleep(1);
addch('.');
refresh();
}
}
if (Other.p_1scratch == oldhits) {
/* timeout */
mvaddstr(22, 0, "Timeout: waiting for response. Do you want to wait ? ");
ch = getanswer("NY", FALSE);
move(22, 0);
clrtobot();
if (ch == 'Y')
continue;
else
break;
} else
/* foe took action */
{
switch (Other.p_istat) {
case I_RAN: /* foe ran away */
mvprintw(Lines++, 0, "%s ran away!", Enemyname);
break;
case I_STUCK: /* foe tried to run, but
* couldn't */
mvprintw(Lines++, 0, "%s tried to run away.", Enemyname);
break;
case I_BLEWIT: /* foe tried to luckout, but
* didn't */
mvprintw(Lines++, 0, "%s tried to luckout!", Enemyname);
break;
default:
dtemp = Other.p_1scratch - oldhits;
mvprintw(Lines++, 0, "%s hit you %.0f times!", Enemyname, dtemp);
Shield -= dtemp;
break;
}
oldhits = Other.p_1scratch; /* keep track of old
* hits */
if (Other.p_tampered != oldtampered)
/* p_tampered changes to relinquish
* turn */
{
oldtampered = Other.p_tampered;
Foestrikes = FALSE;
}
}
}
/* decide what happens next */
refresh();
if (Lines > LINES - 2) {
more(Lines);
move(Lines = 8, 0);
clrtobot();
}
if (Other.p_istat == I_KILLED || Shield < 0.0)
/* we died */
{
Shield = -2.0; /* insure this value is negative */
break;
}
if (Player.p_istat == I_KILLED)
/* we killed foe; award treasre */
{
mvprintw(Lines++, 0, "You killed %s!", Enemyname);
Player.p_experience += Other.p_experience;
Player.p_crowns += (Player.p_level < 1000.0) ? Other.p_crowns : 0;
Player.p_amulets += Other.p_amulets;
Player.p_charms += Other.p_charms;
collecttaxes(Other.p_gold, Other.p_gems);
Player.p_sword = MAX(Player.p_sword, Other.p_sword);
Player.p_shield = MAX(Player.p_shield, Other.p_shield);
Player.p_quksilver = MAX(Player.p_quksilver, Other.p_quksilver);
if (Other.p_virgin && !Player.p_virgin) {
mvaddstr(Lines++, 0, "You have rescued a virgin. Will you be honorable ? ");
if ((ch = getanswer("YN", FALSE)) == 'Y')
Player.p_virgin = TRUE;
else {
++Player.p_sin;
Player.p_experience += 8000.0;
}
}
sleep(3); /* give other person time to die */
break;
} else
if (Player.p_istat == I_RAN || Other.p_istat == I_RAN)
/* either player ran away */
break;
}
LEAVE:
/* clean up things and leave */
writerecord(&Player, Fileloc); /* update a final time */
altercoordinates(0.0, 0.0, A_NEAR); /* move away from battle site */
Player.p_energy = Shield; /* set energy to actual value */
Player.p_tampered = T_OFF; /* clear p_tampered */
more(Lines); /* pause */
move(4, 0);
clrtobot(); /* clear bottom area of screen */
if (Player.p_energy < 0.0)
/* we are dead */
death("Interterminal battle");
}
void
myturn()
{
double dtemp; /* for temporary calculations */
int ch; /* input */
mvaddstr(7, 0, "1:Fight 2:Run Away! 3:Power Blast ");
if (Luckout)
clrtoeol();
else
addstr("4:Luckout ");
ch = inputoption();
move(Lines = 8, 0);
clrtobot();
switch (ch) {
default: /* fight */
dtemp = ROLL(2.0, Player.p_might);
HIT:
mvprintw(Lines++, 0, "You hit %s %.0f times!", Enemyname, dtemp);
Player.p_sin += 0.5;
Player.p_1scratch += dtemp;
Player.p_istat = I_OFF;
break;
case '2': /* run away */
Player.p_1scratch -= 1.0; /* change this to indicate
* action */
if (drandom() > 0.25) {
mvaddstr(Lines++, 0, "You got away!");
Player.p_istat = I_RAN;
} else {
mvprintw(Lines++, 0, "%s is still after you!", Enemyname);
Player.p_istat = I_STUCK;
}
break;
case '3': /* power blast */
dtemp = MIN(Player.p_mana, Player.p_level * 5.0);
Player.p_mana -= dtemp;
dtemp *= (drandom() + 0.5) * Player.p_magiclvl * 0.2 + 2.0;
mvprintw(Lines++, 0, "You blasted %s !", Enemyname);
goto HIT;
case '4': /* luckout */
if (Luckout || drandom() > 0.1) {
if (Luckout)
mvaddstr(Lines++, 0, "You already tried that!");
else {
mvaddstr(Lines++, 0, "Not this time . . .");
Luckout = TRUE;
}
Player.p_1scratch -= 1.0;
Player.p_istat = I_BLEWIT;
} else {
mvaddstr(Lines++, 0, "You just lucked out!");
Player.p_1scratch = Other.p_energy * 1.1;
}
break;
}
refresh();
Player.p_1scratch = floor(Player.p_1scratch); /* clean up any mess */
if (Player.p_1scratch > Other.p_energy)
Player.p_istat = I_KILLED;
else
if (drandom() * Player.p_speed < drandom() * Other.p_speed)
/* relinquish control */
{
++Player.p_tampered;
Foestrikes = TRUE;
}
writerecord(&Player, Fileloc); /* let foe know what we did */
}
void
checktampered()
{
long loc = 0L; /* location in energy void file */
/* first check for energy voids */
fseek(Energyvoidfp, 0L, 0);
while (fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp) == 1)
if (Enrgyvoid.ev_active
&& Enrgyvoid.ev_x == Player.p_x
&& Enrgyvoid.ev_y == Player.p_y)
/* sitting on one */
{
if (loc > 0L)
/* not the holy grail; inactivate energy void */
{
Enrgyvoid.ev_active = FALSE;
writevoid(&Enrgyvoid, loc);
tampered(T_NRGVOID, 0.0, 0.0);
} else
if (Player.p_status != S_CLOAKED)
/* holy grail */
tampered(T_GRAIL, 0.0, 0.0);
break;
} else
loc += SZ_VOIDSTRUCT;
/* now check for other things */
readrecord(&Other, Fileloc);
if (Other.p_tampered != T_OFF)
tampered(Other.p_tampered, Other.p_1scratch, Other.p_2scratch);
}
void
tampered(what, arg1, arg2)
int what;
double arg1;
double arg2;
{
long loc; /* location in file of other players */
Changed = TRUE;
move(4, 0);
Player.p_tampered = T_OFF; /* no longer tampered with */
switch (what) {
case T_NRGVOID:
addstr("You've hit an energy void !\n");
Player.p_mana /= 3.0;
Player.p_energy /= 2.0;
Player.p_gold = floor(Player.p_gold / 1.25) + 0.1;
altercoordinates(0.0, 0.0, A_NEAR);
break;
case T_TRANSPORT:
addstr("The king transported you ! ");
if (Player.p_charms > 0) {
addstr("But your charm saved you. . .\n");
--Player.p_charms;
} else {
altercoordinates(0.0, 0.0, A_FAR);
addch('\n');
}
break;
case T_BESTOW:
printw("The king has bestowed %.0f gold pieces on you !\n", arg1);
Player.p_gold += arg1;
break;
case T_CURSED:
addstr("You've been cursed ! ");
if (Player.p_blessing) {
addstr("But your blessing saved you. . .\n");
Player.p_blessing = FALSE;
} else {
addch('\n');
Player.p_poison += 2.0;
Player.p_energy = 10.0;
Player.p_maxenergy *= 0.95;
Player.p_status = S_PLAYING; /* no longer cloaked */
}
break;
case T_VAPORIZED:
addstr("You have been vaporized!\n");
more(7);
death("Vaporization");
break;
case T_MONSTER:
addstr("The Valar zapped you with a monster!\n");
more(7);
encounter((int) arg1);
return;
case T_BLESSED:
addstr("The Valar has blessed you!\n");
Player.p_energy = (Player.p_maxenergy *= 1.05) + Player.p_shield;
Player.p_mana += 500.0;
Player.p_strength += 0.5;
Player.p_brains += 0.5;
Player.p_magiclvl += 0.5;
Player.p_poison = MIN(0.5, Player.p_poison);
break;
case T_RELOCATE:
addstr("You've been relocated. . .\n");
altercoordinates(arg1, arg2, A_FORCED);
break;
case T_HEAL:
addstr("You've been healed!\n");
Player.p_poison -= 0.25;
Player.p_energy = Player.p_maxenergy + Player.p_shield;
break;
case T_EXVALAR:
addstr("You are no longer Valar!\n");
Player.p_specialtype = SC_COUNCIL;
break;
case T_GRAIL:
addstr("You have found The Holy Grail!!\n");
if (Player.p_specialtype < SC_COUNCIL)
/* must be council of wise to behold grail */
{
addstr("However, you are not experienced enough to behold it.\n");
Player.p_sin *= Player.p_sin;
Player.p_mana += 1000;
} else
if (Player.p_specialtype == SC_VALAR
|| Player.p_specialtype == SC_EXVALAR) {
addstr("You have made it to the position of Valar once already.\n");
addstr("The Grail is of no more use to you now.\n");
} else {
addstr("It is now time to see if you are worthy to behold it. . .\n");
refresh();
sleep(4);
if (drandom() / 2.0 < Player.p_sin) {
addstr("You have failed!\n");
Player.p_strength =
Player.p_mana =
Player.p_energy =
Player.p_maxenergy =
Player.p_magiclvl =
Player.p_brains =
Player.p_experience =
Player.p_quickness = 1.0;
altercoordinates(1.0, 1.0, A_FORCED);
Player.p_level = 0.0;
} else {
addstr("You made to position of Valar!\n");
Player.p_specialtype = SC_VALAR;
Player.p_lives = 5;
fseek(Playersfp, 0L, 0);
loc = 0L;
while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
/* search for existing valar */
if (Other.p_specialtype == SC_VALAR
&& Other.p_status != S_NOTUSED)
/* found old valar */
{
Other.p_tampered = T_EXVALAR;
writerecord(&Other, loc);
break;
} else
loc += SZ_PLAYERSTRUCT;
}
}
/* move grail to new location */
Enrgyvoid.ev_active = TRUE;
Enrgyvoid.ev_x = ROLL(-1.0e6, 2.0e6);
Enrgyvoid.ev_y = ROLL(-1.0e6, 2.0e6);
writevoid(&Enrgyvoid, 0L);
break;
}
refresh();
sleep(2);
}
void
userlist(ingameflag)
bool ingameflag;
{
int numusers = 0; /* number of users on file */
if (ingameflag && Player.p_blindness) {
mvaddstr(8, 0, "You cannot see anyone.\n");
return;
}
fseek(Playersfp, 0L, 0);
mvaddstr(8, 0,
"Name X Y Lvl Type Login Status\n");
while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) {
if (Other.p_status == S_NOTUSED
/* record is unused */
|| (Other.p_specialtype == SC_VALAR && Other.p_status == S_CLOAKED))
/* cloaked valar */
{
if (!Wizard)
/* wizard can see everything on file */
continue;
}
++numusers;
if (ingameflag &&
/* must be playing for the rest of these conditions */
(Player.p_specialtype >= SC_KING
/* kings and higher can see others */
|| Other.p_specialtype >= SC_KING
/* kings and higher can be seen by others */
|| Circle >= CIRCLE(Other.p_x, Other.p_y)
/* those nearer the origin can be seen */
|| Player.p_palantir)
/* palantir enables one to see others */
&& (Other.p_status != S_CLOAKED
|| (Player.p_specialtype == SC_VALAR && Player.p_palantir))
/* not cloaked; valar can see through cloak with a palantir */
&& Other.p_specialtype != SC_VALAR)
/* not a valar */
/* coordinates should be printed */
printw("%-20s %8.0f %8.0f ",
Other.p_name, Other.p_x, Other.p_y);
else
/* cannot see player's coordinates */
printw("%-20s %19.19s ",
Other.p_name, descrlocation(&Other, TRUE));
printw("%6.0f %s %-9.9s%s\n", Other.p_level, descrtype(&Other, TRUE),
Other.p_login, descrstatus(&Other));
if ((numusers % (LINES - 10)) == 0) {
more(LINES - 1);
move(9, 0);
clrtobot();
}
}
printw("Total players on file = %d\n", numusers);
refresh();
}
void
throneroom()
{
FILE *fp; /* to clear energy voids */
long loc = 0L; /* location of old king in player file */
if (Player.p_specialtype < SC_KING)
/* not already king -- assumes crown */
{
fseek(Playersfp, 0L, 0);
while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
if (Other.p_specialtype == SC_KING && Other.p_status != S_NOTUSED)
/* found old king */
{
if (Other.p_status != S_OFF)
/* old king is playing */
{
mvaddstr(4, 0, "The king is playing, so you cannot steal his throne\n");
altercoordinates(0.0, 0.0, A_NEAR);
move(6, 0);
return;
} else
/* old king is not playing - remove
* him/her */
{
Other.p_specialtype = SC_NONE;
if (Other.p_crowns)
--Other.p_crowns;
writerecord(&Other, loc);
break;
}
} else
loc += SZ_PLAYERSTRUCT;
/* make player new king */
Changed = TRUE;
Player.p_specialtype = SC_KING;
mvaddstr(4, 0, "You have become king!\n");
/* let everyone else know */
fp = fopen(_PATH_MESS, "w");
fprintf(fp, "All hail the new king!");
fclose(fp);
/* clear all energy voids; retain location of holy grail */
fseek(Energyvoidfp, 0L, 0);
fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp);
fp = fopen(_PATH_VOID, "w");
fwrite((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, fp);
fclose(fp);
}
mvaddstr(6, 0, "0:Decree ");
}
void
dotampered()
{
short tamper; /* value for tampering with other players */
char *option; /* pointer to option description */
double temp1 = 0.0, temp2 = 0.0; /* other tampering values */
int ch; /* input */
long loc; /* location in energy void file */
FILE *fp; /* for opening gold file */
move(6, 0);
clrtoeol();
if (Player.p_specialtype < SC_COUNCIL && !Wizard)
/* king options */
{
addstr("1:Transport 2:Curse 3:Energy Void 4:Bestow 5:Collect Taxes ");
ch = getanswer(" ", TRUE);
move(6, 0);
clrtoeol();
move(4, 0);
switch (ch) {
case '1': /* transport someone */
tamper = T_TRANSPORT;
option = "transport";
break;
case '2': /* curse another */
tamper = T_CURSED;
option = "curse";
break;
case '3': /* create energy void */
if ((loc = allocvoid()) > 20L * (long)SZ_VOIDSTRUCT)
/* can only have 20 void active at once */
mvaddstr(5, 0, "Sorry, void creation limit reached.\n");
else {
addstr("Enter the X Y coordinates of void ? ");
getstring(Databuf, SZ_DATABUF);
sscanf(Databuf, "%lf %lf", &temp1, &temp2);
Enrgyvoid.ev_x = floor(temp1);
Enrgyvoid.ev_y = floor(temp2);
Enrgyvoid.ev_active = TRUE;
writevoid(&Enrgyvoid, loc);
mvaddstr(5, 0, "It is done.\n");
}
return;
case '4': /* bestow gold to subject */
tamper = T_BESTOW;
addstr("How much gold to bestow ? ");
temp1 = infloat();
if (temp1 > Player.p_gold || temp1 < 0) {
mvaddstr(5, 0, "You don't have that !\n");
return;
}
/* adjust gold after we are sure it will be given to
* someone */
option = "give gold to";
break;
case '5': /* collect accumulated taxes */
if ((fp = fopen(_PATH_GOLD, "r+")) != NULL)
/* collect taxes */
{
fread((char *) &temp1, sizeof(double), 1, fp);
fseek(fp, 0L, 0);
/* clear out value */
temp2 = 0.0;
fwrite((char *) &temp2, sizeof(double), 1, fp);
fclose(fp);
}
mvprintw(4, 0, "You have collected %.0f in gold.\n", temp1);
Player.p_gold += floor(temp1);
return;
default:
return;
}
/* end of king options */
} else
/* council of wise, valar, wizard options */
{
addstr("1:Heal ");
if (Player.p_palantir || Wizard)
addstr("2:Seek Grail ");
if (Player.p_specialtype == SC_VALAR || Wizard)
addstr("3:Throw Monster 4:Relocate 5:Bless ");
if (Wizard)
addstr("6:Vaporize ");
ch = getanswer(" ", TRUE);
if (!Wizard) {
if (ch > '2' && Player.p_specialtype != SC_VALAR) {
ILLCMD();
return;
}
if (Player.p_mana < MM_INTERVENE) {
mvaddstr(5, 0, "No mana left.\n");
return;
} else
Player.p_mana -= MM_INTERVENE;
}
switch (ch) {
case '1': /* heal another */
tamper = T_HEAL;
option = "heal";
break;
case '2': /* seek grail */
if (Player.p_palantir)
/* need a palantir to seek */
{
fseek(Energyvoidfp, 0L, 0);
fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp);
temp1 = distance(Player.p_x, Enrgyvoid.ev_x, Player.p_y, Enrgyvoid.ev_y);
temp1 += ROLL(-temp1 / 10.0, temp1 / 5.0); /* add some error */
mvprintw(5, 0, "The palantir says the Grail is about %.0f away.\n", temp1);
} else
/* no palantir */
mvaddstr(5, 0, "You need a palantir to seek the Grail.\n");
return;
case '3': /* lob monster at someone */
mvaddstr(4, 0, "Which monster [0-99] ? ");
temp1 = infloat();
temp1 = MAX(0.0, MIN(99.0, temp1));
tamper = T_MONSTER;
option = "throw a monster at";
break;
case '4': /* move another player */
mvaddstr(4, 0, "New X Y coordinates ? ");
getstring(Databuf, SZ_DATABUF);
sscanf(Databuf, "%lf %lf", &temp1, &temp2);
tamper = T_RELOCATE;
option = "relocate";
break;
case '5': /* bless a player */
tamper = T_BLESSED;
option = "bless";
break;
case '6': /* kill off a player */
if (Wizard) {
tamper = T_VAPORIZED;
option = "vaporize";
break;
} else
return;
default:
return;
}
/* adjust age after we are sure intervention will be done */
/* end of valar, etc. options */
}
for (;;)
/* prompt for player to affect */
{
mvprintw(4, 0, "Who do you want to %s ? ", option);
getstring(Databuf, SZ_DATABUF);
truncstring(Databuf);
if (Databuf[0] == '\0')
userlist(TRUE);
else
break;
}
if (strcmp(Player.p_name, Databuf) != 0)
/* name other than self */
{
if ((loc = findname(Databuf, &Other)) >= 0L) {
if (Other.p_tampered != T_OFF) {
mvaddstr(5, 0, "That person has something pending already.\n");
return;
} else {
if (tamper == T_RELOCATE
&& CIRCLE(temp1, temp2) < CIRCLE(Other.p_x, Other.p_y)
&& !Wizard)
mvaddstr(5, 0, "Cannot move someone closer to the Lord's Chamber.\n");
else {
if (tamper == T_BESTOW)
Player.p_gold -= floor(temp1);
if (!Wizard && (tamper == T_HEAL || tamper == T_MONSTER ||
tamper == T_RELOCATE || tamper == T_BLESSED))
Player.p_age += N_AGE; /* age penalty */
Other.p_tampered = tamper;
Other.p_1scratch = floor(temp1);
Other.p_2scratch = floor(temp2);
writerecord(&Other, loc);
mvaddstr(5, 0, "It is done.\n");
}
return;
}
} else
/* player not found */
mvaddstr(5, 0, "There is no one by that name.\n");
} else
/* self */
mvaddstr(5, 0, "You may not do it to yourself!\n");
}
void
writevoid(vp, loc)
struct energyvoid *vp;
long loc;
{
fseek(Energyvoidfp, loc, 0);
fwrite((char *) vp, SZ_VOIDSTRUCT, 1, Energyvoidfp);
fflush(Energyvoidfp);
fseek(Energyvoidfp, 0L, 0);
}
long
allocvoid()
{
long loc = 0L; /* location of new energy void */
fseek(Energyvoidfp, 0L, 0);
while (fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp) == 1)
if (Enrgyvoid.ev_active)
loc += SZ_VOIDSTRUCT;
else
break;
return (loc);
}

244
phantasia/io.c Normal file
View File

@@ -0,0 +1,244 @@
/* $NetBSD: io.c,v 1.3 1997/10/13 02:18:25 lukem Exp $ */
/*
* io.c - input/output routines for Phantasia
*/
#include "include.h"
void
getstring(cp, mx)
char *cp;
int mx;
{
char *inptr; /* pointer into string for next string */
int x, y; /* original x, y coordinates on screen */
int ch; /* input */
getyx(stdscr, y, x); /* get coordinates on screen */
inptr = cp;
*inptr = '\0'; /* clear string to start */
--mx; /* reserve room in string for nul terminator */
do
/* get characters and process */
{
if (Echo)
mvaddstr(y, x, cp); /* print string on screen */
clrtoeol(); /* clear any data after string */
refresh(); /* update screen */
ch = getchar(); /* get character */
switch (ch) {
case CH_ERASE: /* back up one character */
if (inptr > cp)
--inptr;
break;
case CH_KILL: /* back up to original location */
inptr = cp;
break;
case CH_NEWLINE: /* terminate string */
break;
case CH_REDRAW:/* redraw screen */
clearok(stdscr, TRUE);
continue;
default: /* put data in string */
if (ch >= ' ' || Wizard)
/* printing char; put in string */
*inptr++ = ch;
}
*inptr = '\0'; /* terminate string */
}
while (ch != CH_NEWLINE && inptr < cp + mx);
}
void
more(where)
int where;
{
mvaddstr(where, 0, "-- more --");
getanswer(" ", FALSE);
}
double
infloat()
{
double result; /* return value */
getstring(Databuf, SZ_DATABUF);
if (sscanf(Databuf, "%lf", &result) < 1)
/* no valid number entered */
result = 0.0;
return (result);
}
int
inputoption()
{
++Player.p_age; /* increase age */
if (Player.p_ring.ring_type != R_SPOILED)
/* ring ok */
return (getanswer("T ", TRUE));
else
/* bad ring */
{
getanswer(" ", TRUE);
return ((int) ROLL(0.0, 5.0) + '0');
}
}
void
interrupt()
{
char line[81]; /* a place to store data already on screen */
int loop; /* counter */
int x, y; /* coordinates on screen */
int ch; /* input */
unsigned savealarm; /* to save alarm value */
#ifdef SYS3
signal(SIGINT, SIG_IGN);
#endif
#ifdef SYS5
signal(SIGINT, SIG_IGN);
#endif
savealarm = alarm(0); /* turn off any alarms */
getyx(stdscr, y, x); /* save cursor location */
for (loop = 0; loop < 80; ++loop) { /* save line on screen */
move(4, loop);
line[loop] = inch();
}
line[80] = '\0'; /* nul terminate */
if (Player.p_status == S_INBATTLE || Player.p_status == S_MONSTER)
/* in midst of fighting */
{
mvaddstr(4, 0, "Quitting now will automatically kill your character. Still want to ? ");
ch = getanswer("NY", FALSE);
if (ch == 'Y')
death("Bailing out");
/* NOTREACHED */
} else {
mvaddstr(4, 0, "Do you really want to quit ? ");
ch = getanswer("NY", FALSE);
if (ch == 'Y')
leavegame();
/* NOTREACHED */
}
mvaddstr(4, 0, line); /* restore data on screen */
move(y, x); /* restore cursor */
refresh();
#ifdef SYS3
signal(SIGINT, interrupt);
#endif
#ifdef SYS5
signal(SIGINT, interrupt);
#endif
alarm(savealarm); /* restore alarm */
}
int
getanswer(choices, def)
char *choices;
bool def;
{
int ch; /* input */
volatile int loop; /* counter */
volatile int oldx, oldy; /* original coordinates on screen */
getyx(stdscr, oldy, oldx);
alarm(0); /* make sure alarm is off */
for (loop = 3; loop; --loop)
/* try for 3 times */
{
if (setjmp(Timeoenv) != 0)
/* timed out waiting for response */
{
if (def || loop <= 1)
/* return default answer */
break;
else
/* prompt, and try again */
goto YELL;
} else
/* wait for response */
{
clrtoeol();
refresh();
#ifdef BSD41
sigset(SIGALRM, catchalarm);
#else
signal(SIGALRM, catchalarm);
#endif
/* set timeout */
if (Timeout)
alarm(7); /* short */
else
alarm(600); /* long */
ch = getchar();
alarm(0); /* turn off timeout */
if (ch < 0)
/* caught some signal */
{
++loop;
continue;
} else
if (ch == CH_REDRAW)
/* redraw screen */
{
clearok(stdscr, TRUE); /* force clear screen */
++loop; /* don't count this input */
continue;
} else
if (Echo) {
addch(ch); /* echo character */
refresh();
}
if (islower(ch))
/* convert to upper case */
ch = toupper(ch);
if (def || strchr(choices, ch) != NULL)
/* valid choice */
return (ch);
else
if (!def && loop > 1)
/* bad choice; prompt, and try again */
{
YELL: mvprintw(oldy + 1, 0, "Please choose one of : [%s]\n", choices);
move(oldy, oldx);
clrtoeol();
continue;
} else
/* return default answer */
break;
}
}
return (*choices);
}
void
catchalarm(dummy)
int dummy __attribute__((unused));
{
longjmp(Timeoenv, 1);
}

20
phantasia/macros.h Normal file
View File

@@ -0,0 +1,20 @@
/* $NetBSD: macros.h,v 1.3 1995/04/24 12:24:34 cgd Exp $ */
/*
* macros.h - macro definitions for Phantasia
*/
#define ROLL(BASE,INTERVAL) floor((BASE) + (INTERVAL) * drandom())
#define SGN(X) ((X) < 0 ? -1 : 1)
#define CIRCLE(X, Y) floor(distance(X, 0.0, Y, 0.0) / 125.0 + 1)
#undef MAX
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#undef MIN
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define ILLCMD() mvaddstr(5, 0, Illcmd)
#define MAXMOVE() (Player.p_level * 1.5 + 1)
#define ILLMOVE() mvaddstr(5, 0, Illmove)
#define ILLSPELL() mvaddstr(5, 0, Illspell)
#define NOMANA() mvaddstr(5, 0, Nomana)
#define SOMEBETTER() addstr(Somebetter)
#define NOBETTER() mvaddstr(17, 0, Nobetter)

1015
phantasia/main.c Normal file

File diff suppressed because it is too large Load Diff

162
phantasia/map.c Normal file
View File

@@ -0,0 +1,162 @@
/* $NetBSD: map.c,v 1.2 1995/03/24 03:58:58 cgd Exp $ */
#define minusminus plusplus
#define minusplus plusminus
main()
{
/* Set up */
openpl();
space(-1400, -1000, 1200, 1200);
/* Big box */
move(-1400, -1000);
cont(-1400, 1000);
cont(600, 1000);
cont(600, -1000);
cont(-1400, -1000);
/* Grid -- horizontal lines every 200 */
linemod("dotted");
line(600, -800, -1400, -800);
line(-1400, -600, 600, -600);
line(600, -400, -1400, -400);
line(-1400, -200, 600, -200);
linemod("solid");
line(600, 0, -1400, 0);
linemod("dotted");
line(-1400, 200, 600, 200);
line(600, 400, -1400, 400);
line(-1400, 600, 600, 600);
line(600, 800, -1400, 800);
/* Grid -- vertical lines every 200 */
line(-1200, 1000, -1200, -1000);
line(-1000, 1000, -1000, -1000);
line(-800, 1000, -800, -1000);
line(-600, 1000, -600, -1000);
linemod("solid");
line(-400, 1000, -400, -1000);
linemod("dotted");
line(-200, 1000, -200, -1000);
line(0, 1000, 0, -1000);
line(200, 1000, 200, -1000);
line(400, 1000, 400, -1000);
/* Circles radius +250 on "center" */
linemod("solid");
circle(-400, 0, 250);
circle(-400, 0, 500);
circle(-400, 0, 750);
circle(-400, 0, 1000);
/* A few labels */
move(-670, 1075);
label("- THE PHANTASIA UNIVERSE -");
line(-630, 1045, -115, 1045);
move(-360, 80);
label("Lorien");
move(-385, -100);
label("Ithilien");
move(-560, 80);
label("Rohan");
move(-580, -100);
label("Anorien");
plusplus("Rovanion", -250, 320);
plusplus("The Iron Hills", -100, 560);
plusplus("Rhun", 250, 570);
minusplus("Dunland", -700, 160);
minusplus("Eriador", -920, 300);
minusplus("The Northern Waste", -1240, 320);
minusminus("Gondor", -720, -180);
minusminus("South Gondor", -940, -270);
minusminus("Far Harad", -1100, -500);
plusminus("Mordor", -180, -300);
plusminus("Khand", 0, -500);
plusminus("Near Harad", 40, -780);
move(340, 900);
label("The Moors");
move(300, 840);
label("Adventurous");
move(340, -840);
label("The Moors");
move(300, -900);
label("Adventurous");
move(-1340, 900);
label("The Moors");
move(-1340, 840);
label("Adventurous");
move(-1340, -840);
label("The Moors");
move(-1340, -900);
label("Adventurous");
move(700, 1000);
label("OUTER CIRCLES:");
line(690, 970, 1000, 970);
move(700, 900);
label("> 9: The Outer Waste");
move(700, 800);
label("> 20: The Dead Marshes");
move(700, 700);
label("> 35: Kennaquhair");
move(700, 600);
label("> 55: Morannon");
move(700, 300);
label("(0,0): The Lord's Chamber");
move(700, -400);
label("Grid squares are 100 x 100");
move(700, -800);
label("Created by Ted Estes");
move(700, -860);
label("Plotted by Chris Robertson");
move(700, -920);
label(" c 1985");
circle(723, -923, 20);
/* Close down */
move(-1380, 1180);
closepl();
exit(0);
}
plusplus(s, x, y) /* draw strings in plus plus quadrant */
char *s;
int x, y;
{
char s1[2];
while (*s)
{
move(x, y);
s1[0] = *s++;
s1[1] = '\0';
label(s1);
x += 25;
y -= 30;
}
}
plusminus(s, x, y) /* draw strings in plus minus quadrant */
char *s;
int x, y;
{
char s1[2];
while (*s)
{
move(x, y);
s1[0] = *s++;
s1[1] = '\0';
label(s1);
x += 25;
y += 30;
}
}

1071
phantasia/misc.c Normal file

File diff suppressed because it is too large Load Diff

100
phantasia/monsters.asc Normal file
View File

@@ -0,0 +1,100 @@
A Water Leaper 12 14 16 24 59 0 0 62
A Leech 4 19 29 30 66 0 0 73
An Urisk 13 30 15 46 127 1 0 3
Shellycoat 28 21 18 63 226 2 0 0
A Naiad 21 62 27 58 378 2 0 11
A Nixie 22 58 28 108 604 3 0 6
A Glaistig 21 106 25 127 1002 3 0 0
A Mermaid 18 116 22 108 809 3 0 0
A Merman 24 115 23 109 808 4 0 0
A Siren 22 128 31 89 915 4 0 24
A Lamprey 14 67 33 156 1562 4 15 37
A Kopoacinth 26 36 26 206 2006 5 0 20
A Kelpie 61 25 24 223 4025 5 0 0
An Aspidchelone 114 104 19 898 10041 7 0 2
An Idiot 13 14 16 28 49 0 0 0
Some Green Slime 1 5 45 100 57 0 0 26
A Pixie 11 29 23 26 64 0 0 32
A Serpent 10 18 25 25 79 0 0 10
A Cluricaun 12 27 20 30 81 0 14 5
An Imp 22 30 14 40 92 0 0 1
A Centipede 3 8 18 15 33 0 0 61
A Beetle 2 11 21 26 44 0 0 48
A Fir Darrig 18 22 17 35 107 0 14 1
Modnar 15 23 20 40 101 7 2 12
A Gnome 7 45 26 23 111 0 0 21
A Sprite 9 37 25 31 132 1 0 43
A Mimic 11 55 29 47 213 1 3 2
A Kobold 13 10 14 21 121 1 12 68
A Spider 6 11 28 28 124 1 0 57
An Uldra 14 37 21 32 93 1 0 6
A Gnoll 20 25 15 40 166 1 0 61
A Bogie 23 28 19 57 189 1 0 57
A Fachan 9 40 15 45 139 1 14 10
A Moron 3 1 10 10 28 0 0 100
An Orc 25 13 16 26 141 1 0 92
A Ghillie Dhu 12 16 13 28 104 2 14 2
A Bogle 19 15 16 35 157 2 14 15
A Shrieker 2 62 27 9 213 2 16 0
A Carrion Crawler 12 20 20 65 142 2 0 42
A Trow 15 17 23 51 136 2 0 36
A Warg 20 10 17 45 152 2 0 88
A Stirge 2 6 35 25 153 2 0 95
A Crebain 5 11 31 31 82 2 0 81
A Killmoulis 30 19 8 75 175 3 14 22
A Hob-goblin 35 20 15 72 246 3 0 18
A Unicorn 27 57 27 57 627 3 1 0
A Fenoderee 16 6 21 65 222 3 0 42
An Ogre 42 14 16 115 409 3 0 19
A Dodo 62 12 11 76 563 3 0 3
A Hydra 14 27 33 99 599 3 0 27
A Hamadryad 23 47 26 62 426 3 0 12
A Bwca 21 17 19 55 387 3 14 1
An Owlbear 35 16 18 100 623 4 0 22
Black Annis 37 52 15 65 786 4 0 2
A Jello Blob 100 25 7 264 1257 4 0 13
A Jubjub Bird 45 23 12 114 1191 4 0 0
A Wichtlein 13 40 25 61 800 4 0 8
A Cocodrill 39 28 24 206 1438 4 0 38
A Troll 75 12 20 185 1013 4 24 29
A Bonnacon 89 26 9 255 1661 4 17 14
A Gargoyle 22 21 29 200 1753 5 0 7
A Chaladrius 8 49 37 172 1929 5 0 20
A Gwyllion 27 73 20 65 1888 5 0 4
A Cinomulgus 23 2 10 199 263 5 0 18
A Peridexion 26 32 24 98 1300 5 0 2
Smeagol 41 33 27 373 2487 5 18 0
A Wraith 52 102 22 200 3112 5 25 13
A Snotgurgle 143 19 26 525 4752 6 0 3
A Phooka 42 63 21 300 4125 5 0 12
A Vortex 101 30 31 500 6992 6 9 4
Shelob 147 64 28 628 5003 7 13 0
A Thaumaturgist 35 200 23 400 7628 6 7 0
Smaug 251 76 26 1022 9877 7 0 0
A Cold-drake 301 102 24 1222 10888 7 0 0
A Red Dragon 342 141 23 1299 11649 8 0 0
Scatha the Worm 406 208 20 1790 11999 8 0 0
Tiamat 506 381 29 2000 13001 9 11 0
A Bandersnatch 105 98 22 450 7981 6 0 3
A Harpy 103 49 24 263 7582 6 0 2
A Tigris 182 38 17 809 7777 6 0 3
A Gryphon 201 45 19 813 8888 7 0 1
A Coblynau 205 46 18 585 8333 6 0 2
A Chimaera 173 109 28 947 12006 7 0 0
A Jack-in-Irons 222 36 12 1000 9119 7 0 0
Saruman 55 373 17 1500 17101 11 6 0
A Balrog 500 100 25 705 8103 7 8 0
Argus 201 87 14 1500 10010 8 0 0
A Titan 302 1483 12 1625 11011 8 0 0
Cacus 256 43 19 1750 12012 8 0 0
Begion 403 154 10 1875 13013 8 0 0
Grendel 197 262 23 2000 14014 8 0 0
A Nazgul 250 251 26 1011 9988 12 10 9
A Succubus 186 1049 27 2007 19984 9 19 0
Red Cap 143 50 35 1965 23456 9 0 0
A Nuckelavee 300 75 20 2185 11111 8 0 0
Cerberus 236 96 29 2600 25862 9 20 0
A Jabberwock 185 136 25 2265 23256 9 22 0
Ungoliant 399 2398 37 2784 27849 10 21 0
Leanan-Sidhe 486 5432 46 3000 30004 9 5 0
The Dark Lord 9999 9999 31 19999 30005 13 4 0

56
phantasia/oldplayer.h Normal file
View File

@@ -0,0 +1,56 @@
/* $NetBSD: oldplayer.h,v 1.2 1995/03/24 03:59:09 cgd Exp $ */
/*
* oldplayer.h - old player structure
*/
struct oldplayer /* player statistics */
{
char o_name[21]; /* name */
char o_password[9]; /* password */
char o_login[10]; /* login */
double o_x; /* x coord */
double o_y; /* y coord */
double o_experience; /* experience */
int o_level; /* level */
short o_quickness; /* quickness */
double o_strength; /* strength */
double o_sin; /* sin */
double o_mana; /* mana */
double o_gold; /* gold */
double o_energy; /* energy */
double o_maxenergy; /* maximum energy */
double o_magiclvl; /* magic level */
double o_brains; /* brains */
short o_crowns; /* crowns */
struct
{
short ring_type; /* type of ring */
short ring_duration; /* duration of ring */
} o_ring; /* ring stuff */
bool o_palantir; /* palantir */
double o_poison; /* poison */
short o_holywater; /* holy water */
short o_amulets; /* amulets */
bool o_blessing; /* blessing */
short o_charms; /* charms */
double o_gems; /* gems */
short o_quksilver; /* quicksilver */
double o_sword; /* sword */
double o_shield; /* shield */
short o_type; /* character type */
bool o_virgin; /* virgin */
short o_lastused; /* day of year last used */
short o_status; /* playing, cloaked, etc. */
short o_tampered; /* decree'd, etc. flag */
double o_1scratch,
o_2scratch; /* variables used for decree, player battle */
bool o_blindness; /* blindness */
int o_notused; /* not used */
long o_age; /* age in seconds */
short o_degenerated; /* age/2500 last degenerated */
short o_istat; /* used for inter-terminal battle */
#ifdef PHANTPLUS
short o_lives;
#endif
};

46
phantasia/pathnames.h.in Normal file
View File

@@ -0,0 +1,46 @@
/* $NetBSD: pathnames.h,v 1.2 1995/03/24 03:59:17 cgd Exp $ */
/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pathnames.h 8.2 (Berkeley) 4/2/94
*/
#define _PATH_GAMEPROG "@gamesdir@/phantasia"
#define _PATH_GOLD "@phantasia_dir@/gold"
#define _PATH_LASTDEAD "@phantasia_dir@/lastdead"
#define _PATH_MESS "@phantasia_dir@/mess"
#define _PATH_MONST "@phantasia_dir@/monsters"
#define _PATH_MOTD "@phantasia_dir@/motd"
#define _PATH_PEOPLE "@phantasia_dir@/characs"
#define _PATH_SCORE "@phantasia_dir@/scoreboard"
#define _PATH_VOID "@phantasia_dir@/void"

1226
phantasia/phantasia.6 Normal file

File diff suppressed because it is too large Load Diff

150
phantasia/phantdefs.h Normal file
View File

@@ -0,0 +1,150 @@
/* $NetBSD: phantdefs.h,v 1.2 1995/03/24 03:59:28 cgd Exp $ */
/*
* phantdefs.h - important constants for Phantasia
*/
/* ring constants */
#define R_NONE 0 /* no ring */
#define R_NAZREG 1 /* regular Nazgul ring (expires) */
#define R_DLREG 2 /* regular Dark Lord ring (does not expire) */
#define R_BAD 3 /* bad ring */
#define R_SPOILED 4 /* ring which has gone bad */
/* status constants */
/* We must #undef these first since setup.c includes headers that reserve S_* */
#undef S_NOTUSED
#undef S_OFF
#undef S_PLAYING
#undef S_CLOAKED
#undef S_INBATTLE
#undef S_MONSTER
#undef S_TRADING
#undef S_HUNGUP
#define S_NOTUSED 0 /* record not in use */
#define S_OFF 1 /* not playing */
#define S_PLAYING 2 /* playing - nothing else */
#define S_CLOAKED 3 /* playing - cloaked */
#define S_INBATTLE 4 /* playing - in battle */
#define S_MONSTER 5 /* playing - fighting monster */
#define S_TRADING 6 /* playing - at a trading post */
#define S_HUNGUP 7 /* error occured with character */
/* tampered constants */
#define T_OFF 0 /* nothing */
#define T_NRGVOID 1 /* hit an energy void */
#define T_GRAIL 2 /* landed on the holy grail */
#define T_TRANSPORT 3 /* transported by king */
#define T_BESTOW 4 /* gold bestowed by king */
#define T_CURSED 5 /* cursed by king */
#define T_MONSTER 6 /* monster lobbed by valar */
#define T_BLESSED 7 /* blessed by valar */
#define T_RELOCATE 8 /* moved by valar */
#define T_HEAL 9 /* healed by valar */
#define T_VAPORIZED 10 /* vaporized by wizard */
#define T_EXVALAR 11 /* no longer valar */
/* inter-terminal battle status constants */
#define I_OFF 0 /* nothing */
#define I_RAN 1 /* ran away */
#define I_STUCK 2 /* tried to run unsuccessfully */
#define I_BLEWIT 3 /* tried to luckout unsuccessfully */
#define I_KILLED 4 /* killed foe */
/* constants for altering coordinates */
#define A_SPECIFIC 0 /* coordinates specified */
#define A_FORCED 1 /* coordinates specified, ignore Beyond */
#define A_NEAR 2 /* coordinates not specified, move near */
#define A_FAR 3 /* coordinates not specified, move far */
/* constants for character types */
#define C_MAGIC 0 /* magic user */
#define C_FIGHTER 1 /* fighter */
#define C_ELF 2 /* elf */
#define C_DWARF 3 /* dwarf */
#define C_HALFLING 4 /* halfling */
#define C_EXPER 5 /* experimento */
#define C_SUPER 6 /* super being */
/* constants for special character types */
#define SC_NONE 0 /* not a special character */
#define SC_KING 1 /* king */
#define SC_COUNCIL 2 /* council of the wise */
#define SC_VALAR 3 /* valar */
#define SC_EXVALAR 4 /* ex-valar */
/* special monster constants */
#define SM_NONE 0 /* nothing special */
#define SM_UNICORN 1 /* unicorn */
#define SM_MODNAR 2 /* Modnar */
#define SM_MIMIC 3 /* mimic */
#define SM_DARKLORD 4 /* Dark Lord */
#define SM_LEANAN 5 /* Leanan-Sidhe */
#define SM_SARUMAN 6 /* Saruman */
#define SM_THAUMATURG 7 /* thaumaturgist */
#define SM_BALROG 8 /* balrog */
#define SM_VORTEX 9 /* vortex */
#define SM_NAZGUL 10 /* nazgul */
#define SM_TIAMAT 11 /* Tiamat */
#define SM_KOBOLD 12 /* kobold */
#define SM_SHELOB 13 /* Shelob */
#define SM_FAERIES 14 /* assorted faeries */
#define SM_LAMPREY 15 /* lamprey */
#define SM_SHRIEKER 16 /* shrieker */
#define SM_BONNACON 17 /* bonnacon */
#define SM_SMEAGOL 18 /* Smeagol */
#define SM_SUCCUBUS 19 /* succubus */
#define SM_CERBERUS 20 /* Cerberus */
#define SM_UNGOLIANT 21 /* Ungoliant */
#define SM_JABBERWOCK 22 /* jabberwock */
#define SM_MORGOTH 23 /* Morgoth */
#define SM_TROLL 24 /* troll */
#define SM_WRAITH 25 /* wraith */
/* constants for spells */
#define ML_ALLORNOTHING 0.0 /* magic level for 'all or nothing' */
#define MM_ALLORNOTHING 1.0 /* mana used for 'all or nothing' */
#define ML_MAGICBOLT 5.0 /* magic level for 'magic bolt' */
#define ML_FORCEFIELD 15.0 /* magic level for 'force field' */
#define MM_FORCEFIELD 30.0 /* mana used for 'force field' */
#define ML_XFORM 25.0 /* magic level for 'transform' */
#define MM_XFORM 50.0 /* mana used for 'transform' */
#define ML_INCRMIGHT 35.0 /* magic level for 'increase might' */
#define MM_INCRMIGHT 75.0 /* mana used for 'increase might' */
#define ML_INVISIBLE 45.0 /* magic level for 'invisibility' */
#define MM_INVISIBLE 90.0 /* mana used for 'invisibility' */
#define ML_XPORT 60.0 /* magic level for 'transport' */
#define MM_XPORT 125.0 /* mana used for 'transport' */
#define ML_PARALYZE 75.0 /* magic level for 'paralyze' */
#define MM_PARALYZE 150.0 /* mana used for 'paralyze' */
#define MM_SPECIFY 1000.0 /* mana used for 'specify' */
#define ML_CLOAK 20.0 /* magic level for 'cloak' */
#define MEL_CLOAK 7.0 /* experience level for 'cloak' */
#define MM_CLOAK 35.0 /* mana used for 'cloak' */
#define ML_TELEPORT 40.0 /* magic level for 'teleport' */
#define MEL_TELEPORT 12.0 /* experience level for 'teleport' */
#define MM_INTERVENE 1000.0 /* mana used to 'intervene' */
/* some miscellaneous constants */
#define SZ_DATABUF 100 /* size of input buffer */
#define SZ_PLAYERSTRUCT sizeof(struct player) /* size of player structure */
#define SZ_VOIDSTRUCT sizeof(struct energyvoid) /* size of energy void struct */
#define SZ_SCORESTRUCT sizeof(struct scoreboard) /* size of score board entry */
#define SZ_MONSTERSTRUCT sizeof(struct monster) /* size of monster structure */
#define SZ_NAME 21 /* size of player name (incl. trailing nul) */
#define SZ_PASSWORD 9 /* size of password (incl. trailing nul) */
#define SZ_LOGIN 9 /* size of login (incl. trailing nul) */
#define N_DAYSOLD 21 /* number of days old for purge */
#define N_AGE 500 /* age to degenerate ratio */
#define N_GEMVALUE (1000.0) /* number of gold pieces to gem ratio */
#define N_TAXAMOUNT (7.0) /* tax percent */
#define D_BEYOND (1.1e6) /* distance to beyond point of no return */
#define D_EXPER (2000.0) /* distance experimentos are allowed */
#define CH_MARKDELETE '\001' /* used to alter name of deleted players */
#define CH_KILL '\030' /* kill character (ctrl-X) */
#define CH_ERASE '\010' /* erase character (ctrl-H) */
#define CH_NEWLINE '\n' /* newline */
#define CH_REDRAW '\014' /* redraw screen character (ctrl-L) */

118
phantasia/phantglobs.c Normal file
View File

@@ -0,0 +1,118 @@
/* $NetBSD: phantglobs.c,v 1.4 1998/07/27 01:12:35 mycroft Exp $ */
/*
* phantglobs.c - globals for Phantasia
*/
#include "include.h"
double Circle; /* which circle player is in */
double Shield; /* force field thrown up in monster battle */
bool Beyond; /* set if player is beyond point of no return */
bool Marsh; /* set if player is in dead marshes */
bool Throne; /* set if player is on throne */
bool Changed; /* set if important player stats have changed */
bool Wizard; /* set if player is the 'wizard' of the game */
bool Timeout; /* set if short timeout waiting for input */
bool Windows; /* set if we are set up for curses stuff */
bool Luckout; /* set if we have tried to luck out in fight */
bool Foestrikes; /* set if foe gets a chance to hit in battleplayer() */
bool Echo; /* set if echo input to terminal */
int Users; /* number of users currently playing */
int Whichmonster; /* which monster we are fighting */
int Lines; /* line on screen counter for fight routines */
jmp_buf Fightenv; /* used to jump into fight routine */
jmp_buf Timeoenv; /* used for timing out waiting for input */
long Fileloc; /* location in file of player statistics */
const char *Login; /* pointer to login of player */
char *Enemyname; /* pointer name of monster/player we are battling*/
struct player Player; /* stats for player */
struct player Other; /* stats for another player */
struct monster Curmonster;/* stats for current monster */
struct energyvoid Enrgyvoid;/* energy void buffer */
struct charstats *Statptr;/* pointer into Stattable[] */
/* lookup table for character type dependent statistics */
struct charstats Stattable[7] = {
/* MAGIC USER */
{
15.0, 200.0, 18.0, 175.0, 10,
{30, 6, 0.0}, {10, 6, 2.0}, {50, 51, 75.0},
{30, 16, 20.0}, {60, 26, 6.0}, {5, 5, 2.75}
},
/* FIGHTER */
{
10.0, 110.0, 15.0, 220.0, 20,
{30, 6, 0.0}, {40, 16, 3.0}, {30, 21, 40.0},
{45, 26, 30.0}, {25, 21, 3.0}, {3, 4, 1.5}
},
/* ELF */
{
12.0, 150.0, 17.0, 190.0, 13,
{32, 7, 0.0}, {35, 11, 2.5}, {45, 46, 65.0},
{30, 21, 25.0}, {40, 26, 4.0}, {4, 4, 2.0}
},
/* DWARF */
{ 7.0, 80.0, 13.0, 255.0, 25,
{25, 6, 0.0}, {50, 21, 5.0}, {25, 21, 30.0},
{60, 41, 35.0}, {20, 21, 2.5}, {2, 4, 1.0}
},
/* HALFLING */
{
11.0, 80.0, 10.0, 125.0, 40,
{34, 0, 0.0}, {20, 6, 2.0}, {25, 21, 30.0},
{55, 36, 30.0}, {40, 36, 4.5}, {1, 4, 1.0}
},
/* EXPERIMENTO */
{ 9.0, 90.0, 16.0, 160.0, 20,
{27, 0, 0.0}, {25, 0, 0.0}, {100, 0, 0.0},
{35, 0, 0.0}, {25, 0, 0.0}, {2, 0, 0.0}
},
/* SUPER */
{
15.0, 200.0, 10.0, 225.0, 40,
{38, 0, 0.0}, {65, 0, 5.0}, {100, 0, 75.0},
{80, 0, 35.0}, {85, 0, 6.0}, {9, 0, 2.75}
}
};
/* menu of items for purchase */
struct menuitem Menu[] = {
{"Mana", 1},
{"Shield", 5},
{"Book", 200},
{"Sword", 500},
{"Charm", 1000},
{"Quicksilver", 2500},
{"Blessing", 1000},
};
FILE *Playersfp; /* pointer to open player file */
FILE *Monstfp; /* pointer to open monster file */
FILE *Messagefp; /* pointer to open message file */
FILE *Energyvoidfp; /* pointer to open energy void file */
char Databuf[SZ_DATABUF]; /* a place to read data into */
/* some canned strings for messages */
char Illcmd[] = "Illegal command.\n";
char Illmove[] = "Too far.\n";
char Illspell[] = "Illegal spell.\n";
char Nomana[] = "Not enought mana for that spell.\n";
char Somebetter[] = "But you already have something better.\n";
char Nobetter[] = "That's no better than what you already have.\n";

131
phantasia/phantglobs.h Normal file
View File

@@ -0,0 +1,131 @@
/* $NetBSD: phantglobs.h,v 1.5 1998/07/27 01:12:35 mycroft Exp $ */
/*
* phantglobs.h - global declarations for Phantasia
*/
extern double Circle; /* which circle player is in */
extern double Shield; /* force field thrown up in monster battle */
extern bool Beyond; /* set if player is beyond point of no return */
extern bool Marsh; /* set if player is in dead marshes */
extern bool Throne; /* set if player is on throne */
extern bool Changed; /* set if important player stats have changed */
extern bool Wizard; /* set if player is the 'wizard' of the game */
extern bool Timeout; /* set if short timeout waiting for input */
extern bool Windows; /* set if we are set up for curses stuff */
extern bool Luckout; /* set if we have tried to luck out in fight */
extern bool Foestrikes; /* set if foe gets a chance to hit in battleplayer()*/
extern bool Echo; /* set if echo input to terminal */
extern int Users; /* number of users currently playing */
extern int Whichmonster; /* which monster we are fighting */
extern int Lines; /* line on screen counter for fight routines */
extern jmp_buf Fightenv; /* used to jump into fight routine */
extern jmp_buf Timeoenv; /* used for timing out waiting for input */
extern long Fileloc; /* location in file of player statistics */
extern const char *Login; /* pointer to login of current player */
extern char *Enemyname; /* pointer name of monster/player we are battling*/
extern struct player Player; /* stats for player */
extern struct player Other; /* stats for another player */
extern struct monster Curmonster;/* stats for current monster */
extern struct energyvoid Enrgyvoid;/* energy void buffer */
extern struct charstats Stattable[];/* used for rolling and changing player stats*/
extern struct charstats *Statptr;/* pointer into Stattable[] */
extern struct menuitem Menu[]; /* menu of items for purchase */
extern FILE *Playersfp; /* pointer to open player file */
extern FILE *Monstfp; /* pointer to open monster file */
extern FILE *Messagefp; /* pointer to open message file */
extern FILE *Energyvoidfp; /* pointer to open energy void file */
extern char Databuf[]; /* a place to read data into */
/* some canned strings for messages */
extern char Illcmd[];
extern char Illmove[];
extern char Illspell[];
extern char Nomana[];
extern char Somebetter[];
extern char Nobetter[];
/* functions which we need to know about */
char *descrlocation __P((struct player *, bool));
char *descrstatus __P((struct player *));
char *descrtype __P((struct player *, bool));
void activelist __P((void));
void adjuststats __P((void));
long allocrecord __P((void));
long allocvoid __P((void));
void allstatslist __P((void));
void altercoordinates __P((double, double, int));
void awardtreasure __P((void));
void battleplayer __P((long));
void callmonster __P((int));
void cancelmonster __P((void));
void catchalarm __P((int));
void changestats __P((bool));
void checkbattle __P((void));
void checktampered __P((void));
void cleanup __P((int));
void collecttaxes __P((double, double));
void cursedtreasure __P((void));
void death __P((char *));
void displaystats __P((void));
double distance __P((double, double, double, double));
void dotampered __P((void));
double drandom __P((void));
void encounter __P((int));
void enterscore __P((void));
void error __P((char *));
double explevel __P((double));
long findname __P((char *, struct player *));
void freerecord __P((struct player *, long));
void genchar __P((int));
int getanswer __P((char *, bool));
void getstring __P((char *, int));
void hitmonster __P((double));
void ill_sig __P((int));
double infloat __P((void));
void initialstate __P((void));
void initplayer __P((struct player *));
int inputoption __P((void));
void interrupt __P((void));
void leavegame __P((void));
void monsthits __P((void));
void monstlist __P((void));
void more __P((int));
void movelevel __P((void));
void myturn __P((void));
void neatstuff __P((void));
int pickmonster __P((void));
void playerhits __P((void));
void playinit __P((void));
void procmain __P((void));
void purgeoldplayers __P((void));
void readmessage __P((void));
void readrecord __P((struct player *, long));
long recallplayer __P((void));
long recallplayer __P((void));
long rollnewplayer __P((void));
void scorelist __P((void));
void scramblestats __P((void));
void tampered __P((int, double, double));
void throneroom __P((void));
void throwspell __P((void));
void titlelist __P((void));
void tradingpost __P((void));
void truncstring __P((char *));
void userlist __P((bool));
void writerecord __P((struct player *, long));
void writevoid __P((struct energyvoid *, long));

126
phantasia/phantstruct.h Normal file
View File

@@ -0,0 +1,126 @@
/* $NetBSD: phantstruct.h,v 1.2 1995/03/24 04:00:11 cgd Exp $ */
/*
* phantstruct.h - structure definitions for Phantasia
*/
struct player /* player statistics */
{
double p_experience; /* experience */
double p_level; /* level */
double p_strength; /* strength */
double p_sword; /* sword */
double p_might; /* effect strength */
double p_energy; /* energy */
double p_maxenergy; /* maximum energy */
double p_shield; /* shield */
double p_quickness; /* quickness */
double p_quksilver; /* quicksilver */
double p_speed; /* effective quickness */
double p_magiclvl; /* magic level */
double p_mana; /* mana */
double p_brains; /* brains */
double p_poison; /* poison */
double p_gold; /* gold */
double p_gems; /* gems */
double p_sin; /* sin */
double p_x; /* x coord */
double p_y; /* y coord */
double p_1scratch,
p_2scratch; /* variables used for decree, player battle */
struct
{
short ring_type; /* type of ring */
short ring_duration; /* duration of ring */
bool ring_inuse; /* ring in use flag */
} p_ring; /* ring stuff */
long p_age; /* age of player */
int p_degenerated; /* age/3000 last degenerated */
short p_type; /* character type */
short p_specialtype; /* special character type */
short p_lives; /* multiple lives for council, valar */
short p_crowns; /* crowns */
short p_charms; /* charms */
short p_amulets; /* amulets */
short p_holywater; /* holy water */
short p_lastused; /* day of year last used */
short p_status; /* playing, cloaked, etc. */
short p_tampered; /* decree'd, etc. flag */
short p_istat; /* used for inter-terminal battle */
bool p_palantir; /* palantir */
bool p_blessing; /* blessing */
bool p_virgin; /* virgin */
bool p_blindness; /* blindness */
char p_name[SZ_NAME]; /* name */
char p_password[SZ_PASSWORD];/* password */
char p_login[SZ_LOGIN]; /* login */
};
struct monster /* monster stats */
{
double m_strength; /* strength */
double m_brains; /* brains */
double m_speed; /* speed */
double m_energy; /* energy */
double m_experience; /* experience */
double m_flock; /* % chance of flocking */
double m_o_strength; /* original strength */
double m_o_speed; /* original speed */
double m_maxspeed; /* maximum speed */
double m_o_energy; /* original energy */
double m_melee; /* melee damage */
double m_skirmish; /* skirmish damage */
int m_treasuretype; /* treasure type */
int m_type; /* special type */
char m_name[26]; /* name */
};
struct energyvoid /* energy void */
{
double ev_x; /* x coordinate */
double ev_y; /* y coordinate */
bool ev_active; /* active or not */
};
struct scoreboard /* scoreboard entry */
{
double sb_level; /* level of player */
char sb_type[4]; /* character type of player */
char sb_name[SZ_NAME]; /* name of player */
char sb_login[SZ_LOGIN]; /* login of player */
};
struct charstats /* character type statistics */
{
double c_maxbrains; /* max brains per level */
double c_maxmana; /* max mana per level */
double c_weakness; /* how strongly poison affects player */
double c_goldtote; /* how much gold char can carry */
int c_ringduration; /* bad ring duration */
struct
{
double base; /* base for roll */
double interval; /* interval for roll */
double increase; /* increment per level */
} c_quickness, /* quickness */
c_strength, /* strength */
c_mana, /* mana */
c_energy, /* energy level */
c_brains, /* brains */
c_magiclvl; /* magic level */
};
struct menuitem /* menu item for purchase */
{
char *item; /* menu item name */
double cost; /* cost of item */
};

283
phantasia/setup.c Normal file
View File

@@ -0,0 +1,283 @@
/* $NetBSD: setup.c,v 1.8 1997/11/24 01:47:26 mrg Exp $ */
/*
* setup.c - set up all files for Phantasia
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "include.h"
int main __P((int, char *[]));
void Error __P((char *, char *));
double drandom __P((void));
/* */
/************************************************************************
/
/ FUNCTION NAME: main()
/
/ FUNCTION: setup files for Phantasia 3.3.2
/
/ AUTHOR: E. A. Estes, 12/4/85
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: time(), exit(), stat(), Error(), creat(), close(), fopen(),
/ fgets(), floor(), srandom(), umask(), drandom(), strcpy(), getuid(),
/ unlink(), fwrite(), fclose(), sscanf(), printf(), strlen(), fprintf()
/
/ GLOBAL INPUTS: Curmonster, _iob[], Databuf[], *Monstfp, Enrgyvoid
/
/ GLOBAL OUTPUTS: Curmonster, Databuf[], *Monstfp, Enrgyvoid
/
/ DESCRIPTION:
/
/ This program tries to verify the parameters specified in
/ the Makefile.
/
/ Create all necessary files. Note that nothing needs to be
/ put in these files.
/ Also, the monster binary data base is created here.
/
/ ************************************************************************/
static char *files[] = { /* all files to create */
_PATH_MONST,
_PATH_PEOPLE,
_PATH_MESS,
_PATH_LASTDEAD,
_PATH_MOTD,
_PATH_GOLD,
_PATH_VOID,
_PATH_SCORE,
NULL,
};
char *monsterfile="monsters.asc";
int
main(argc, argv)
int argc;
char *argv[];
{
register char **filename; /* for pointing to file names */
register int fd; /* file descriptor */
FILE *fp; /* for opening files */
struct stat fbuf; /* for getting files statistics */
int ch;
char path[MAXPATHLEN], *prefix;
while ((ch = getopt(argc, argv, "m:")) != -1)
switch(ch) {
case 'm':
monsterfile = optarg;
break;
case '?':
default:
break;
}
argc -= optind;
argv += optind;
srandom((unsigned) time(NULL)); /* prime random numbers */
umask(0117); /* only owner can read/write created files */
prefix = getenv("DESTDIR");
/* try to create data files */
filename = &files[0];
while (*filename != NULL)
/* create each file */
{
snprintf(path, sizeof(path), "%s%s", prefix?prefix:"", *filename);
if (stat(path, &fbuf) == 0)
/* file exists; remove it */
{
if (!strcmp(*filename, _PATH_PEOPLE))
/* do not reset character file if it already exists */
{
++filename;
continue;
}
if (!strcmp(*filename, _PATH_SCORE))
/* do not reset score file if it already exists */
{
++filename;
continue;
}
if (unlink(path) < 0)
Error("Cannot unlink %s.\n", path);
/*NOTREACHED*/
}
if ((fd = creat(path, 0660)) < 0)
Error("Cannot create %s.\n", path);
/*NOTREACHED*/
close(fd); /* close newly created file */
++filename; /* process next file */
}
/* put holy grail info into energy void file */
Enrgyvoid.ev_active = TRUE;
Enrgyvoid.ev_x = ROLL(-1.0e6, 2.0e6);
Enrgyvoid.ev_y = ROLL(-1.0e6, 2.0e6);
snprintf(path, sizeof(path), "%s%s", prefix?prefix:"", _PATH_VOID);
if ((fp = fopen(path, "w")) == NULL)
Error("Cannot update %s.\n", path);
else
{
fwrite(&Enrgyvoid, SZ_VOIDSTRUCT, 1, fp);
fclose(fp);
}
/* create binary monster data base */
snprintf(path, sizeof(path), "%s%s", prefix?prefix:"", _PATH_MONST);
if ((Monstfp = fopen(path, "w")) == NULL)
Error("Cannot update %s.\n", path);
else
{
if ((fp = fopen(monsterfile, "r")) == NULL)
{
fclose(Monstfp);
Error("cannot open %s to create monster database.\n", "monsters.asc");
}
else
{
Curmonster.m_o_strength =
Curmonster.m_o_speed =
Curmonster.m_maxspeed =
Curmonster.m_o_energy =
Curmonster.m_melee =
Curmonster.m_skirmish = 0.0;
while (fgets(Databuf, SZ_DATABUF, fp) != NULL)
/* read in text file, convert to binary */
{
sscanf(&Databuf[24], "%lf%lf%lf%lf%lf%d%d%lf",
&Curmonster.m_strength, &Curmonster.m_brains,
&Curmonster.m_speed, &Curmonster.m_energy,
&Curmonster.m_experience, &Curmonster.m_treasuretype,
&Curmonster.m_type, &Curmonster.m_flock);
Databuf[24] = '\0';
strcpy(Curmonster.m_name, Databuf);
fwrite((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp);
}
fclose(fp);
fclose(Monstfp);
}
}
#ifdef MAKE_INSTALLS_THIS_AND_DOESNT_WANT_TO_HEAR_ABOUT_IT
/* write to motd file */
printf("One line 'motd' ? ");
if (fgets(Databuf, SZ_DATABUF, stdin) == NULL)
Databuf[0] = '\0';
snprintf(path, sizeof(path), "%s%s", prefix?prefix:"", _PATH_MOTD);
if ((fp = fopen(path, "w")) == NULL)
Error("Cannot update %s.\n", path);
else
{
fwrite(Databuf, sizeof(char), strlen(Databuf), fp);
fclose(fp);
}
/* report compile-time options */
printf("Compiled options:\n\n");
printf("Phantasia destination directory: %s\n", _PATH_PHANTDIR);
printf("Wizard: root UID: 0\n");
#ifdef BSD41
printf("Compiled for BSD 4.1\n");
#endif
#ifdef BSD42
printf("Compiled for BSD 4.2\n");
#endif
#ifdef SYS3
printf("Compiled for System III\n");
#endif
#ifdef SYS5
printf("Compiled for System V\n");
#endif
#endif
exit(0);
/*NOTREACHED*/
}
/* */
/************************************************************************
/
/ FUNCTION NAME: Error()
/
/ FUNCTION: print an error message, and exit
/
/ AUTHOR: E. A. Estes, 12/4/85
/
/ ARGUMENTS:
/ char *str - format string for printf()
/ char *file - file which caused error
/
/ RETURN VALUE: none
/
/ MODULES CALLED: exit(), perror(), fprintf()
/
/ GLOBAL INPUTS: _iob[]
/
/ GLOBAL OUTPUTS: none
/
/ DESCRIPTION:
/ Print an error message, then exit.
/
/ ************************************************************************/
void
Error(str, file)
char *str, *file;
{
fprintf(stderr, "Error: ");
fprintf(stderr, str, file);
perror(file);
exit(1);
/*NOTREACHED*/
}
/* */
/************************************************************************
/
/ FUNCTION NAME: drandom()
/
/ FUNCTION: return a random number
/
/ AUTHOR: E. A. Estes, 2/7/86
/
/ ARGUMENTS: none
/
/ RETURN VALUE: none
/
/ MODULES CALLED: random()
/
/ GLOBAL INPUTS: none
/
/ GLOBAL OUTPUTS: none
/
/ DESCRIPTION:
/
/ ************************************************************************/
double
drandom()
{
if (sizeof(int) != 2)
return((double) (random() & 0x7fff) / 32768.0);
else
return((double) random() / 32768.0);
}