1 #define INCLUDED // Define externs here
\r
7 #define SSTDOC "sst.doc"
\r
10 static char line[128], *linep = line;
\r
12 /* Compared to original version, I've changed the "help" command to
\r
13 "call" and the "terminate" command to "quit" to better match
\r
14 user expectations. The DECUS version apparently made those changes
\r
15 as well as changing "freeze" to "save". However I like "freeze".
\r
17 When I got a later version of Super Star Trek that I was converting
\r
18 from, I added the emexit command.
\r
20 That later version also mentions srscan and lrscan working when
\r
21 docked (using the starbase's scanners), so I made some changes here
\r
22 to do this (and indicating that fact to the player), and then realized
\r
23 the base would have a subspace radio as well -- doing a Chart when docked
\r
24 updates the star chart, and all radio reports will be heard. The Dock
\r
25 command will also give a report if a base is under attack.
\r
27 Movecom no longer reports movement if sensors are damaged so you wouldn't
\r
32 1. Better base positioning at startup
\r
34 2. deathray improvement (but keeping original failure alternatives)
\r
38 4. Enemies can ram the Enterprise. Regular Klingons and Romulans can
\r
39 move in Expert and Emeritus games. This code could use improvement.
\r
41 5. The deep space probe looks interesting! DECUS version
\r
43 6. Perhaps cloaking to be added later? BSD version
\r
49 static char *commands[] = {
\r
85 #define NUMCOMMANDS sizeof(commands)/sizeof(commands[0])
\r
87 static void listCommands(int x) {
\r
88 prout(" SRSCAN MOVE PHASERS CALL\n"
\r
89 " STATUS IMPULSE PHOTONS ABANDON\n"
\r
90 " LRSCAN WARP SHIELDS DESTRUCT\n"
\r
91 " CHART REST DOCK QUIT\n"
\r
92 " DAMAGES REPORT SENSORS ORBIT\n"
\r
93 " TRANSPORT MINE CRYSTALS SHUTTLE\n"
\r
94 " PLANETS REQUEST DEATHRAY FREEZE\n"
\r
95 " COMPUTER EMEXIT PROBE COMMANDS");
\r
96 if (x) prout(" HELP");
\r
99 static void helpme(void) {
\r
101 char cmdbuf[32], *cp;
\r
104 /* Give help on commands */
\r
108 if (key == IHEOL) {
\r
109 proutn("Help on what command?");
\r
112 if (key == IHEOL) return;
\r
113 for (i = 0; i < NUMCOMMANDS; i++) {
\r
114 if (strcmp(commands[i], citem)==0) break;
\r
116 if (i != NUMCOMMANDS) break;
\r
118 prout("Valid commands:");
\r
119 listCommands(FALSE);
\r
125 strcpy(cmdbuf, " ABBREV");
\r
128 for (j = 0; commands[i][j]; j++)
\r
129 cmdbuf[j] = toupper(commands[i][j]);
\r
132 fp = fopen(SSTDOC, "r");
\r
134 prout("Spock- \"Captain, that information is missing from the");
\r
135 prout(" computer. You need to find SST.DOC and put it in the");
\r
136 prout(" current directory.\"");
\r
140 if (fgets(linebuf, sizeof(linebuf), fp) == NULL) {
\r
141 prout("Spock- \"Captain, there is no information on that command.\"");
\r
145 if (linebuf[0] == '%' && linebuf[1] == '%'&& linebuf[2] == ' ') {
\r
146 for (cp = linebuf+3; isspace(*cp); cp++)
\r
148 linebuf[strlen(linebuf)-1] = '\0';
\r
149 if (strcmp(cp, cmdbuf) == 0)
\r
155 prout("Spock- \"Captain, I've found the following information:\"");
\r
158 while (fgets(linebuf, sizeof(linebuf),fp)) {
\r
159 if (strstr(linebuf, "******"))
\r
166 static void makemoves(void) {
\r
169 while (TRUE) { /* command loop */
\r
174 while (TRUE) { /* get a command */
\r
177 proutn("COMMAND> ");
\r
178 if (scan() == IHEOL) continue;
\r
179 for (i=0; i < 26; i++)
\r
180 if (isit(commands[i]))
\r
183 for (; i < NUMCOMMANDS; i++)
\r
184 if (strcmp(commands[i], citem) == 0) break;
\r
185 if (i < NUMCOMMANDS) break;
\r
188 prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");
\r
189 listCommands(TRUE);
\r
191 else prout("UNRECOGNIZED COMMAND.");
\r
193 switch (i) { /* command switch */
\r
202 if (ididit) hitme = TRUE;
\r
206 if (ididit) hitme = TRUE;
\r
232 if (ididit) hitme = TRUE;
\r
240 case 13: // sensors
\r
245 if (ididit) hitme = TRUE;
\r
247 case 15: // transport "beam"
\r
252 if (ididit) hitme = TRUE;
\r
254 case 17: // crystals
\r
257 case 18: // shuttle
\r
259 if (ididit) hitme = TRUE;
\r
261 case 19: // Planet list
\r
264 case 20: // Status information
\r
267 case 21: // Game Report
\r
270 case 22: // use COMPUTER!
\r
274 listCommands(TRUE);
\r
276 case 24: // Emergency exit
\r
277 clearscreen(); // Hide screen
\r
278 freeze(TRUE); // forced save
\r
279 exit(1); // And quick exit
\r
282 probe(); // Launch probe
\r
284 case 26: // Abandon Ship
\r
287 case 27: // Self Destruct
\r
290 case 28: // Save Game
\r
293 prout("WARNING--Frozen games produce no plaques!");
\r
295 case 29: // Try a desparation measure
\r
297 if (ididit) hitme = TRUE;
\r
299 case 30: // What do we want for debug???
\r
304 case 31: // Call for help
\r
308 alldone = 1; // quit the game
\r
310 if (idebug) score();
\r
314 helpme(); // get help
\r
318 if (alldone) break; // Game has ended
\r
320 if (idebug) prout("2500");
\r
324 if (alldone) break; // Events did us in
\r
326 if (game.state.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!
\r
330 if (nenhere == 0) movetho();
\r
331 if (hitme && justin==0) {
\r
333 if (alldone) break;
\r
334 if (game.state.galaxy[quadx][quady] == 1000) { // went NOVA!
\r
342 if (alldone) break;
\r
347 int main(int argc, char **argv) {
\r
348 int i, option, usecurses = TRUE;
\r
352 while ((option = getopt(argc, argv, "t")) != -1) {
\r
358 fprintf(stderr, "usage: sst [-t] [startcommand...].\n");
\r
363 iostart(usecurses);
\r
366 for (i = optind; i < argc; i++) {
\r
367 strcat(line, argv[i]);
\r
370 while (TRUE) { /* Play a game */
\r
371 setup(line[0] == '\0');
\r
381 if (tourn && alldone) {
\r
382 proutn("Do you want your score recorded?");
\r
388 proutn("Do you want to play again?");
\r
393 puts("May the Great Bird of the Galaxy roost upon your home planet.");
\r
397 void cramen(int i) {
\r
398 /* return an enemy */
\r
402 case IHR: s = "Romulan"; break;
\r
403 case IHK: s = "Klingon"; break;
\r
404 case IHC: s = "Commander"; break;
\r
405 case IHS: s = "Super-commander"; break;
\r
406 case IHSTAR: s = "Star"; break;
\r
407 case IHP: s = "Planet"; break;
\r
408 case IHB: s = "Starbase"; break;
\r
409 case IHBLANK: s = "Black hole"; break;
\r
410 case IHT: s = "Tholian"; break;
\r
411 case IHWEB: s = "Tholian web"; break;
\r
412 default: s = "Unknown??"; break;
\r
417 char *cramlc(enum loctype key, int x, int y) {
\r
418 static char buf[32];
\r
420 if (key == quadrant) strcpy(buf, "Quadrant ");
\r
421 else if (key == sector) strcpy(buf, "Sector ");
\r
422 sprintf(buf+strlen(buf), "%d-%d", x, y);
\r
426 void crmena(int i, int enemy, int key, int x, int y) {
\r
427 if (i == 1) proutn("***");
\r
430 proutn(cramlc(key, x, y));
\r
433 void crmshp(void) {
\r
436 case IHE: s = "Enterprise"; break;
\r
437 case IHF: s = "Faerie Queene"; break;
\r
438 default: s = "Ship???"; break;
\r
444 prouts("******************************************************");
\r
448 double expran(double avrage) {
\r
449 return -avrage*log(1e-7 + Rand());
\r
452 double Rand(void) {
\r
453 return rand()/(1.0 + (double)RAND_MAX);
\r
456 void iran8(int *i, int *j) {
\r
457 *i = Rand()*8.0 + 1.0;
\r
458 *j = Rand()*8.0 + 1.0;
\r
461 void iran10(int *i, int *j) {
\r
462 *i = Rand()*10.0 + 1.0;
\r
463 *j = Rand()*10.0 + 1.0;
\r
472 /* return IHEOL next time */
\r
485 // Read a line if nothing here
\r
487 if (linep != line) {
\r
491 getline(line, sizeof(line));
\r
494 // Skip leading white space
\r
495 while (*linep == ' ') linep++;
\r
501 if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {
\r
502 // treat as a number
\r
503 if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
\r
504 linep = line; // Invalid numbers are ignored
\r
516 while (*linep && *linep!=' ') {
\r
517 if ((cp - citem) < 9) *cp++ = tolower(*linep);
\r
529 if (*citem == 'y') return TRUE;
\r
530 if (*citem == 'n') return FALSE;
\r
531 proutn("Please answer with \"Y\" or \"N\":");
\r
535 double square(double i) { return i*i; }
\r
540 prout("Beg your pardon, Captain?");
\r
543 int isit(char *s) {
\r
544 /* New function -- compares s to scaned citem and returns true if it
\r
545 matches to the length of s */
\r
547 return strncmp(s, citem, max(1, strlen(citem))) == 0;
\r
552 void debugme(void) {
\r
553 proutn("Reset levels? ");
\r
555 if (energy < inenrg) energy = inenrg;
\r
560 proutn("Reset damage? ");
\r
563 for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;
\r
566 proutn("Toggle idebug? ");
\r
569 if (idebug) prout("Debug output ON");
\r
570 else prout("Debug output OFF");
\r
572 proutn("Cause selective damage? ");
\r
575 for (i=1; i <= NDEVICES; i++) {
\r
581 if (key == IHALPHA && isit("y")) {
\r
583 if (i == DRADIO) stdamtim = game.state.date;
\r
587 proutn("Examine/change events? ");
\r
590 for (i = 1; i < NEVENTS; i++) {
\r
592 if (future[i] == 1e30) continue;
\r
594 case FSNOVA: proutn("Supernova "); break;
\r
595 case FTBEAM: proutn("T Beam "); break;
\r
596 case FSNAP: proutn("Snapshot "); break;
\r
597 case FBATTAK: proutn("Base Attack "); break;
\r
598 case FCDBAS: proutn("Base Destroy "); break;
\r
599 case FSCMOVE: proutn("SC Move "); break;
\r
600 case FSCDBAS: proutn("SC Base Destroy "); break;
\r
602 proutn("%.2f", future[i]-game.state.date);
\r
606 if (key == IHREAL) {
\r
607 future[i] = game.state.date + aaitem;
\r