1 #define INCLUDED // Define externs here
\r
6 #define SSTDOC "sst.doc"
\r
9 static char line[128], *linep = line;
\r
11 /* Compared to original version, I've changed the "help" command to
\r
12 "call" and the "terminate" command to "quit" to better match
\r
13 user expectations. The DECUS version apparently made those changes
\r
14 as well as changing "freeze" to "save". However I like "freeze".
\r
16 When I got a later version of Super Star Trek that I was converting
\r
17 from, I added the emexit command.
\r
19 That later version also mentions srscan and lrscan working when
\r
20 docked (using the starbase's scanners), so I made some changes here
\r
21 to do this (and indicating that fact to the player), and then realized
\r
22 the base would have a subspace radio as well -- doing a Chart when docked
\r
23 updates the star chart, and all radio reports will be heard. The Dock
\r
24 command will also give a report if a base is under attack.
\r
26 Movecom no longer reports movement if sensors are damaged so you wouldn't
\r
31 1. Better base positioning at startup
\r
33 2. deathray improvement (but keeping original failure alternatives)
\r
37 4. Enemies can ram the Enterprise. Regular Klingons and Romulans can
\r
38 move in Expert and Emeritus games. This code could use improvement.
\r
40 5. The deep space probe looks interesting! DECUS version
\r
42 6. Perhaps cloaking to be added later? BSD version
\r
48 static char *commands[] = {
\r
84 #define NUMCOMMANDS sizeof(commands)/sizeof(commands[0])
\r
86 static void listCommands(int x) {
\r
87 prout(" SRSCAN MOVE PHASERS CALL\n"
\r
88 " STATUS IMPULSE PHOTONS ABANDON\n"
\r
89 " LRSCAN WARP SHIELDS DESTRUCT\n"
\r
90 " CHART REST DOCK QUIT\n"
\r
91 " DAMAGES REPORT SENSORS ORBIT\n"
\r
92 " TRANSPORT MINE CRYSTALS SHUTTLE\n"
\r
93 " PLANETS REQUEST DEATHRAY FREEZE\n"
\r
94 " COMPUTER EMEXIT PROBE COMMANDS");
\r
95 if (x) prout(" HELP");
\r
98 static void helpme(void) {
\r
100 char cmdbuf[32], *cp;
\r
103 /* Give help on commands */
\r
107 if (key == IHEOL) {
\r
108 proutn("Help on what command?");
\r
111 if (key == IHEOL) return;
\r
112 for (i = 0; i < NUMCOMMANDS; i++) {
\r
113 if (strcmp(commands[i], citem)==0) break;
\r
115 if (i != NUMCOMMANDS) break;
\r
117 prout("Valid commands:");
\r
118 listCommands(FALSE);
\r
124 strcpy(cmdbuf, " ABBREV");
\r
127 for (j = 0; commands[i][j]; j++)
\r
128 cmdbuf[j] = toupper(commands[i][j]);
\r
131 fp = fopen(SSTDOC, "r");
\r
133 prout("Spock- \"Captain, that information is missing from the");
\r
134 prout(" computer. You need to find SST.DOC and put it in the");
\r
135 prout(" current directory.\"");
\r
139 if (fgets(linebuf, sizeof(linebuf), fp) == NULL) {
\r
140 prout("Spock- \"Captain, there is no information on that command.\"");
\r
144 if (linebuf[0] == '%' && linebuf[1] == '%'&& linebuf[2] == ' ') {
\r
145 for (cp = linebuf+3; isspace(*cp); cp++)
\r
147 linebuf[strlen(linebuf)-1] = '\0';
\r
148 if (strcmp(cp, cmdbuf) == 0)
\r
154 prout("Spock- \"Captain, I've found the following information:\"");
\r
157 while (fgets(linebuf, sizeof(linebuf),fp)) {
\r
158 if (strstr(linebuf, "******"))
\r
165 static void makemoves(void) {
\r
168 while (TRUE) { /* command loop */
\r
173 while (TRUE) { /* get a command */
\r
176 proutn("COMMAND> ");
\r
177 if (scan() == IHEOL) continue;
\r
178 for (i=0; i < 26; i++)
\r
179 if (isit(commands[i]))
\r
182 for (; i < NUMCOMMANDS; i++)
\r
183 if (strcmp(commands[i], citem) == 0) break;
\r
184 if (i < NUMCOMMANDS) break;
\r
187 prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");
\r
188 listCommands(TRUE);
\r
190 else prout("UNRECOGNIZED COMMAND.");
\r
192 switch (i) { /* command switch */
\r
201 if (ididit) hitme = TRUE;
\r
205 if (ididit) hitme = TRUE;
\r
231 if (ididit) hitme = TRUE;
\r
239 case 13: // sensors
\r
244 if (ididit) hitme = TRUE;
\r
246 case 15: // transport "beam"
\r
251 if (ididit) hitme = TRUE;
\r
253 case 17: // crystals
\r
256 case 18: // shuttle
\r
258 if (ididit) hitme = TRUE;
\r
260 case 19: // Planet list
\r
263 case 20: // Status information
\r
266 case 21: // Game Report
\r
269 case 22: // use COMPUTER!
\r
273 listCommands(TRUE);
\r
275 case 24: // Emergency exit
\r
276 clearscreen(); // Hide screen
\r
277 freeze(TRUE); // forced save
\r
278 exit(1); // And quick exit
\r
281 probe(); // Launch probe
\r
283 case 26: // Abandon Ship
\r
286 case 27: // Self Destruct
\r
289 case 28: // Save Game
\r
292 prout("WARNING--Frozen games produce no plaques!");
\r
294 case 29: // Try a desparation measure
\r
296 if (ididit) hitme = TRUE;
\r
298 case 30: // What do we want for debug???
\r
303 case 31: // Call for help
\r
307 alldone = 1; // quit the game
\r
309 if (idebug) score();
\r
313 helpme(); // get help
\r
317 if (alldone) break; // Game has ended
\r
319 if (idebug) prout("2500");
\r
323 if (alldone) break; // Events did us in
\r
325 if (game.state.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!
\r
329 if (nenhere == 0) movetho();
\r
330 if (hitme && justin==0) {
\r
332 if (alldone) break;
\r
333 if (game.state.galaxy[quadx][quady] == 1000) { // went NOVA!
\r
341 if (alldone) break;
\r
346 int main(int argc, char **argv) {
\r
355 while (--argc > 0) {
\r
356 strcat(line, *(++argv));
\r
361 while (TRUE) { /* Play a game */
\r
362 setup(line[0] == '\0');
\r
372 if (tourn && alldone) {
\r
373 proutn("Do you want your score recorded?");
\r
379 proutn("Do you want to play again?");
\r
384 puts("May the Great Bird of the Galaxy roost upon your home planet.");
\r
388 void cramen(int i) {
\r
389 /* return an enemy */
\r
393 case IHR: s = "Romulan"; break;
\r
394 case IHK: s = "Klingon"; break;
\r
395 case IHC: s = "Commander"; break;
\r
396 case IHS: s = "Super-commander"; break;
\r
397 case IHSTAR: s = "Star"; break;
\r
398 case IHP: s = "Planet"; break;
\r
399 case IHB: s = "Starbase"; break;
\r
400 case IHBLANK: s = "Black hole"; break;
\r
401 case IHT: s = "Tholian"; break;
\r
402 case IHWEB: s = "Tholian web"; break;
\r
403 default: s = "Unknown??"; break;
\r
408 char *cramlc(enum loctype key, int x, int y) {
\r
409 static char buf[32];
\r
411 if (key == quadrant) strcpy(buf, "Quadrant ");
\r
412 else if (key == sector) strcpy(buf, "Sector ");
\r
413 sprintf(buf+strlen(buf), "%d-%d", x, y);
\r
417 void crmena(int i, int enemy, int key, int x, int y) {
\r
418 if (i == 1) proutn("***");
\r
421 proutn(cramlc(key, x, y));
\r
424 void crmshp(void) {
\r
427 case IHE: s = "Enterprise"; break;
\r
428 case IHF: s = "Faerie Queene"; break;
\r
429 default: s = "Ship???"; break;
\r
435 prouts("******************************************************");
\r
439 double expran(double avrage) {
\r
440 return -avrage*log(1e-7 + Rand());
\r
443 double Rand(void) {
\r
444 return rand()/(1.0 + (double)RAND_MAX);
\r
447 void iran8(int *i, int *j) {
\r
448 *i = Rand()*8.0 + 1.0;
\r
449 *j = Rand()*8.0 + 1.0;
\r
452 void iran10(int *i, int *j) {
\r
453 *i = Rand()*10.0 + 1.0;
\r
454 *j = Rand()*10.0 + 1.0;
\r
463 /* return IHEOL next time */
\r
476 // Read a line if nothing here
\r
478 if (linep != line) {
\r
482 getline(line, sizeof(line));
\r
483 line[strlen(line)-1] = '\0';
\r
486 // Skip leading white space
\r
487 while (*linep == ' ') linep++;
\r
493 if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {
\r
494 // treat as a number
\r
495 if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
\r
496 linep = line; // Invalid numbers are ignored
\r
508 while (*linep && *linep!=' ') {
\r
509 if ((cp - citem) < 9) *cp++ = tolower(*linep);
\r
521 if (*citem == 'y') return TRUE;
\r
522 if (*citem == 'n') return FALSE;
\r
523 proutn("Please answer with \"Y\" or \"N\":");
\r
527 double square(double i) { return i*i; }
\r
532 prout("Beg your pardon, Captain?");
\r
535 int isit(char *s) {
\r
536 /* New function -- compares s to scaned citem and returns true if it
\r
537 matches to the length of s */
\r
539 return strncmp(s, citem, max(1, strlen(citem))) == 0;
\r
544 void debugme(void) {
\r
545 proutn("Reset levels? ");
\r
547 if (energy < inenrg) energy = inenrg;
\r
552 proutn("Reset damage? ");
\r
555 for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;
\r
558 proutn("Toggle idebug? ");
\r
561 if (idebug) prout("Debug output ON");
\r
562 else prout("Debug output OFF");
\r
564 proutn("Cause selective damage? ");
\r
567 for (i=1; i <= NDEVICES; i++) {
\r
573 if (key == IHALPHA && isit("y")) {
\r
575 if (i == DRADIO) stdamtim = game.state.date;
\r
579 proutn("Examine/change events? ");
\r
582 for (i = 1; i < NEVENTS; i++) {
\r
584 if (future[i] == 1e30) continue;
\r
586 case FSNOVA: proutn("Supernova "); break;
\r
587 case FTBEAM: proutn("T Beam "); break;
\r
588 case FSNAP: proutn("Snapshot "); break;
\r
589 case FBATTAK: proutn("Base Attack "); break;
\r
590 case FCDBAS: proutn("Base Destroy "); break;
\r
591 case FSCMOVE: proutn("SC Move "); break;
\r
592 case FSCDBAS: proutn("SC Base Destroy "); break;
\r
594 proutn("%.2f", future[i]-game.state.date);
\r
598 if (key == IHREAL) {
\r
599 future[i] = game.state.date + aaitem;
\r