1 #define INCLUDED // Define externs here
\r
12 static char line[128], *linep = line;
\r
13 static int linecount; /* for paging */
\r
15 static void clearscreen(void);
\r
17 /* Compared to original version, I've changed the "help" command to
\r
18 "call" and the "terminate" command to "quit" to better match
\r
19 user expectations. The DECUS version apparently made those changes
\r
20 as well as changing "freeze" to "save". However I like "freeze".
\r
22 When I got a later version of Super Star Trek that I was converting
\r
23 from, I added the emexit command.
\r
25 That later version also mentions srscan and lrscan working when
\r
26 docked (using the starbase's scanners), so I made some changes here
\r
27 to do this (and indicating that fact to the player), and then realized
\r
28 the base would have a subspace radio as well -- doing a Chart when docked
\r
29 updates the star chart, and all radio reports will be heard. The Dock
\r
30 command will also give a report if a base is under attack.
\r
32 Movecom no longer reports movement if sensors are damaged so you wouldn't
\r
37 1. Better base positioning at startup
\r
39 2. deathray improvement (but keeping original failure alternatives)
\r
43 4. Enemies can ram the Enterprise. Regular Klingons and Romulans can
\r
44 move in Expert and Emeritus games. This code could use improvement.
\r
46 5. The deep space probe looks interesting! DECUS version
\r
48 6. Perhaps cloaking to be added later? BSD version
\r
54 static char *commands[] = {
\r
90 #define NUMCOMMANDS sizeof(commands)/sizeof(commands[0])
\r
92 static void listCommands(int x) {
\r
93 prout(" SRSCAN MOVE PHASERS CALL\n"
\r
94 " STATUS IMPULSE PHOTONS ABANDON\n"
\r
95 " LRSCAN WARP SHIELDS DESTRUCT\n"
\r
96 " CHART REST DOCK QUIT\n"
\r
97 " DAMAGES REPORT SENSORS ORBIT\n"
\r
98 " TRANSPORT MINE CRYSTALS SHUTTLE\n"
\r
99 " PLANETS REQUEST DEATHRAY FREEZE\n"
\r
100 " COMPUTER EMEXIT PROBE COMMANDS");
\r
101 if (x) prout(" HELP");
\r
104 static void helpme(void) {
\r
109 /* Give help on commands */
\r
113 if (key == IHEOL) {
\r
114 proutn("Help on what command?");
\r
117 if (key == IHEOL) return;
\r
118 for (i = 0; i < NUMCOMMANDS; i++) {
\r
119 if (strcmp(commands[i], citem)==0) break;
\r
121 if (i != NUMCOMMANDS) break;
\r
123 prout("Valid commands:");
\r
124 listCommands(FALSE);
\r
130 strcpy(cmdbuf, " ABBREV");
\r
133 strcpy(cmdbuf, " Mnemonic: ");
\r
135 while ((cmdbuf[j+13] = toupper(commands[i][j])) != 0) j++;
\r
137 fp = fopen("sst.doc", "r");
\r
139 prout("Spock- \"Captain, that information is missing from the");
\r
140 prout(" computer. You need to find SST.DOC and put it in the");
\r
141 prout(" current directory.\"");
\r
144 i = strlen(cmdbuf);
\r
146 if (fgets(linebuf, 132, fp) == NULL) {
\r
147 prout("Spock- \"Captain, there is no information on that command.\"");
\r
151 } while (strncmp(linebuf, cmdbuf, i) != 0);
\r
154 prout("Spock- \"Captain, I've found the following information:\"");
\r
158 if (linebuf[0]!=12) { // ignore page break lines
\r
159 linebuf[strlen(linebuf)-1] = '\0'; // No \n at end
\r
162 fgets(linebuf,132,fp);
\r
163 } while (strstr(linebuf, "******")==NULL);
\r
167 static void makemoves(void) {
\r
170 while (TRUE) { /* command loop */
\r
175 while (TRUE) { /* get a command */
\r
178 proutn("COMMAND> ");
\r
179 if (scan() == IHEOL) continue;
\r
180 for (i=0; i < 26; i++)
\r
181 if (isit(commands[i]))
\r
184 for (; i < NUMCOMMANDS; i++)
\r
185 if (strcmp(commands[i], citem) == 0) break;
\r
186 if (i < NUMCOMMANDS) break;
\r
189 prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");
\r
190 listCommands(TRUE);
\r
192 else prout("UNRECOGNIZED COMMAND.");
\r
194 switch (i) { /* command switch */
\r
203 if (ididit) hitme = TRUE;
\r
207 if (ididit) hitme = TRUE;
\r
233 if (ididit) hitme = TRUE;
\r
241 case 13: // sensors
\r
246 if (ididit) hitme = TRUE;
\r
248 case 15: // transport "beam"
\r
253 if (ididit) hitme = TRUE;
\r
255 case 17: // crystals
\r
258 case 18: // shuttle
\r
260 if (ididit) hitme = TRUE;
\r
262 case 19: // Planet list
\r
265 case 20: // Status information
\r
268 case 21: // Game Report
\r
271 case 22: // use COMPUTER!
\r
275 listCommands(TRUE);
\r
277 case 24: // Emergency exit
\r
278 clearscreen(); // Hide screen
\r
279 freeze(TRUE); // forced save
\r
280 exit(1); // And quick exit
\r
283 probe(); // Launch probe
\r
285 case 26: // Abandon Ship
\r
288 case 27: // Self Destruct
\r
291 case 28: // Save Game
\r
294 prout("WARNING--Frozen games produce no plaques!");
\r
296 case 29: // Try a desparation measure
\r
298 if (ididit) hitme = TRUE;
\r
300 case 30: // What do we want for debug???
\r
305 case 31: // Call for help
\r
309 alldone = 1; // quit the game
\r
311 if (idebug) score();
\r
315 helpme(); // get help
\r
319 if (alldone) break; // Game has ended
\r
321 if (idebug) prout("2500");
\r
325 if (alldone) break; // Events did us in
\r
327 if (game.state.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!
\r
331 if (nenhere == 0) movetho();
\r
332 if (hitme && justin==0) {
\r
334 if (alldone) break;
\r
335 if (game.state.galaxy[quadx][quady] == 1000) { // went NOVA!
\r
343 if (alldone) break;
\r
348 int main(int argc, char **argv) {
\r
355 fromcommandline = 1;
\r
357 while (--argc > 0) {
\r
358 strcat(line, *(++argv));
\r
362 else fromcommandline = 0;
\r
365 while (TRUE) { /* Play a game */
\r
376 if (tourn && alldone) {
\r
377 proutn("Do you want your score recorded?");
\r
383 proutn("Do you want to play again?");
\r
387 prout("May the Great Bird of the Galaxy roost upon your home planet.");
\r
391 void cramen(int i) {
\r
392 /* return an enemy */
\r
396 case IHR: s = "Romulan"; break;
\r
397 case IHK: s = "Klingon"; break;
\r
398 case IHC: s = "Commander"; break;
\r
399 case IHS: s = "Super-commander"; break;
\r
400 case IHSTAR: s = "Star"; break;
\r
401 case IHP: s = "Planet"; break;
\r
402 case IHB: s = "Starbase"; break;
\r
403 case IHBLANK: s = "Black hole"; break;
\r
404 case IHT: s = "Tholian"; break;
\r
405 case IHWEB: s = "Tholian web"; break;
\r
406 default: s = "Unknown??"; break;
\r
411 void cramlc(int key, int x, int y) {
\r
412 if (key == 1) proutn(" Quadrant");
\r
413 else if (key == 2) proutn(" Sector");
\r
414 proutn(" %d - %d", x, y);
\r
417 void crmena(int i, int enemy, int key, int x, int y) {
\r
418 if (i == 1) proutn("***");
\r
424 void crmshp(void) {
\r
427 case IHE: s = "Enterprise"; break;
\r
428 case IHF: s = "Faerie Queene"; break;
\r
429 default: s = "Ship???"; break;
\r
435 prouts("******************************************************");
\r
439 double expran(double avrage) {
\r
440 return -avrage*log(1e-7 + Rand());
\r
443 double Rand(void) {
\r
444 return rand()/(1.0 + (double)RAND_MAX);
\r
447 void iran8(int *i, int *j) {
\r
448 *i = Rand()*8.0 + 1.0;
\r
449 *j = Rand()*8.0 + 1.0;
\r
452 void iran10(int *i, int *j) {
\r
453 *i = Rand()*10.0 + 1.0;
\r
454 *j = Rand()*10.0 + 1.0;
\r
464 /* return IHEOL next time */
\r
480 // Read a line if nothing here
\r
482 if (linep != line) {
\r
486 fgets(line, sizeof(line), stdin);
\r
487 line[strlen(line)-1] = '\0';
\r
490 // Skip leading white space
\r
491 while (*linep == ' ') linep++;
\r
497 if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {
\r
498 // treat as a number
\r
499 if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
\r
500 linep = line; // Invalid numbers are ignored
\r
512 while (*linep && *linep!=' ') {
\r
513 if ((cp - citem) < 9) *cp++ = tolower(*linep);
\r
525 if (*citem == 'y') return TRUE;
\r
526 if (*citem == 'n') return FALSE;
\r
527 proutn("Please answer with \"Y\" or \"N\":");
\r
531 void cramf(double x, int w, int d) {
\r
533 sprintf(buf, "%*.*f", w, d, x);
\r
537 double square(double i) { return i*i; }
\r
539 static void clearscreen(void) {
\r
540 /* Somehow we need to clear the screen */
\r
541 #ifdef __BORLANDC__
\r
542 extern void clrscr(void);
\r
545 proutn("\033[2J"); /* Hope for an ANSI display */
\r
549 /* We will pull these out in case we want to do something special later */
\r
551 void pause(int i) {
\r
555 prout("[ANOUNCEMENT ARRIVING...]");
\r
557 prout("[IMPORTANT ANNOUNCEMENT ARRIVING -- HIT SPACE BAR TO CONTINUE]");
\r
562 proutn("[CONTINUE?]");
\r
564 proutn("[HIT SPACE BAR TO CONTINUE]");
\r
578 if (linecount >= 23)
\r
586 void proutn(char *fmt, ...) {
\r
593 void prout(char *fmt, ...) {
\r
601 void prouts(char *fmt, ...) {
\r
603 char *s, buf[BUFSIZ];
\r
604 /* print slowly! */
\r
607 vsprintf(buf, fmt, ap);
\r
610 for (s = buf; *s; s++) {
\r
611 endTime = clock() + CLOCKS_PER_SEC*0.05;
\r
612 while (clock() < endTime) ;
\r
621 prout("Beg your pardon, Captain?");
\r
624 int isit(char *s) {
\r
625 /* New function -- compares s to scaned citem and returns true if it
\r
626 matches to the length of s */
\r
628 return strncmp(s, citem, max(1, strlen(citem))) == 0;
\r
633 void debugme(void) {
\r
634 proutn("Reset levels? ");
\r
636 if (energy < inenrg) energy = inenrg;
\r
641 proutn("Reset damage? ");
\r
644 for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;
\r
647 proutn("Toggle idebug? ");
\r
650 if (idebug) prout("Debug output ON");
\r
651 else prout("Debug output OFF");
\r
653 proutn("Cause selective damage? ");
\r
656 for (i=1; i <= NDEVICES; i++) {
\r
662 if (key == IHALPHA && isit("y")) {
\r
664 if (i == DRADIO) stdamtim = game.state.date;
\r
668 proutn("Examine/change events? ");
\r
671 for (i = 1; i < NEVENTS; i++) {
\r
673 if (future[i] == 1e30) continue;
\r
675 case FSNOVA: proutn("Supernova "); break;
\r
676 case FTBEAM: proutn("T Beam "); break;
\r
677 case FSNAP: proutn("Snapshot "); break;
\r
678 case FBATTAK: proutn("Base Attack "); break;
\r
679 case FCDBAS: proutn("Base Destroy "); break;
\r
680 case FSCMOVE: proutn("SC Move "); break;
\r
681 case FSCDBAS: proutn("SC Base Destroy "); break;
\r
683 cramf(future[i]-game.state.date, 8, 2);
\r
687 if (key == IHREAL) {
\r
688 future[i] = game.state.date + aaitem;
\r