1 #define INCLUDED // Define externs here
\r
11 #define SSTDOC "sst.doc"
\r
16 static char line[128], *linep = line;
\r
17 static int linecount; /* for paging */
\r
18 static int screenheight = 24;
\r
20 static void clearscreen(void);
\r
22 /* Compared to original version, I've changed the "help" command to
\r
23 "call" and the "terminate" command to "quit" to better match
\r
24 user expectations. The DECUS version apparently made those changes
\r
25 as well as changing "freeze" to "save". However I like "freeze".
\r
27 When I got a later version of Super Star Trek that I was converting
\r
28 from, I added the emexit command.
\r
30 That later version also mentions srscan and lrscan working when
\r
31 docked (using the starbase's scanners), so I made some changes here
\r
32 to do this (and indicating that fact to the player), and then realized
\r
33 the base would have a subspace radio as well -- doing a Chart when docked
\r
34 updates the star chart, and all radio reports will be heard. The Dock
\r
35 command will also give a report if a base is under attack.
\r
37 Movecom no longer reports movement if sensors are damaged so you wouldn't
\r
42 1. Better base positioning at startup
\r
44 2. deathray improvement (but keeping original failure alternatives)
\r
48 4. Enemies can ram the Enterprise. Regular Klingons and Romulans can
\r
49 move in Expert and Emeritus games. This code could use improvement.
\r
51 5. The deep space probe looks interesting! DECUS version
\r
53 6. Perhaps cloaking to be added later? BSD version
\r
59 static char *commands[] = {
\r
95 #define NUMCOMMANDS sizeof(commands)/sizeof(commands[0])
\r
97 static void listCommands(int x) {
\r
98 prout(" SRSCAN MOVE PHASERS CALL\n"
\r
99 " STATUS IMPULSE PHOTONS ABANDON\n"
\r
100 " LRSCAN WARP SHIELDS DESTRUCT\n"
\r
101 " CHART REST DOCK QUIT\n"
\r
102 " DAMAGES REPORT SENSORS ORBIT\n"
\r
103 " TRANSPORT MINE CRYSTALS SHUTTLE\n"
\r
104 " PLANETS REQUEST DEATHRAY FREEZE\n"
\r
105 " COMPUTER EMEXIT PROBE COMMANDS");
\r
106 if (x) prout(" HELP");
\r
109 static void helpme(void) {
\r
111 char cmdbuf[32], *cp;
\r
114 /* Give help on commands */
\r
118 if (key == IHEOL) {
\r
119 proutn("Help on what command?");
\r
122 if (key == IHEOL) return;
\r
123 for (i = 0; i < NUMCOMMANDS; i++) {
\r
124 if (strcmp(commands[i], citem)==0) break;
\r
126 if (i != NUMCOMMANDS) break;
\r
128 prout("Valid commands:");
\r
129 listCommands(FALSE);
\r
135 strcpy(cmdbuf, " ABBREV");
\r
138 for (j = 0; commands[i][j]; j++)
\r
139 cmdbuf[j] = toupper(commands[i][j]);
\r
142 fp = fopen(SSTDOC, "r");
\r
144 prout("Spock- \"Captain, that information is missing from the");
\r
145 prout(" computer. You need to find SST.DOC and put it in the");
\r
146 prout(" current directory.\"");
\r
150 if (fgets(linebuf, sizeof(linebuf), fp) == NULL) {
\r
151 prout("Spock- \"Captain, there is no information on that command.\"");
\r
155 if (linebuf[0] == '%' && linebuf[1] == '%'&& linebuf[2] == ' ') {
\r
156 for (cp = linebuf+3; isspace(*cp); cp++)
\r
158 linebuf[strlen(linebuf)-1] = '\0';
\r
159 if (strcmp(cp, cmdbuf) == 0)
\r
165 prout("Spock- \"Captain, I've found the following information:\"");
\r
168 while (fgets(linebuf, sizeof(linebuf),fp)) {
\r
169 if (strstr(linebuf, "******"))
\r
171 /* use fputs here to avoid % expansion */
\r
172 fputs(linebuf, stdout);
\r
177 static void makemoves(void) {
\r
180 while (TRUE) { /* command loop */
\r
185 while (TRUE) { /* get a command */
\r
188 proutn("COMMAND> ");
\r
189 if (scan() == IHEOL) continue;
\r
190 for (i=0; i < 26; i++)
\r
191 if (isit(commands[i]))
\r
194 for (; i < NUMCOMMANDS; i++)
\r
195 if (strcmp(commands[i], citem) == 0) break;
\r
196 if (i < NUMCOMMANDS) break;
\r
199 prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");
\r
200 listCommands(TRUE);
\r
202 else prout("UNRECOGNIZED COMMAND.");
\r
204 switch (i) { /* command switch */
\r
213 if (ididit) hitme = TRUE;
\r
217 if (ididit) hitme = TRUE;
\r
243 if (ididit) hitme = TRUE;
\r
251 case 13: // sensors
\r
256 if (ididit) hitme = TRUE;
\r
258 case 15: // transport "beam"
\r
263 if (ididit) hitme = TRUE;
\r
265 case 17: // crystals
\r
268 case 18: // shuttle
\r
270 if (ididit) hitme = TRUE;
\r
272 case 19: // Planet list
\r
275 case 20: // Status information
\r
278 case 21: // Game Report
\r
281 case 22: // use COMPUTER!
\r
285 listCommands(TRUE);
\r
287 case 24: // Emergency exit
\r
288 clearscreen(); // Hide screen
\r
289 freeze(TRUE); // forced save
\r
290 exit(1); // And quick exit
\r
293 probe(); // Launch probe
\r
295 case 26: // Abandon Ship
\r
298 case 27: // Self Destruct
\r
301 case 28: // Save Game
\r
304 prout("WARNING--Frozen games produce no plaques!");
\r
306 case 29: // Try a desparation measure
\r
308 if (ididit) hitme = TRUE;
\r
310 case 30: // What do we want for debug???
\r
315 case 31: // Call for help
\r
319 alldone = 1; // quit the game
\r
321 if (idebug) score();
\r
325 helpme(); // get help
\r
329 if (alldone) break; // Game has ended
\r
331 if (idebug) prout("2500");
\r
335 if (alldone) break; // Events did us in
\r
337 if (game.state.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!
\r
341 if (nenhere == 0) movetho();
\r
342 if (hitme && justin==0) {
\r
344 if (alldone) break;
\r
345 if (game.state.galaxy[quadx][quady] == 1000) { // went NOVA!
\r
353 if (alldone) break;
\r
358 int main(int argc, char **argv) {
\r
363 char *LINES = getenv("LINES");
\r
366 screenheight = atoi(LINES);
\r
369 fromcommandline = 1;
\r
371 while (--argc > 0) {
\r
372 strcat(line, *(++argv));
\r
376 else fromcommandline = 0;
\r
379 while (TRUE) { /* Play a game */
\r
390 if (tourn && alldone) {
\r
391 proutn("Do you want your score recorded?");
\r
397 proutn("Do you want to play again?");
\r
401 prout("May the Great Bird of the Galaxy roost upon your home planet.");
\r
405 void cramen(int i) {
\r
406 /* return an enemy */
\r
410 case IHR: s = "Romulan"; break;
\r
411 case IHK: s = "Klingon"; break;
\r
412 case IHC: s = "Commander"; break;
\r
413 case IHS: s = "Super-commander"; break;
\r
414 case IHSTAR: s = "Star"; break;
\r
415 case IHP: s = "Planet"; break;
\r
416 case IHB: s = "Starbase"; break;
\r
417 case IHBLANK: s = "Black hole"; break;
\r
418 case IHT: s = "Tholian"; break;
\r
419 case IHWEB: s = "Tholian web"; break;
\r
420 default: s = "Unknown??"; break;
\r
425 char *cramlc(enum loctype key, int x, int y) {
\r
426 static char buf[32];
\r
428 if (key == quadrant) strcpy(buf, "Quadrant ");
\r
429 else if (key == sector) strcpy(buf, "Sector ");
\r
430 sprintf(buf+strlen(buf), "%d-%d", x, y);
\r
434 void crmena(int i, int enemy, int key, int x, int y) {
\r
435 if (i == 1) proutn("***");
\r
438 proutn(cramlc(key, x, y));
\r
441 void crmshp(void) {
\r
444 case IHE: s = "Enterprise"; break;
\r
445 case IHF: s = "Faerie Queene"; break;
\r
446 default: s = "Ship???"; break;
\r
452 prouts("******************************************************");
\r
456 double expran(double avrage) {
\r
457 return -avrage*log(1e-7 + Rand());
\r
460 double Rand(void) {
\r
461 return rand()/(1.0 + (double)RAND_MAX);
\r
464 void iran8(int *i, int *j) {
\r
465 *i = Rand()*8.0 + 1.0;
\r
466 *j = Rand()*8.0 + 1.0;
\r
469 void iran10(int *i, int *j) {
\r
470 *i = Rand()*10.0 + 1.0;
\r
471 *j = Rand()*10.0 + 1.0;
\r
481 /* return IHEOL next time */
\r
497 // Read a line if nothing here
\r
499 if (linep != line) {
\r
503 fgets(line, sizeof(line), stdin);
\r
504 line[strlen(line)-1] = '\0';
\r
507 // Skip leading white space
\r
508 while (*linep == ' ') linep++;
\r
514 if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {
\r
515 // treat as a number
\r
516 if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
\r
517 linep = line; // Invalid numbers are ignored
\r
529 while (*linep && *linep!=' ') {
\r
530 if ((cp - citem) < 9) *cp++ = tolower(*linep);
\r
542 if (*citem == 'y') return TRUE;
\r
543 if (*citem == 'n') return FALSE;
\r
544 proutn("Please answer with \"Y\" or \"N\":");
\r
548 double square(double i) { return i*i; }
\r
550 static void clearscreen(void) {
\r
551 /* Somehow we need to clear the screen */
\r
552 #ifdef __BORLANDC__
\r
553 extern void clrscr(void);
\r
556 proutn("\033[2J"); /* Hope for an ANSI display */
\r
560 /* We will pull these out in case we want to do something special later */
\r
562 void pause(int i) {
\r
566 prout("[ANOUNCEMENT ARRIVING...]");
\r
568 prout("[IMPORTANT ANNOUNCEMENT ARRIVING -- HIT SPACE BAR TO CONTINUE]");
\r
573 proutn("[CONTINUE?]");
\r
575 proutn("[HIT SPACE BAR TO CONTINUE]");
\r
589 if (linecount >= screenheight)
\r
597 void proutn(char *fmt, ...) {
\r
604 void prout(char *fmt, ...) {
\r
612 void prouts(char *fmt, ...) {
\r
614 char *s, buf[BUFSIZ];
\r
615 /* print slowly! */
\r
618 vsprintf(buf, fmt, ap);
\r
621 for (s = buf; *s; s++) {
\r
622 endTime = clock() + CLOCKS_PER_SEC*0.05;
\r
623 while (clock() < endTime) ;
\r
632 prout("Beg your pardon, Captain?");
\r
635 int isit(char *s) {
\r
636 /* New function -- compares s to scaned citem and returns true if it
\r
637 matches to the length of s */
\r
639 return strncmp(s, citem, max(1, strlen(citem))) == 0;
\r
644 void debugme(void) {
\r
645 proutn("Reset levels? ");
\r
647 if (energy < inenrg) energy = inenrg;
\r
652 proutn("Reset damage? ");
\r
655 for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;
\r
658 proutn("Toggle idebug? ");
\r
661 if (idebug) prout("Debug output ON");
\r
662 else prout("Debug output OFF");
\r
664 proutn("Cause selective damage? ");
\r
667 for (i=1; i <= NDEVICES; i++) {
\r
673 if (key == IHALPHA && isit("y")) {
\r
675 if (i == DRADIO) stdamtim = game.state.date;
\r
679 proutn("Examine/change events? ");
\r
682 for (i = 1; i < NEVENTS; i++) {
\r
684 if (future[i] == 1e30) continue;
\r
686 case FSNOVA: proutn("Supernova "); break;
\r
687 case FTBEAM: proutn("T Beam "); break;
\r
688 case FSNAP: proutn("Snapshot "); break;
\r
689 case FBATTAK: proutn("Base Attack "); break;
\r
690 case FCDBAS: proutn("Base Destroy "); break;
\r
691 case FSCMOVE: proutn("SC Move "); break;
\r
692 case FSCDBAS: proutn("SC Base Destroy "); break;
\r
694 proutn("%.2f", future[i]-game.state.date);
\r
698 if (key == IHREAL) {
\r
699 future[i] = game.state.date + aaitem;
\r