1 #define INCLUDED // Define externs here
\r
12 static char line[128], *linep = line;
\r
13 static int linecount; /* for paging */
\r
14 static int screenheight = 24;
\r
16 static void clearscreen(void);
\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[] = {
\r
91 #define NUMCOMMANDS sizeof(commands)/sizeof(commands[0])
\r
93 static void listCommands(int x) {
\r
94 prout(" SRSCAN MOVE PHASERS CALL\n"
\r
95 " STATUS IMPULSE PHOTONS ABANDON\n"
\r
96 " LRSCAN WARP SHIELDS DESTRUCT\n"
\r
97 " CHART REST DOCK QUIT\n"
\r
98 " DAMAGES REPORT SENSORS ORBIT\n"
\r
99 " TRANSPORT MINE CRYSTALS SHUTTLE\n"
\r
100 " PLANETS REQUEST DEATHRAY FREEZE\n"
\r
101 " COMPUTER EMEXIT PROBE COMMANDS");
\r
102 if (x) prout(" HELP");
\r
105 static void helpme(void) {
\r
107 char cmdbuf[32], *cp;
\r
110 /* Give help on commands */
\r
114 if (key == IHEOL) {
\r
115 proutn("Help on what command?");
\r
118 if (key == IHEOL) return;
\r
119 for (i = 0; i < NUMCOMMANDS; i++) {
\r
120 if (strcmp(commands[i], citem)==0) break;
\r
122 if (i != NUMCOMMANDS) break;
\r
124 prout("Valid commands:");
\r
125 listCommands(FALSE);
\r
131 strcpy(cmdbuf, " ABBREV");
\r
134 for (j = 0; commands[i][j]; j++)
\r
135 cmdbuf[j] = toupper(commands[i][j]);
\r
138 fp = fopen("sst.doc", "r");
\r
140 prout("Spock- \"Captain, that information is missing from the");
\r
141 prout(" computer. You need to find SST.DOC and put it in the");
\r
142 prout(" current directory.\"");
\r
146 if (fgets(linebuf, sizeof(linebuf), fp) == NULL) {
\r
147 prout("Spock- \"Captain, there is no information on that command.\"");
\r
151 if (linebuf[0] == '%' && linebuf[1] == '%'&& linebuf[2] == ' ') {
\r
152 for (cp = linebuf+3; isspace(*cp); cp++)
\r
154 linebuf[strlen(linebuf)-1] = '\0';
\r
155 if (strcmp(cp, cmdbuf) == 0)
\r
161 prout("Spock- \"Captain, I've found the following information:\"");
\r
164 while (fgets(linebuf, sizeof(linebuf),fp)) {
\r
165 if (strstr(linebuf, "******"))
\r
167 /* use fputs here to avoid % expansion */
\r
168 fputs(linebuf, stdout);
\r
173 static void makemoves(void) {
\r
176 while (TRUE) { /* command loop */
\r
181 while (TRUE) { /* get a command */
\r
184 proutn("COMMAND> ");
\r
185 if (scan() == IHEOL) continue;
\r
186 for (i=0; i < 26; i++)
\r
187 if (isit(commands[i]))
\r
190 for (; i < NUMCOMMANDS; i++)
\r
191 if (strcmp(commands[i], citem) == 0) break;
\r
192 if (i < NUMCOMMANDS) break;
\r
195 prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");
\r
196 listCommands(TRUE);
\r
198 else prout("UNRECOGNIZED COMMAND.");
\r
200 switch (i) { /* command switch */
\r
209 if (ididit) hitme = TRUE;
\r
213 if (ididit) hitme = TRUE;
\r
239 if (ididit) hitme = TRUE;
\r
247 case 13: // sensors
\r
252 if (ididit) hitme = TRUE;
\r
254 case 15: // transport "beam"
\r
259 if (ididit) hitme = TRUE;
\r
261 case 17: // crystals
\r
264 case 18: // shuttle
\r
266 if (ididit) hitme = TRUE;
\r
268 case 19: // Planet list
\r
271 case 20: // Status information
\r
274 case 21: // Game Report
\r
277 case 22: // use COMPUTER!
\r
281 listCommands(TRUE);
\r
283 case 24: // Emergency exit
\r
284 clearscreen(); // Hide screen
\r
285 freeze(TRUE); // forced save
\r
286 exit(1); // And quick exit
\r
289 probe(); // Launch probe
\r
291 case 26: // Abandon Ship
\r
294 case 27: // Self Destruct
\r
297 case 28: // Save Game
\r
300 prout("WARNING--Frozen games produce no plaques!");
\r
302 case 29: // Try a desparation measure
\r
304 if (ididit) hitme = TRUE;
\r
306 case 30: // What do we want for debug???
\r
311 case 31: // Call for help
\r
315 alldone = 1; // quit the game
\r
317 if (idebug) score();
\r
321 helpme(); // get help
\r
325 if (alldone) break; // Game has ended
\r
327 if (idebug) prout("2500");
\r
331 if (alldone) break; // Events did us in
\r
333 if (game.state.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!
\r
337 if (nenhere == 0) movetho();
\r
338 if (hitme && justin==0) {
\r
340 if (alldone) break;
\r
341 if (game.state.galaxy[quadx][quady] == 1000) { // went NOVA!
\r
349 if (alldone) break;
\r
354 int main(int argc, char **argv) {
\r
359 char *LINES = getenv("LINES");
\r
362 screenheight = atoi(LINES);
\r
365 fromcommandline = 1;
\r
367 while (--argc > 0) {
\r
368 strcat(line, *(++argv));
\r
372 else fromcommandline = 0;
\r
375 while (TRUE) { /* Play a game */
\r
386 if (tourn && alldone) {
\r
387 proutn("Do you want your score recorded?");
\r
393 proutn("Do you want to play again?");
\r
397 prout("May the Great Bird of the Galaxy roost upon your home planet.");
\r
401 void cramen(int i) {
\r
402 /* return an enemy */
\r
406 case IHR: s = "Romulan"; break;
\r
407 case IHK: s = "Klingon"; break;
\r
408 case IHC: s = "Commander"; break;
\r
409 case IHS: s = "Super-commander"; break;
\r
410 case IHSTAR: s = "Star"; break;
\r
411 case IHP: s = "Planet"; break;
\r
412 case IHB: s = "Starbase"; break;
\r
413 case IHBLANK: s = "Black hole"; break;
\r
414 case IHT: s = "Tholian"; break;
\r
415 case IHWEB: s = "Tholian web"; break;
\r
416 default: s = "Unknown??"; break;
\r
421 char *cramlc(enum loctype key, int x, int y) {
\r
422 static char buf[32];
\r
424 if (key == quadrant) strcpy(buf, "Quadrant ");
\r
425 else if (key == sector) strcpy(buf, "Sector ");
\r
426 sprintf(buf+strlen(buf), "%d-%d", x, y);
\r
430 void crmena(int i, int enemy, int key, int x, int y) {
\r
431 if (i == 1) proutn("***");
\r
434 proutn(cramlc(key, x, y));
\r
437 void crmshp(void) {
\r
440 case IHE: s = "Enterprise"; break;
\r
441 case IHF: s = "Faerie Queene"; break;
\r
442 default: s = "Ship???"; break;
\r
448 prouts("******************************************************");
\r
452 double expran(double avrage) {
\r
453 return -avrage*log(1e-7 + Rand());
\r
456 double Rand(void) {
\r
457 return rand()/(1.0 + (double)RAND_MAX);
\r
460 void iran8(int *i, int *j) {
\r
461 *i = Rand()*8.0 + 1.0;
\r
462 *j = Rand()*8.0 + 1.0;
\r
465 void iran10(int *i, int *j) {
\r
466 *i = Rand()*10.0 + 1.0;
\r
467 *j = Rand()*10.0 + 1.0;
\r
477 /* return IHEOL next time */
\r
493 // Read a line if nothing here
\r
495 if (linep != line) {
\r
499 fgets(line, sizeof(line), stdin);
\r
500 line[strlen(line)-1] = '\0';
\r
503 // Skip leading white space
\r
504 while (*linep == ' ') linep++;
\r
510 if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {
\r
511 // treat as a number
\r
512 if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
\r
513 linep = line; // Invalid numbers are ignored
\r
525 while (*linep && *linep!=' ') {
\r
526 if ((cp - citem) < 9) *cp++ = tolower(*linep);
\r
538 if (*citem == 'y') return TRUE;
\r
539 if (*citem == 'n') return FALSE;
\r
540 proutn("Please answer with \"Y\" or \"N\":");
\r
544 double square(double i) { return i*i; }
\r
546 static void clearscreen(void) {
\r
547 /* Somehow we need to clear the screen */
\r
548 #ifdef __BORLANDC__
\r
549 extern void clrscr(void);
\r
552 proutn("\033[2J"); /* Hope for an ANSI display */
\r
556 /* We will pull these out in case we want to do something special later */
\r
558 void pause(int i) {
\r
562 prout("[ANOUNCEMENT ARRIVING...]");
\r
564 prout("[IMPORTANT ANNOUNCEMENT ARRIVING -- HIT SPACE BAR TO CONTINUE]");
\r
569 proutn("[CONTINUE?]");
\r
571 proutn("[HIT SPACE BAR TO CONTINUE]");
\r
585 if (linecount >= screenheight)
\r
593 void proutn(char *fmt, ...) {
\r
600 void prout(char *fmt, ...) {
\r
608 void prouts(char *fmt, ...) {
\r
610 char *s, buf[BUFSIZ];
\r
611 /* print slowly! */
\r
614 vsprintf(buf, fmt, ap);
\r
617 for (s = buf; *s; s++) {
\r
618 endTime = clock() + CLOCKS_PER_SEC*0.05;
\r
619 while (clock() < endTime) ;
\r
628 prout("Beg your pardon, Captain?");
\r
631 int isit(char *s) {
\r
632 /* New function -- compares s to scaned citem and returns true if it
\r
633 matches to the length of s */
\r
635 return strncmp(s, citem, max(1, strlen(citem))) == 0;
\r
640 void debugme(void) {
\r
641 proutn("Reset levels? ");
\r
643 if (energy < inenrg) energy = inenrg;
\r
648 proutn("Reset damage? ");
\r
651 for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;
\r
654 proutn("Toggle idebug? ");
\r
657 if (idebug) prout("Debug output ON");
\r
658 else prout("Debug output OFF");
\r
660 proutn("Cause selective damage? ");
\r
663 for (i=1; i <= NDEVICES; i++) {
\r
669 if (key == IHALPHA && isit("y")) {
\r
671 if (i == DRADIO) stdamtim = game.state.date;
\r
675 proutn("Examine/change events? ");
\r
678 for (i = 1; i < NEVENTS; i++) {
\r
680 if (future[i] == 1e30) continue;
\r
682 case FSNOVA: proutn("Supernova "); break;
\r
683 case FTBEAM: proutn("T Beam "); break;
\r
684 case FSNAP: proutn("Snapshot "); break;
\r
685 case FBATTAK: proutn("Base Attack "); break;
\r
686 case FCDBAS: proutn("Base Destroy "); break;
\r
687 case FSCMOVE: proutn("SC Move "); break;
\r
688 case FSCDBAS: proutn("SC Base Destroy "); break;
\r
690 proutn("%.2f", future[i]-game.state.date);
\r
694 if (key == IHREAL) {
\r
695 future[i] = game.state.date + aaitem;
\r