|
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; }