home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 7 Games
/
07-Games.zip
/
MVTREK.ZIP
/
SUB1.C
< prev
next >
Wrap
Text File
|
1990-06-04
|
17KB
|
788 lines
/* sub1.c -- subroutines for visual star trek */
#include "vtrek.h"
#ifdef HI_TECH_C
#define atan2 atan
#endif
/* print short help information */
help()
{
if (rolines > 5)
readout(CLEAR, NULL);
readout(ADDLINE, "Directions = Q,W,E,A,D,Z,X,C");
readout(ADDLINE, "H = Hyper-space S = Short range scan");
readout(ADDLINE, "L = Long range scan P = Fire phasers");
readout(ADDLINE, "T = Fire torpedo U = Defense control");
readout(ADDLINE, "R = Redraw screen F = Fix devices");
}
/* get command character */
getcmd()
{
int ch;
char str[40];
fflush(stdout);
sprintf(str, "Command, Captain %s ? ", captain);
prompt(str);
fflush(stdout);
ch = getchar();
fflush(stdout);
fflush(stdin);
return Toupper(ch);
}
/* give option to see instructions */
instructions()
{
FILE *fp;
char line[80];
int n, ch;
fflush(stdin);
fflush(stdout);
printf("Instructions <y/N>? ");
fflush(stdout);
/* Took out chready(). see original src! */
if (fgets(line, 80, stdin) == (char *)NULL)
vexit(0);
fflush(stdin);
fflush(stdout);
ch = Toupper(line[0]);
if (ch == 'Y') {
if ((fp = fopen(VTREKINS, "r")) == (FILE *)NULL)
printf("Error: Missing instruction file\n");
else {
terminit();
for (;;) {
cls();
for (n = 0; n < 22; n++) {
if (fgets(line, 80, fp) == (char *)NULL)
break;
printf("%s", line);
fflush(stdout);
#ifdef UNIX
putchar('\r');
#endif
}
if (n < 22)
break;
printf("--More--");
fflush(stdout);
getchar();
fflush(stdout);
fflush(stdin);
}
fclose(fp);
termreset();
}
}
}
/* get captain's name and ship's name */
getnames()
{
int tmp;
fflush(stdout);
printf("Your name captain ? ");
fflush(stdout);
if (fgets(captain, 11, stdin) == (char *)NULL)
vexit(1);
fflush(stdout);
fflush(stdin);
if (captain[tmp = strlen(captain) - 1] == '\n')
captain[tmp] = '\0';
else
while (getchar() != '\n');
if (*captain == '\0')
strcpy(captain, "Kirk");
fflush(stdout);
printf("Your ship's name captain ? ");
fflush(stdout);
if (fgets(shipname, 11, stdin) == (char *)NULL)
vexit(1);
fflush(stdout);
fflush(stdin);
if (shipname[tmp = strlen(shipname) - 1] == '\n')
shipname[tmp] = '\0';
else
while (getchar() != '\n');
if (*shipname == '\0')
strcpy(shipname, "Enterprise");
}
/* get skill level */
getskill()
{
char level[10];
fflush(stdout);
printf("Skill level (0-5, 0=easy, 5=hard) ? ");
fflush(stdout);
if (fgets(level, 10, stdin) == (char *)NULL)
vexit(1);
fflush(stdin);
fflush(stdout);
if (isdigit(level[0]))
skill = level[0] - '0';
else
skill = 3;
}
/* initialize galaxy */
initgal()
{
int i, j, k, r, n;
numkling = 0;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
if ((r = rnd(100)) < 10)
k = 3;
else if (r < 20)
k = 2;
else if (r < 30)
k = 1;
else
k = 0;
numkling += k;
galaxy[i][j].nkling = k;
galaxy[i][j].nstar = rnd(8) + 1;
galaxy[i][j].nbase = 0;
galaxy[i][j].known = 0;
}
}
numbases = rnd(3) + 2;
for (n = 0; n < numbases; n++) {
for (;;) {
if (galaxy[i = rnd(7)][j = rnd(7)].nbase == 0) {
galaxy[i][j].nbase = 1;
break;
}
}
}
}
/* initialize variables */
initvars()
{
int i;
getnames();
getskill();
initgal();
numkmove = skill;
begkling = numkling;
xquad = rnd(7);
yquad = rnd(7);
old_xsect = (xsect = rnd(7));
old_ysect = (ysect = rnd(7));
shields = 0;
energy = 3000;
stardate = 2000.0;
begdate = stardate;
lastdate = stardate + (float)numkling;
torps = 10;
playership[1] = *shipname;
condition = YELLOW;
for (i = 0; i < 8; i++)
damage[i] = 100;
old_xquad = -1;
old_yquad = -1;
setpos();
}
/* set new position -- check for outside galaxy, set up new quadrant */
setpos()
{
int dam = 0, i, j, n, status = 0;
static int notfirstcall = 0;
if (xsect > 7) {
xsect = 0;
xquad++;
}
else if (xsect < 0) {
xsect = 7;
xquad--;
}
if (ysect > 7) {
ysect = 0;
yquad++;
}
else if (ysect < 0) {
ysect = 7;
yquad--;
}
if (xquad > 7) {
dam = 1;
xquad = 7;
xsect = 7;
}
else if (xquad < 0) {
dam = 1;
xquad = 0;
xsect = 0;
}
if (yquad > 7) {
dam = 1;
yquad = 7;
ysect = 7;
}
else if (yquad < 0) {
dam = 1;
yquad = 0;
ysect = 0;
}
if (dam) {
readout(ADDLINE, "You encounter a force field.");
shields -= rnd(20) + 90;
plt_stat(ELEMENT, SHIELDS);
status = DAMAGE;
if (shields < 0)
die();
}
if (xquad != old_xquad || yquad != old_yquad) {
galaxy[xquad][yquad].known = 1;
if (notfirstcall) {
plt_gal(ELEMENT, old_xquad, old_yquad);
plt_gal(ELEMENT, xquad, yquad);
}
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
quadrant[i][j] = EMPTY;
quadrant[xsect][ysect] = PLAYER;
for (n = 0; n < galaxy[xquad][yquad].nkling; n++) {
for (;;) {
if (quadrant[i = rnd(7)][j = rnd(7)] == EMPTY) {
quadrant[i][j] = KLINGON;
break;
}
}
klingon[n].xs = i;
klingon[n].ys = j;
klingon[n].sh = 200;
}
for (; n < 3; n++)
klingon[n].xs = klingon[n].ys = klingon[n].sh = -1;
for (n = 0; n < galaxy[xquad][yquad].nbase; n++)
for (;;) {
if (quadrant[i = rnd(7)][j = rnd(7)] == EMPTY) {
quadrant[i][j] = STARBASE;
base_xsect = i;
base_ysect = j;
break;
}
}
for (n = 0; n < galaxy[xquad][yquad].nstar; n++)
for (;;) {
if (quadrant[i = rnd(7)][j = rnd(7)] == EMPTY) {
quadrant[i][j] = STAR;
break;
}
}
old_xquad = xquad;
old_yquad = yquad;
if (notfirstcall) {
plt_srs(INFO);
plt_stat(ELEMENT, CONDITION);
plt_stat(ELEMENT, QUADRANT);
plt_gal(ELEMENT, xquad, yquad);
}
}
else {
switch (quadrant[xsect][ysect]) {
case KLINGON:
dam = rnd(20) + 90;
if (damkling(xsect, ysect, dam) != DEAD) {
xsect = old_xsect;
ysect = old_ysect;
}
dam >>= 1;
if ((shields -= dam) < 0)
die();
fixdev(REL, RND, -dam);
plt_stat(ELEMENT, SHIELDS);
break;
case STAR:
readout(ADDLINE, "There's a star in the way, Dunce!");
if (damage[SRS] > 0)
strcpy(captain, "Dunce");
xsect = old_xsect;
ysect = old_ysect;
break;
case STARBASE:
xsect = old_xsect;
ysect = old_ysect;
readout(ADDLINE, "There's a star base in the way!");
break;
}
status = quadrant[xsect][ysect];
quadrant[old_xsect][old_ysect] = EMPTY;
quadrant[xsect][ysect] = PLAYER;
plt_srs(ELEMENT, old_xsect, old_ysect);
plt_srs(ELEMENT, xsect, ysect);
}
old_xsect = xsect;
old_ysect = ysect;
if (notfirstcall)
plt_stat(ELEMENT, SECTOR);
notfirstcall = 1;
return status;
}
/* "So this is it. We're going to die." -- Arthur Dent */
die()
{
plt_stat(ELEMENT, SHIELDS);
prompt("(Press RETURN)");
fflush(stdout);
fflush(stdin);
getchar();
fflush(stdout);
cls();
fflush(stdout);
score(0);
moveyx(15, 21);
printf("Your ship the %s has been destroyed.", shipname);
fflush(stdout);
moveyx(16, 21);
printf("The Federation will be conquered.\n\n\n\r");
fflush(stdout);
vexit(0);
}
win()
{
readout(ADDLINE, "Congratulations!");
fflush(stdout);
prompt("(Press RETURN)");
fflush(stdout);
getchar();
fflush(stdout);
cls();
fflush(stdout);
score(1);
moveyx(20,1);
fflush(stdout);
printf("[Press Return]\n");
fflush(stdout);
getchar();
fflush(stdout);
cls();
fflush(stdout);
moveyx(11, 16);
fflush(stdout);
printf("The last of the Klingon battle cruisers have been\n");
fflush(stdout);
printf("%15sdestroyed. You alone have saved the Federation. You\n", "");
fflush(stdout);
printf("%15sare promoted to Admiral %s !!!\n\n\n\r", "", captain);
fflush(stdout);
vexit(0);
}
/* random (?) number generator */
rnd(max)
int max;
{
#ifdef AZTEC
static long iy = 0x86A186A1;
iy *= 125;
iy &= 0x7FFFFFFF;
iy %= 0xAAAAAAAd;
return (int)((iy >> 8) % max);
#else
return (int)(rand() % max);
#endif
}
#ifdef UNIX
/* randomize */
randomize()
{
srand(time(0));
}
#endif
/* impulse drive -- move one sector */
impulse(dir)
int dir;
{
int dx, dy, status;
if (energy <= 0) {
readout(ADDLINE, "Insufficient energy for command.");
return ERROR;
}
if (checkdir(dir, &dx, &dy) != ERROR) {
xsect += dx;
ysect += dy;
}
energy--;
status = setpos();
plt_stat(ELEMENT, ENERGY);
return status;
}
/* defense -- set shield level */
defense()
{
if (damage[DEFENSE] <= 0)
readout(ADDLINE, "Defense control is damaged.");
else {
energy += shields;
for (;;) {
prompt("Shield level ? ");
if ((shields = getnumb()) >= 0 && shields <= energy) {
energy -= shields;
break;
}
}
if (shields > 0) {
playership[0] = '(';
playership[2] = ')';
}
else {
playership[0] = ' ';
playership[2] = ' ';
}
plt_srs(ELEMENT, xsect, ysect);
plt_stat(ELEMENT, SHIELDS);
plt_stat(ELEMENT, ENERGY);
}
}
/* get a number */
getnumb()
{
int num = 0, ch;
fflush(stdout);
while ((ch = getchar()) != '\r') {
fflush(stdout);
putchar(ch);
fflush(stdout);
if (isdigit(ch))
num = num * 10 + ch - '0';
else if (ch == '\b') {
num = num / 10;
fflush(stdout);
putchar(' ');
fflush(stdout);
putchar('\b');
fflush(stdout);
}
else
break;
}
return num;
}
/* damage a klingon */
damkling(xs, ys, dam)
int xs, ys, dam;
{
char str[40];
int k;
if ((k = findkling(xs, ys)) == ERROR)
readout(ADDLINE, "damkling: error");
else {
if (dam != AUTOKILL) {
sprintf(str, "You did %d to the Klingon.", dam);
readout(ADDLINE, str);
fflush(stdout);
}
if ((klingon[k].sh -= dam) < 0) {
readout(ADDLINE, "Klingon destroyed.");
fflush(stdout);
klingon[k].xs = klingon[k].ys = -1;
quadrant[xs][ys] = EMPTY;
plt_srs(ELEMENT, xs, ys);
numkling--;
plt_num(INFO);
galaxy[xquad][yquad].nkling--;
plt_gal(ELEMENT, xquad, yquad);
return DEAD;
}
}
return ALIVE;
}
/* fix/damage a device */
fixdev(type, dev, value)
int type; /* ABSolution fix or RELative fix */
int dev; /* device (if RND then pick a damaged device) */
int value; /* new device value for ABS, amount to add for REL */
{
int i, old_dam;
if (dev == RND) {
dev = rnd(8);
if (value > 0 && damage[dev] >= 100) {
for (i = 0; i < 8; i++) {
if (++dev > 7)
dev = 0;
if (damage[dev] < 100)
break;
}
}
}
old_dam = damage[dev];
if (type == ABS)
damage[dev] = value;
else
damage[dev] += value;
if (damage[dev] > 100)
damage[dev] = 100;
plt_dam(ELEMENT, dev);
/* see if device changed from fixed <==> broken */
if ((old_dam <= 0 && damage[dev] > 0) || (old_dam > 0 && damage[dev] <= 0)) {
switch (dev) {
case SRS :
plt_srs(INFO);
break;
case DAMAGE :
plt_dam(INFO);
break;
case COMPUTER :
plt_gal(INFO);
break;
}
}
}
/* print a prompt in the upper left hand corner */
prompt(str)
char *str;
{
int i;
moveyx(1, 1);
fflush(stdout);
for (i = 0; i < 26; i++)
putchar(' ');
moveyx(1, 1);
fflush(stdout);
printf("%-.26s", str);
fflush(stdout);
}
/* check a direction for validity and return delta-x and delta-y */
checkdir(dir, dx, dy)
int dir, *dx, *dy;
{
static struct {
int d, x, y;
} dirs[8] = {
{'Q', -1, -1}, {'W', 0, -1}, {'E', 1, -1}, {'D', 1, 0},
{'C', 1, 1}, {'X', 0, 1}, {'Z', -1, 1}, {'A', -1, 0}
};
int i;
for (i = 0; i < 8; i++)
if (dirs[i].d == dir) {
*dx = dirs[i].x;
*dy = dirs[i].y;
return 0;
}
return ERROR;
}
/* hyperspace drive */
hyperspace()
{
int dir, dx, dy, w, tmp, savex, savey;
if (damage[WARP] <= 0)
readout(ADDLINE, "Warp engines are damaged.");
else {
prompt("Direction ? ");
fflush(stdout);
if (islower(dir = getchar()))
dir = toupper(dir);
fflush(stdin);
fflush(stdout);
if (checkdir(dir, &dx, &dy) == ERROR) {
readout(ADDLINE, "Illegal direction.");
return;
}
fflush(stdout);
prompt("Warp ? ");
fflush(stdout);
putchar(w = getchar());
fflush(stdin);
fflush(stdout);
if (isdigit(w)) {
w -= '0';
if (w <= 0)
return;
savex = xsect;
savey = ysect;
while ((tmp = xsect + dx) >= 0 && tmp <= 7 && (tmp = ysect + dy) >= 0 && tmp <= 7) {
if (impulse(dir))
return;
}
if (energy < 20 * w)
readout(ADDLINE, "Insufficient energy for command.");
else {
xquad += w * dx;
yquad += w * dy;
energy -= 20 * w;
stardate += (double)(w) / 5.0;
xsect = savex;
ysect = savey;
setpos();
plt_stat(ELEMENT, ENERGY);
}
}
else if (w == '.' && isdigit(w = getchar())) {
fflush(stdout);
fflush(stdin);
putchar(w);
w -= '0';
stardate += (double)(w) / 50.0;
for (; w > 0; w--)
if (impulse(dir))
break;
}
else
readout(ADDLINE, "Illegal warp factor.");
}
}
/* long range scan */
lrs()
{
int x, y;
char str[20];
if (damage[LRS] <= 0)
readout(ADDLINE, "Long range sensors are damaged.");
else {
if (rolines > 3)
readout(CLEAR, NULL);
for (y = yquad - 1; y <= yquad + 1; y++) {
readout(ADDLINE, "+---+---+---+");
strcpy(str, "|");
for (x = xquad - 1; x <= xquad + 1; x++) {
if (x < 0 || x > 7 || y < 0 || y > 7)
strcat(str, "XXX");
else {
if (damage[COMPUTER] > 0)
galaxy[x][y].known = 1;
sprintf(str + strlen(str), "%d%d%d", galaxy[x][y].nkling,
galaxy[x][y].nbase, galaxy[x][y].nstar);
plt_gal(ELEMENT, x, y);
}
strcat(str, "|");
}
str[13] = '\0';
readout(ADDLINE, str);
}
readout(ADDLINE, "+---+---+---+");
plt_gal(ELEMENT, xquad, yquad);
}
}
/* short range scan */
srs()
{
int k, dx, dy;
double dir, dist;
char str[40];
if (damage[SRS] <= 0)
readout(ADDLINE, "Short range sensors are damaged.");
else {
if (rolines > 6)
readout(CLEAR, NULL);
readout(ADDLINE, "Sector Direction Distance");
for (k = 0; k < 3; k++) {
if (klingon[k].sh >= 0) {
if (damage[COMPUTER] <= 0)
sprintf(str, "[%d,%d]", klingon[k].xs+1, klingon[k].ys+1);
else {
dx = klingon[k].xs - xsect;
dy = klingon[k].ys - ysect;
dist = sqrt((double)(dx*dx) + (double)(dy*dy));
if (dx) {
dir = atan2(-(double)dy, (double)dx) * 180.0 / PI;
if (dir < 0.0)
dir += 360.0;
}
else if (dy > 0)
dir = 270.0;
else
dir = 90.0;
sprintf(str, "[%d,%d] %5.1f %4.1f", klingon[k].xs+1,
klingon[k].ys+1, dir, dist);
}
readout(ADDLINE, str);
}
}
}
}
findkling(x, y)
int x, y;
{
int i;
for (i = 0; i < 3; i++)
if (x == klingon[i].xs && y == klingon[i].ys)
return i;
return ERROR;
}