|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 14221 (0x378d)
Types: TextFile
Names: »sub1.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Vtrek/sub1.c«
/* sub1.c -- subroutines for visual star trek */
#include "vtrek.h"
#ifdef BSD
#include <strings.h>
#else
#include <string.h>
#endif
#ifndef BSD
extern void srand ();
#endif
extern long time ();
/* print short help information */
help()
{
if (rolines > 5)
readout(CLEAR, (char *) 0);
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];
(void) sprintf(str, "Command %s ? ", captain);
prompt(str);
refresh ();
ch = getch();
return Toupper(ch);
}
/* give option to see instructions */
instructions()
{
FILE *fp;
char line[80];
int n, ch;
(void) printf("Instructions ? ");
randomize();
if (fgets(line, 80, stdin) == NULL)
vexit(0);
ch = Toupper(line[0]);
if (ch == 'Y') {
if ((fp = fopen(VTREKINS, "r")) == NULL)
(void) printf("Error: Missing instruction file\n");
else {
for (;;) {
for (n = 0; n < 22; n++) {
if (fgets(line, 80, fp) == NULL)
break;
(void) printf ("%s", line);
}
if (n < 22) {
(void) printf ("(Hit RETURN)");
(void) getchar ();
break;
}
(void) printf ("(Hit RETURN)");
(void) getchar ();
}
(void) fclose(fp);
}
}
}
/* get captain's name and ship's name */
getnames()
{
int tmp;
(void) printf("Your name captain ? ");
if (fgets(captain, 11, stdin) == NULL)
vexit(1);
if (captain[tmp = strlen(captain) - 1] == '\n')
captain[tmp] = '\0';
else
while (getchar() != '\n');
if (*captain == '\0')
(void) strcpy(captain, "Duncel");
(void) printf("Your ship's name captain ? ");
if (fgets(shipname, 11, stdin) == NULL)
vexit(1);
if (shipname[tmp = strlen(shipname) - 1] == '\n')
shipname[tmp] = '\0';
else
while (getchar() != '\n');
if (*shipname == '\0')
(void) strcpy(shipname, "Fruit");
}
/* get skill level */
getskill()
{
char level[10];
(void) printf("Skill level (0-5, 0=easy, 5=hard) ? ");
if (fgets(level, 10, stdin) == NULL)
vexit(1);
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;
(void) 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, 0, 0);
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, Duncel!");
if (damage[SRS] > 0)
(void) strcpy(captain, "Duncel");
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()
{
char c;
plt_stat(ELEMENT, SHIELDS);
prompt("(Press RETURN)");
refresh ();
while ((c = getch()) != '\n' && c != '\r')
;
erase ();
(void) mvprintw (10, 20, "Your ship the %s has been destroyed.", shipname);
mvaddstr (11, 20, "The Federation will be conquered.");
refresh ();
while ((c = getch()) != '\n' && c != '\r')
;
vexit(0);
}
win()
{
char c;
readout(ADDLINE, "Congratulations!");
prompt("(Press RETURN)");
refresh ();
while ((c = getch()) != '\n' && c != '\r')
;
erase ();
move (10, 15);
(void) printw ("The last of the Klingon battle cruisers have been\n");
(void) printw ("%15sdestroyed. You alone have saved the Federation. You\n", "");
(void) printw ("%15sare promoted to Admiral %s !!!\n", "", captain);
refresh ();
while ((c = getch()) != '\n' && c != '\r')
;
vexit(0);
}
/* random (?) number generator */
rnd(max)
int max;
{
return (int)(rand() % max);
}
/* randomize */
randomize()
{
#ifdef BSD
srand((int) time((long *) 0));
#else
srand((unsigned int) time((long *) 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 = getnum()) >= 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 */
getnum()
{
int num = 0, ch;
refresh ();
while ((ch = getch()) != '\n') {
addch (ch);
if (isdigit(ch))
num = num * 10 + ch - '0';
else if (ch == '\b') {
num = num / 10;
addch (' ');
addch ('\b');
}
else
break;
refresh ();
}
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) {
(void) sprintf(str, "You did %d to the Klingon.", dam);
readout(ADDLINE, str);
}
if ((klingon[k].sh -= dam) < 0) {
readout(ADDLINE, "Klingon destroyed.");
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, 0, 0);
break;
case DAMAGE :
plt_dam(INFO, 0);
break;
case COMPUTER :
plt_gal(INFO, 0, 0);
break;
}
}
}
/* print a prompt in the upper left hand corner */
prompt(str)
char *str;
{
int i;
move (0, 0);
for (i = 0; i < 26; i++)
addch (' ');
(void) mvprintw (0, 0, "%-.26s", str);
}
/* 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 ? ");
refresh ();
if (islower(dir = getch()))
dir = toupper(dir);
if (checkdir(dir, &dx, &dy) == ERROR) {
readout(ADDLINE, "Illegal direction.");
return;
}
prompt("Warp ? ");
refresh ();
addch (w = getch());
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;
(void) setpos();
plt_stat(ELEMENT, ENERGY);
}
}
else if (w == '.' && (refresh (), isdigit(w = getch()) )) {
addch (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, (char *) 0);
for (y = yquad - 1; y <= yquad + 1; y++) {
readout(ADDLINE, "+---+---+---+");
(void) strcpy(str, "|");
for (x = xquad - 1; x <= xquad + 1; x++) {
if (x < 0 || x > 7 || y < 0 || y > 7)
(void) strcat(str, "XXX");
else {
if (damage[COMPUTER] > 0)
galaxy[x][y].known = 1;
(void) sprintf(str + strlen(str), "%d%d%d", galaxy[x][y].nkling,
galaxy[x][y].nbase, galaxy[x][y].nstar);
plt_gal(ELEMENT, x, y);
}
(void) 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, (char *) 0);
readout(ADDLINE, "Sector Direction Distance");
for (k = 0; k < 3; k++) {
if (klingon[k].sh >= 0) {
if (damage[COMPUTER] <= 0)
(void) 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;
(void) 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;
}