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
106 char cmdbuf[32], *cp;
\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 for (j = 0; commands[i][j]; j++)
\r
134 cmdbuf[j] = toupper(commands[i][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
145 if (fgets(linebuf, sizeof(linebuf), fp) == NULL) {
\r
146 prout("Spock- \"Captain, there is no information on that command.\"");
\r
150 if (linebuf[0] == '%' && linebuf[1] == '%'&& linebuf[2] == ' ') {
\r
151 for (cp = linebuf+3; isspace(*cp); cp++)
\r
153 linebuf[strlen(linebuf)-1] = '\0';
\r
154 if (strcmp(cp, cmdbuf) == 0)
\r
160 prout("Spock- \"Captain, I've found the following information:\"");
\r
163 while (fgets(linebuf, sizeof(linebuf),fp)) {
\r
164 if (strstr(linebuf, "******"))
\r
166 linebuf[strlen(linebuf)-1] = '\0'; // No \n at end
\r
172 static void makemoves(void) {
\r
175 while (TRUE) { /* command loop */
\r
180 while (TRUE) { /* get a command */
\r
183 proutn("COMMAND> ");
\r
184 if (scan() == IHEOL) continue;
\r
185 for (i=0; i < 26; i++)
\r
186 if (isit(commands[i]))
\r
189 for (; i < NUMCOMMANDS; i++)
\r
190 if (strcmp(commands[i], citem) == 0) break;
\r
191 if (i < NUMCOMMANDS) break;
\r
194 prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");
\r
195 listCommands(TRUE);
\r
197 else prout("UNRECOGNIZED COMMAND.");
\r
199 switch (i) { /* command switch */
\r
208 if (ididit) hitme = TRUE;
\r
212 if (ididit) hitme = TRUE;
\r
238 if (ididit) hitme = TRUE;
\r
246 case 13: // sensors
\r
251 if (ididit) hitme = TRUE;
\r
253 case 15: // transport "beam"
\r
258 if (ididit) hitme = TRUE;
\r
260 case 17: // crystals
\r
263 case 18: // shuttle
\r
265 if (ididit) hitme = TRUE;
\r
267 case 19: // Planet list
\r
270 case 20: // Status information
\r
273 case 21: // Game Report
\r
276 case 22: // use COMPUTER!
\r
280 listCommands(TRUE);
\r
282 case 24: // Emergency exit
\r
283 clearscreen(); // Hide screen
\r
284 freeze(TRUE); // forced save
\r
285 exit(1); // And quick exit
\r
288 probe(); // Launch probe
\r
290 case 26: // Abandon Ship
\r
293 case 27: // Self Destruct
\r
296 case 28: // Save Game
\r
299 prout("WARNING--Frozen games produce no plaques!");
\r
301 case 29: // Try a desparation measure
\r
303 if (ididit) hitme = TRUE;
\r
305 case 30: // What do we want for debug???
\r
310 case 31: // Call for help
\r
314 alldone = 1; // quit the game
\r
316 if (idebug) score();
\r
320 helpme(); // get help
\r
324 if (alldone) break; // Game has ended
\r
326 if (idebug) prout("2500");
\r
330 if (alldone) break; // Events did us in
\r
332 if (game.state.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!
\r
336 if (nenhere == 0) movetho();
\r
337 if (hitme && justin==0) {
\r
339 if (alldone) break;
\r
340 if (game.state.galaxy[quadx][quady] == 1000) { // went NOVA!
\r
348 if (alldone) break;
\r
353 int main(int argc, char **argv) {
\r
360 fromcommandline = 1;
\r
362 while (--argc > 0) {
\r
363 strcat(line, *(++argv));
\r
367 else fromcommandline = 0;
\r
370 while (TRUE) { /* Play a game */
\r
381 if (tourn && alldone) {
\r
382 proutn("Do you want your score recorded?");
\r
388 proutn("Do you want to play again?");
\r
392 prout("May the Great Bird of the Galaxy roost upon your home planet.");
\r
396 void cramen(int i) {
\r
397 /* return an enemy */
\r
401 case IHR: s = "Romulan"; break;
\r
402 case IHK: s = "Klingon"; break;
\r
403 case IHC: s = "Commander"; break;
\r
404 case IHS: s = "Super-commander"; break;
\r
405 case IHSTAR: s = "Star"; break;
\r
406 case IHP: s = "Planet"; break;
\r
407 case IHB: s = "Starbase"; break;
\r
408 case IHBLANK: s = "Black hole"; break;
\r
409 case IHT: s = "Tholian"; break;
\r
410 case IHWEB: s = "Tholian web"; break;
\r
411 default: s = "Unknown??"; break;
\r
416 char *cramlc(enum loctype key, int x, int y) {
\r
417 static char buf[32];
\r
419 if (key == quadrant) strcpy(buf, "Quadrant ");
\r
420 else if (key == sector) strcpy(buf, "Sector ");
\r
421 sprintf(buf+strlen(buf), "%d-%d", x, y);
\r
425 void crmena(int i, int enemy, int key, int x, int y) {
\r
426 if (i == 1) proutn("***");
\r
429 proutn(cramlc(key, x, y));
\r
432 void crmshp(void) {
\r
435 case IHE: s = "Enterprise"; break;
\r
436 case IHF: s = "Faerie Queene"; break;
\r
437 default: s = "Ship???"; break;
\r
443 prouts("******************************************************");
\r
447 double expran(double avrage) {
\r
448 return -avrage*log(1e-7 + Rand());
\r
451 double Rand(void) {
\r
452 return rand()/(1.0 + (double)RAND_MAX);
\r
455 void iran8(int *i, int *j) {
\r
456 *i = Rand()*8.0 + 1.0;
\r
457 *j = Rand()*8.0 + 1.0;
\r
460 void iran10(int *i, int *j) {
\r
461 *i = Rand()*10.0 + 1.0;
\r
462 *j = Rand()*10.0 + 1.0;
\r
472 /* return IHEOL next time */
\r
488 // Read a line if nothing here
\r
490 if (linep != line) {
\r
494 fgets(line, sizeof(line), stdin);
\r
495 line[strlen(line)-1] = '\0';
\r
498 // Skip leading white space
\r
499 while (*linep == ' ') linep++;
\r
505 if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {
\r
506 // treat as a number
\r
507 if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
\r
508 linep = line; // Invalid numbers are ignored
\r
520 while (*linep && *linep!=' ') {
\r
521 if ((cp - citem) < 9) *cp++ = tolower(*linep);
\r
533 if (*citem == 'y') return TRUE;
\r
534 if (*citem == 'n') return FALSE;
\r
535 proutn("Please answer with \"Y\" or \"N\":");
\r
539 double square(double i) { return i*i; }
\r
541 static void clearscreen(void) {
\r
542 /* Somehow we need to clear the screen */
\r
543 #ifdef __BORLANDC__
\r
544 extern void clrscr(void);
\r
547 proutn("\033[2J"); /* Hope for an ANSI display */
\r
551 /* We will pull these out in case we want to do something special later */
\r
553 void pause(int i) {
\r
557 prout("[ANOUNCEMENT ARRIVING...]");
\r
559 prout("[IMPORTANT ANNOUNCEMENT ARRIVING -- HIT SPACE BAR TO CONTINUE]");
\r
564 proutn("[CONTINUE?]");
\r
566 proutn("[HIT SPACE BAR TO CONTINUE]");
\r
580 if (linecount >= 23)
\r
588 void proutn(char *fmt, ...) {
\r
595 void prout(char *fmt, ...) {
\r
603 void prouts(char *fmt, ...) {
\r
605 char *s, buf[BUFSIZ];
\r
606 /* print slowly! */
\r
609 vsprintf(buf, fmt, ap);
\r
612 for (s = buf; *s; s++) {
\r
613 endTime = clock() + CLOCKS_PER_SEC*0.05;
\r
614 while (clock() < endTime) ;
\r
623 prout("Beg your pardon, Captain?");
\r
626 int isit(char *s) {
\r
627 /* New function -- compares s to scaned citem and returns true if it
\r
628 matches to the length of s */
\r
630 return strncmp(s, citem, max(1, strlen(citem))) == 0;
\r
635 void debugme(void) {
\r
636 proutn("Reset levels? ");
\r
638 if (energy < inenrg) energy = inenrg;
\r
643 proutn("Reset damage? ");
\r
646 for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;
\r
649 proutn("Toggle idebug? ");
\r
652 if (idebug) prout("Debug output ON");
\r
653 else prout("Debug output OFF");
\r
655 proutn("Cause selective damage? ");
\r
658 for (i=1; i <= NDEVICES; i++) {
\r
664 if (key == IHALPHA && isit("y")) {
\r
666 if (i == DRADIO) stdamtim = game.state.date;
\r
670 proutn("Examine/change events? ");
\r
673 for (i = 1; i < NEVENTS; i++) {
\r
675 if (future[i] == 1e30) continue;
\r
677 case FSNOVA: proutn("Supernova "); break;
\r
678 case FTBEAM: proutn("T Beam "); break;
\r
679 case FSNAP: proutn("Snapshot "); break;
\r
680 case FBATTAK: proutn("Base Attack "); break;
\r
681 case FCDBAS: proutn("Base Destroy "); break;
\r
682 case FSCMOVE: proutn("SC Move "); break;
\r
683 case FSCDBAS: proutn("SC Base Destroy "); break;
\r
685 proutn("%.2f", future[i]-game.state.date);
\r
689 if (key == IHREAL) {
\r
690 future[i] = game.state.date + aaitem;
\r