1 #define INCLUDED // Define externs here
\r
11 static char line[128], *linep = line;
\r
12 static int linecount; /* for paging */
\r
14 static void clearscreen(void);
\r
16 #define NUMCOMMANDS 34
\r
18 /* Compared to original version, I've changed the "help" command to
\r
19 "call" and the "terminate" command to "quit" to better match
\r
20 user expectations. The DECUS version apparently made those changes
\r
21 as well as changing "freeze" to "save". However I like "freeze".
\r
23 When I got a later version of Super Star Trek that I was converting
\r
24 from, I added the emexit command.
\r
26 That later version also mentions srscan and lrscan working when
\r
27 docked (using the starbase's scanners), so I made some changes here
\r
28 to do this (and indicating that fact to the player), and then realized
\r
29 the base would have a subspace radio as well -- doing a Chart when docked
\r
30 updates the star chart, and all radio reports will be heard. The Dock
\r
31 command will also give a report if a base is under attack.
\r
33 Movecom no longer reports movement if sensors are damaged so you wouldn't
\r
38 1. Better base positioning at startup
\r
40 2. deathray improvement (but keeping original failure alternatives)
\r
44 4. Enemies can ram the Enterprise. Regular Klingons and Romulans can
\r
45 move in Expert and Emeritus games. This code could use improvement.
\r
47 5. The deep space probe looks interesting! DECUS version
\r
49 6. Perhaps cloaking to be added later? BSD version
\r
55 static char *commands[NUMCOMMANDS] = {
\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 (d.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 (d.galaxy[quadx][quady] == 1000) { // went NOVA!
\r
343 if (alldone) break;
\r
348 void 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 printf("Do you want your score recorded?");
\r
383 printf("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
420 void crmena(int i, int enemy, int key, int x, int y) {
\r
421 if (i == 1) proutn("***");
\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
492 // Skip leading white space
\r
493 while (*linep == ' ') linep++;
\r
499 if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {
\r
500 // treat as a number
\r
501 if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
\r
502 linep = line; // Invalid numbers are ignored
\r
514 while (*linep && *linep!=' ') {
\r
515 if ((cp - citem) < 9) *cp++ = tolower(*linep);
\r
527 if (*citem == 'y') return TRUE;
\r
528 if (*citem == 'n') return FALSE;
\r
529 proutn("Please answer with \"Y\" or \"N\":");
\r
533 void cramf(double x, int w, int d) {
\r
535 sprintf(buf, "%*.*f", w, d, x);
\r
539 void crami(int i, int w) {
\r
541 sprintf(buf, "%*d", w, i);
\r
545 double square(double i) { return i*i; }
\r
547 static void clearscreen(void) {
\r
548 /* Somehow we need to clear the screen */
\r
549 #ifdef __BORLANDC__
\r
550 extern void clrscr(void);
\r
553 proutn("\033[2J"); /* Hope for an ANSI display */
\r
557 /* We will pull these out in case we want to do something special later */
\r
559 void pause(int i) {
\r
563 prout("[ANOUNCEMENT ARRIVING...]");
\r
565 prout("[IMPORTANT ANNOUNCEMENT ARRIVING -- HIT SPACE BAR TO CONTINUE]");
\r
570 proutn("[CONTINUE?]");
\r
572 proutn("[HIT SPACE BAR TO CONTINUE]");
\r
586 if (linecount >= 23)
\r
594 void proutn(char *s) {
\r
598 void prout(char *s) {
\r
603 void prouts(char *s) {
\r
605 /* print slowly! */
\r
607 endTime = clock() + CLOCKS_PER_SEC*0.05;
\r
608 while (clock() < endTime) ;
\r
617 prout("Beg your pardon, Captain?");
\r
620 int isit(char *s) {
\r
621 /* New function -- compares s to scaned citem and returns true if it
\r
622 matches to the length of s */
\r
624 return strncmp(s, citem, max(1, strlen(citem))) == 0;
\r
629 void debugme(void) {
\r
630 proutn("Reset levels? ");
\r
632 if (energy < inenrg) energy = inenrg;
\r
637 proutn("Reset damage? ");
\r
640 for (i=0; i <= ndevice; i++) if (damage[i] > 0.0) damage[i] = 0.0;
\r
643 proutn("Toggle idebug? ");
\r
646 if (idebug) prout("Debug output ON");
\r
647 else prout("Debug output OFF");
\r
649 proutn("Cause selective damage? ");
\r
652 for (i=1; i <= ndevice; i++) {
\r
658 if (key == IHALPHA && isit("y")) {
\r
660 if (i == DRADIO) stdamtim = d.date;
\r
664 proutn("Examine/change events? ");
\r
667 for (i = 1; i < NEVENTS; i++) {
\r
669 if (future[i] == 1e30) continue;
\r
671 case FSNOVA: proutn("Supernova "); break;
\r
672 case FTBEAM: proutn("T Beam "); break;
\r
673 case FSNAP: proutn("Snapshot "); break;
\r
674 case FBATTAK: proutn("Base Attack "); break;
\r
675 case FCDBAS: proutn("Base Destroy "); break;
\r
676 case FSCMOVE: proutn("SC Move "); break;
\r
677 case FSCDBAS: proutn("SC Base Destroy "); break;
\r
679 cramf(future[i]-d.date, 8, 2);
\r
683 if (key == IHREAL) {
\r
684 future[i] = d.date + aaitem;
\r