1 #define INCLUDED // Define externs here
\r
11 #define SSTDOC "sst.doc"
\r
14 static char line[128], *linep = line;
\r
15 static int linecount; /* for paging */
\r
16 static int screenheight = 24;
\r
18 static void clearscreen(void);
\r
20 /* Compared to original version, I've changed the "help" command to
\r
21 "call" and the "terminate" command to "quit" to better match
\r
22 user expectations. The DECUS version apparently made those changes
\r
23 as well as changing "freeze" to "save". However I like "freeze".
\r
25 When I got a later version of Super Star Trek that I was converting
\r
26 from, I added the emexit command.
\r
28 That later version also mentions srscan and lrscan working when
\r
29 docked (using the starbase's scanners), so I made some changes here
\r
30 to do this (and indicating that fact to the player), and then realized
\r
31 the base would have a subspace radio as well -- doing a Chart when docked
\r
32 updates the star chart, and all radio reports will be heard. The Dock
\r
33 command will also give a report if a base is under attack.
\r
35 Movecom no longer reports movement if sensors are damaged so you wouldn't
\r
40 1. Better base positioning at startup
\r
42 2. deathray improvement (but keeping original failure alternatives)
\r
46 4. Enemies can ram the Enterprise. Regular Klingons and Romulans can
\r
47 move in Expert and Emeritus games. This code could use improvement.
\r
49 5. The deep space probe looks interesting! DECUS version
\r
51 6. Perhaps cloaking to be added later? BSD version
\r
57 static char *commands[] = {
\r
93 #define NUMCOMMANDS sizeof(commands)/sizeof(commands[0])
\r
95 static void listCommands(int x) {
\r
96 prout(" SRSCAN MOVE PHASERS CALL\n"
\r
97 " STATUS IMPULSE PHOTONS ABANDON\n"
\r
98 " LRSCAN WARP SHIELDS DESTRUCT\n"
\r
99 " CHART REST DOCK QUIT\n"
\r
100 " DAMAGES REPORT SENSORS ORBIT\n"
\r
101 " TRANSPORT MINE CRYSTALS SHUTTLE\n"
\r
102 " PLANETS REQUEST DEATHRAY FREEZE\n"
\r
103 " COMPUTER EMEXIT PROBE COMMANDS");
\r
104 if (x) prout(" HELP");
\r
107 static void helpme(void) {
\r
109 char cmdbuf[32], *cp;
\r
112 /* Give help on commands */
\r
116 if (key == IHEOL) {
\r
117 proutn("Help on what command?");
\r
120 if (key == IHEOL) return;
\r
121 for (i = 0; i < NUMCOMMANDS; i++) {
\r
122 if (strcmp(commands[i], citem)==0) break;
\r
124 if (i != NUMCOMMANDS) break;
\r
126 prout("Valid commands:");
\r
127 listCommands(FALSE);
\r
133 strcpy(cmdbuf, " ABBREV");
\r
136 for (j = 0; commands[i][j]; j++)
\r
137 cmdbuf[j] = toupper(commands[i][j]);
\r
140 fp = fopen(SSTDOC, "r");
\r
142 prout("Spock- \"Captain, that information is missing from the");
\r
143 prout(" computer. You need to find SST.DOC and put it in the");
\r
144 prout(" current directory.\"");
\r
148 if (fgets(linebuf, sizeof(linebuf), fp) == NULL) {
\r
149 prout("Spock- \"Captain, there is no information on that command.\"");
\r
153 if (linebuf[0] == '%' && linebuf[1] == '%'&& linebuf[2] == ' ') {
\r
154 for (cp = linebuf+3; isspace(*cp); cp++)
\r
156 linebuf[strlen(linebuf)-1] = '\0';
\r
157 if (strcmp(cp, cmdbuf) == 0)
\r
163 prout("Spock- \"Captain, I've found the following information:\"");
\r
166 while (fgets(linebuf, sizeof(linebuf),fp)) {
\r
167 if (strstr(linebuf, "******"))
\r
174 static void makemoves(void) {
\r
177 while (TRUE) { /* command loop */
\r
182 while (TRUE) { /* get a command */
\r
185 proutn("COMMAND> ");
\r
186 if (scan() == IHEOL) continue;
\r
187 for (i=0; i < 26; i++)
\r
188 if (isit(commands[i]))
\r
191 for (; i < NUMCOMMANDS; i++)
\r
192 if (strcmp(commands[i], citem) == 0) break;
\r
193 if (i < NUMCOMMANDS) break;
\r
196 prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");
\r
197 listCommands(TRUE);
\r
199 else prout("UNRECOGNIZED COMMAND.");
\r
201 switch (i) { /* command switch */
\r
210 if (ididit) hitme = TRUE;
\r
214 if (ididit) hitme = TRUE;
\r
240 if (ididit) hitme = TRUE;
\r
248 case 13: // sensors
\r
253 if (ididit) hitme = TRUE;
\r
255 case 15: // transport "beam"
\r
260 if (ididit) hitme = TRUE;
\r
262 case 17: // crystals
\r
265 case 18: // shuttle
\r
267 if (ididit) hitme = TRUE;
\r
269 case 19: // Planet list
\r
272 case 20: // Status information
\r
275 case 21: // Game Report
\r
278 case 22: // use COMPUTER!
\r
282 listCommands(TRUE);
\r
284 case 24: // Emergency exit
\r
285 clearscreen(); // Hide screen
\r
286 freeze(TRUE); // forced save
\r
287 exit(1); // And quick exit
\r
290 probe(); // Launch probe
\r
292 case 26: // Abandon Ship
\r
295 case 27: // Self Destruct
\r
298 case 28: // Save Game
\r
301 prout("WARNING--Frozen games produce no plaques!");
\r
303 case 29: // Try a desparation measure
\r
305 if (ididit) hitme = TRUE;
\r
307 case 30: // What do we want for debug???
\r
312 case 31: // Call for help
\r
316 alldone = 1; // quit the game
\r
318 if (idebug) score();
\r
322 helpme(); // get help
\r
326 if (alldone) break; // Game has ended
\r
328 if (idebug) prout("2500");
\r
332 if (alldone) break; // Events did us in
\r
334 if (game.state.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!
\r
338 if (nenhere == 0) movetho();
\r
339 if (hitme && justin==0) {
\r
341 if (alldone) break;
\r
342 if (game.state.galaxy[quadx][quady] == 1000) { // went NOVA!
\r
350 if (alldone) break;
\r
355 int main(int argc, char **argv) {
\r
360 char *LINES = getenv("LINES");
\r
363 screenheight = atoi(LINES);
\r
367 while (--argc > 0) {
\r
368 strcat(line, *(++argv));
\r
373 while (TRUE) { /* Play a game */
\r
374 setup(line[0] == '\0');
\r
384 if (tourn && alldone) {
\r
385 proutn("Do you want your score recorded?");
\r
391 proutn("Do you want to play again?");
\r
395 prout("May the Great Bird of the Galaxy roost upon your home planet.");
\r
399 void cramen(int i) {
\r
400 /* return an enemy */
\r
404 case IHR: s = "Romulan"; break;
\r
405 case IHK: s = "Klingon"; break;
\r
406 case IHC: s = "Commander"; break;
\r
407 case IHS: s = "Super-commander"; break;
\r
408 case IHSTAR: s = "Star"; break;
\r
409 case IHP: s = "Planet"; break;
\r
410 case IHB: s = "Starbase"; break;
\r
411 case IHBLANK: s = "Black hole"; break;
\r
412 case IHT: s = "Tholian"; break;
\r
413 case IHWEB: s = "Tholian web"; break;
\r
414 default: s = "Unknown??"; break;
\r
419 char *cramlc(enum loctype key, int x, int y) {
\r
420 static char buf[32];
\r
422 if (key == quadrant) strcpy(buf, "Quadrant ");
\r
423 else if (key == sector) strcpy(buf, "Sector ");
\r
424 sprintf(buf+strlen(buf), "%d-%d", x, y);
\r
428 void crmena(int i, int enemy, int key, int x, int y) {
\r
429 if (i == 1) proutn("***");
\r
432 proutn(cramlc(key, x, y));
\r
435 void crmshp(void) {
\r
438 case IHE: s = "Enterprise"; break;
\r
439 case IHF: s = "Faerie Queene"; break;
\r
440 default: s = "Ship???"; break;
\r
446 prouts("******************************************************");
\r
450 double expran(double avrage) {
\r
451 return -avrage*log(1e-7 + Rand());
\r
454 double Rand(void) {
\r
455 return rand()/(1.0 + (double)RAND_MAX);
\r
458 void iran8(int *i, int *j) {
\r
459 *i = Rand()*8.0 + 1.0;
\r
460 *j = Rand()*8.0 + 1.0;
\r
463 void iran10(int *i, int *j) {
\r
464 *i = Rand()*10.0 + 1.0;
\r
465 *j = Rand()*10.0 + 1.0;
\r
475 /* return IHEOL next time */
\r
491 // Read a line if nothing here
\r
493 if (linep != line) {
\r
497 fgets(line, sizeof(line), stdin);
\r
498 line[strlen(line)-1] = '\0';
\r
501 // Skip leading white space
\r
502 while (*linep == ' ') linep++;
\r
508 if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {
\r
509 // treat as a number
\r
510 if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
\r
511 linep = line; // Invalid numbers are ignored
\r
523 while (*linep && *linep!=' ') {
\r
524 if ((cp - citem) < 9) *cp++ = tolower(*linep);
\r
536 if (*citem == 'y') return TRUE;
\r
537 if (*citem == 'n') return FALSE;
\r
538 proutn("Please answer with \"Y\" or \"N\":");
\r
542 double square(double i) { return i*i; }
\r
544 static void clearscreen(void) {
\r
545 /* Somehow we need to clear the screen */
\r
546 #ifdef __BORLANDC__
\r
547 extern void clrscr(void);
\r
550 // proutn("\033[2J"); /* Hope for an ANSI display */
\r
551 /* much more in that old-time TTY spirit to just throw linefeeds */
\r
553 for (i = 0; i < screenheight; i++)
\r
558 /* We will pull these out in case we want to do something special later */
\r
560 void pause(int i) {
\r
565 prout("[ANOUNCEMENT ARRIVING...]");
\r
567 prout("[IMPORTANT ANNOUNCEMENT ARRIVING -- PRESS ENTER TO CONTINUE]");
\r
571 proutn("[CONTINUE?]");
\r
573 proutn("[PRESS ENTER TO CONTINUE]");
\r
576 fgets(buf, sizeof(buf), stdin);
\r
587 if (linecount >= screenheight)
\r
595 void proutn(char *fmt, ...) {
\r
602 void prout(char *fmt, ...) {
\r
610 void proutc(char *line) {
\r
611 line[strlen(line)-1] = '\0';
\r
612 fputs(line, stdout);
\r
616 void prouts(char *fmt, ...) {
\r
618 char *s, buf[BUFSIZ];
\r
619 /* print slowly! */
\r
622 vsprintf(buf, fmt, ap);
\r
625 for (s = buf; *s; s++) {
\r
626 endTime = clock() + CLOCKS_PER_SEC*0.05;
\r
627 while (clock() < endTime) ;
\r
636 prout("Beg your pardon, Captain?");
\r
639 int isit(char *s) {
\r
640 /* New function -- compares s to scaned citem and returns true if it
\r
641 matches to the length of s */
\r
643 return strncmp(s, citem, max(1, strlen(citem))) == 0;
\r
648 void debugme(void) {
\r
649 proutn("Reset levels? ");
\r
651 if (energy < inenrg) energy = inenrg;
\r
656 proutn("Reset damage? ");
\r
659 for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;
\r
662 proutn("Toggle idebug? ");
\r
665 if (idebug) prout("Debug output ON");
\r
666 else prout("Debug output OFF");
\r
668 proutn("Cause selective damage? ");
\r
671 for (i=1; i <= NDEVICES; i++) {
\r
677 if (key == IHALPHA && isit("y")) {
\r
679 if (i == DRADIO) stdamtim = game.state.date;
\r
683 proutn("Examine/change events? ");
\r
686 for (i = 1; i < NEVENTS; i++) {
\r
688 if (future[i] == 1e30) continue;
\r
690 case FSNOVA: proutn("Supernova "); break;
\r
691 case FTBEAM: proutn("T Beam "); break;
\r
692 case FSNAP: proutn("Snapshot "); break;
\r
693 case FBATTAK: proutn("Base Attack "); break;
\r
694 case FCDBAS: proutn("Base Destroy "); break;
\r
695 case FSCMOVE: proutn("SC Move "); break;
\r
696 case FSCDBAS: proutn("SC Base Destroy "); break;
\r
698 proutn("%.2f", future[i]-game.state.date);
\r
702 if (key == IHREAL) {
\r
703 future[i] = game.state.date + aaitem;
\r