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 char *cramlc(enum loctype key, int x, int y) {
\r
412 static char buf[32];
\r
414 if (key == quadrant) strcpy(buf, "Quadrant ");
\r
415 else if (key == sector) strcpy(buf, "Sector ");
\r
416 sprintf(buf+strlen(buf), "%d-%d", x, y);
\r
420 void crmena(int i, int enemy, int key, int x, int y) {
\r
421 if (i == 1) proutn("***");
\r
424 proutn(cramlc(key, x, y));
\r
427 void crmshp(void) {
\r
430 case IHE: s = "Enterprise"; break;
\r
431 case IHF: s = "Faerie Queene"; break;
\r
432 default: s = "Ship???"; break;
\r
438 prouts("******************************************************");
\r
442 double expran(double avrage) {
\r
443 return -avrage*log(1e-7 + Rand());
\r
446 double Rand(void) {
\r
447 return rand()/(1.0 + (double)RAND_MAX);
\r
450 void iran8(int *i, int *j) {
\r
451 *i = Rand()*8.0 + 1.0;
\r
452 *j = Rand()*8.0 + 1.0;
\r
455 void iran10(int *i, int *j) {
\r
456 *i = Rand()*10.0 + 1.0;
\r
457 *j = Rand()*10.0 + 1.0;
\r
467 /* return IHEOL next time */
\r
483 // Read a line if nothing here
\r
485 if (linep != line) {
\r
489 fgets(line, sizeof(line), stdin);
\r
490 line[strlen(line)-1] = '\0';
\r
493 // Skip leading white space
\r
494 while (*linep == ' ') linep++;
\r
500 if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {
\r
501 // treat as a number
\r
502 if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
\r
503 linep = line; // Invalid numbers are ignored
\r
515 while (*linep && *linep!=' ') {
\r
516 if ((cp - citem) < 9) *cp++ = tolower(*linep);
\r
528 if (*citem == 'y') return TRUE;
\r
529 if (*citem == 'n') return FALSE;
\r
530 proutn("Please answer with \"Y\" or \"N\":");
\r
534 double square(double i) { return i*i; }
\r
536 static void clearscreen(void) {
\r
537 /* Somehow we need to clear the screen */
\r
538 #ifdef __BORLANDC__
\r
539 extern void clrscr(void);
\r
542 proutn("\033[2J"); /* Hope for an ANSI display */
\r
546 /* We will pull these out in case we want to do something special later */
\r
548 void pause(int i) {
\r
552 prout("[ANOUNCEMENT ARRIVING...]");
\r
554 prout("[IMPORTANT ANNOUNCEMENT ARRIVING -- HIT SPACE BAR TO CONTINUE]");
\r
559 proutn("[CONTINUE?]");
\r
561 proutn("[HIT SPACE BAR TO CONTINUE]");
\r
575 if (linecount >= 23)
\r
583 void proutn(char *fmt, ...) {
\r
590 void prout(char *fmt, ...) {
\r
598 void prouts(char *fmt, ...) {
\r
600 char *s, buf[BUFSIZ];
\r
601 /* print slowly! */
\r
604 vsprintf(buf, fmt, ap);
\r
607 for (s = buf; *s; s++) {
\r
608 endTime = clock() + CLOCKS_PER_SEC*0.05;
\r
609 while (clock() < endTime) ;
\r
618 prout("Beg your pardon, Captain?");
\r
621 int isit(char *s) {
\r
622 /* New function -- compares s to scaned citem and returns true if it
\r
623 matches to the length of s */
\r
625 return strncmp(s, citem, max(1, strlen(citem))) == 0;
\r
630 void debugme(void) {
\r
631 proutn("Reset levels? ");
\r
633 if (energy < inenrg) energy = inenrg;
\r
638 proutn("Reset damage? ");
\r
641 for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;
\r
644 proutn("Toggle idebug? ");
\r
647 if (idebug) prout("Debug output ON");
\r
648 else prout("Debug output OFF");
\r
650 proutn("Cause selective damage? ");
\r
653 for (i=1; i <= NDEVICES; i++) {
\r
659 if (key == IHALPHA && isit("y")) {
\r
661 if (i == DRADIO) stdamtim = game.state.date;
\r
665 proutn("Examine/change events? ");
\r
668 for (i = 1; i < NEVENTS; i++) {
\r
670 if (future[i] == 1e30) continue;
\r
672 case FSNOVA: proutn("Supernova "); break;
\r
673 case FTBEAM: proutn("T Beam "); break;
\r
674 case FSNAP: proutn("Snapshot "); break;
\r
675 case FBATTAK: proutn("Base Attack "); break;
\r
676 case FCDBAS: proutn("Base Destroy "); break;
\r
677 case FSCMOVE: proutn("SC Move "); break;
\r
678 case FSCDBAS: proutn("SC Base Destroy "); break;
\r
680 proutn("%82.2f", future[i]-game.state.date);
\r
684 if (key == IHREAL) {
\r
685 future[i] = game.state.date + aaitem;
\r