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 commandhook(commands[i], TRUE);
\r
194 switch (i) { /* command switch */
\r
203 if (ididit) hitme = TRUE;
\r
207 if (ididit) hitme = TRUE;
\r
221 if (ididit) attack(0);
\r
234 if (ididit) hitme = TRUE;
\r
242 case 13: // sensors
\r
247 if (ididit) hitme = TRUE;
\r
249 case 15: // transport "beam"
\r
254 if (ididit) hitme = TRUE;
\r
256 case 17: // crystals
\r
259 case 18: // shuttle
\r
261 if (ididit) hitme = TRUE;
\r
263 case 19: // Planet list
\r
266 case 20: // Status information
\r
269 case 21: // Game Report
\r
272 case 22: // use COMPUTER!
\r
276 listCommands(TRUE);
\r
278 case 24: // Emergency exit
\r
279 clearscreen(); // Hide screen
\r
280 freeze(TRUE); // forced save
\r
281 exit(1); // And quick exit
\r
284 probe(); // Launch probe
\r
286 case 26: // Abandon Ship
\r
289 case 27: // Self Destruct
\r
292 case 28: // Save Game
\r
295 prout("WARNING--Frozen games produce no plaques!");
\r
297 case 29: // Try a desparation measure
\r
299 if (ididit) hitme = TRUE;
\r
301 case 30: // What do we want for debug???
\r
306 case 31: // Call for help
\r
310 alldone = 1; // quit the game
\r
312 if (idebug) score();
\r
316 helpme(); // get help
\r
319 commandhook(commands[i], FALSE);
\r
321 if (alldone) break; // Game has ended
\r
323 if (idebug) prout("2500");
\r
327 if (alldone) break; // Events did us in
\r
329 if (game.state.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!
\r
333 if (nenhere == 0) movetho();
\r
334 if (hitme && justin==0) {
\r
336 if (alldone) break;
\r
337 if (game.state.galaxy[quadx][quady] == 1000) { // went NOVA!
\r
345 if (alldone) break;
\r
350 int main(int argc, char **argv) {
\r
351 int i, option, usecurses = TRUE;
\r
355 while ((option = getopt(argc, argv, "t")) != -1) {
\r
361 fprintf(stderr, "usage: sst [-t] [startcommand...].\n");
\r
366 iostart(usecurses);
\r
369 for (i = optind; i < argc; i++) {
\r
370 strcat(line, argv[i]);
\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
396 puts("May the Great Bird of the Galaxy roost upon your home planet.");
\r
400 void cramen(int i) {
\r
401 /* return an enemy */
\r
405 case IHR: s = "Romulan"; break;
\r
406 case IHK: s = "Klingon"; break;
\r
407 case IHC: s = "Commander"; break;
\r
408 case IHS: s = "Super-commander"; break;
\r
409 case IHSTAR: s = "Star"; break;
\r
410 case IHP: s = "Planet"; break;
\r
411 case IHB: s = "Starbase"; break;
\r
412 case IHBLANK: s = "Black hole"; break;
\r
413 case IHT: s = "Tholian"; break;
\r
414 case IHWEB: s = "Tholian web"; break;
\r
415 case IHQUEST: s = "Stranger"; 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
476 /* return IHEOL next time */
\r
489 // Read a line if nothing here
\r
491 if (linep != line) {
\r
495 getline(line, sizeof(line));
\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
508 if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
\r
509 linep = line; // Invalid numbers are ignored
\r
521 while (*linep && *linep!=' ') {
\r
522 if ((cp - citem) < 9) *cp++ = tolower(*linep);
\r
534 if (*citem == 'y') return TRUE;
\r
535 if (*citem == 'n') return FALSE;
\r
536 proutn("Please answer with \"Y\" or \"N\":");
\r
543 prout("Beg your pardon, Captain?");
\r
546 int isit(char *s) {
\r
547 /* New function -- compares s to scaned citem and returns true if it
\r
548 matches to the length of s */
\r
550 return strncmp(s, citem, max(1, strlen(citem))) == 0;
\r
555 void debugme(void) {
\r
556 proutn("Reset levels? ");
\r
558 if (energy < inenrg) energy = inenrg;
\r
563 proutn("Reset damage? ");
\r
566 for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;
\r
569 proutn("Toggle idebug? ");
\r
572 if (idebug) prout("Debug output ON");
\r
573 else prout("Debug output OFF");
\r
575 proutn("Cause selective damage? ");
\r
578 for (i=1; i <= NDEVICES; i++) {
\r
584 if (key == IHALPHA && isit("y")) {
\r
586 if (i == DRADIO) stdamtim = game.state.date;
\r
590 proutn("Examine/change events? ");
\r
593 for (i = 1; i < NEVENTS; i++) {
\r
595 if (future[i] == 1e30) continue;
\r
597 case FSNOVA: proutn("Supernova "); break;
\r
598 case FTBEAM: proutn("T Beam "); break;
\r
599 case FSNAP: proutn("Snapshot "); break;
\r
600 case FBATTAK: proutn("Base Attack "); break;
\r
601 case FCDBAS: proutn("Base Destroy "); break;
\r
602 case FSCMOVE: proutn("SC Move "); break;
\r
603 case FSCDBAS: proutn("SC Base Destroy "); break;
\r
605 proutn("%.2f", future[i]-game.state.date);
\r
609 if (key == IHREAL) {
\r
610 future[i] = game.state.date + aaitem;
\r