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
485 // Skip leading white space
\r
486 while (*linep == ' ') linep++;
\r
492 if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {
\r
493 // treat as a number
\r
494 if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
\r
495 linep = line; // Invalid numbers are ignored
\r
507 while (*linep && *linep!=' ') {
\r
508 if ((cp - citem) < 9) *cp++ = tolower(*linep);
\r
520 if (*citem == 'y') return TRUE;
\r
521 if (*citem == 'n') return FALSE;
\r
522 proutn("Please answer with \"Y\" or \"N\":");
\r
526 double square(double i) { return i*i; }
\r
531 prout("Beg your pardon, Captain?");
\r
534 int isit(char *s) {
\r
535 /* New function -- compares s to scaned citem and returns true if it
\r
536 matches to the length of s */
\r
538 return strncmp(s, citem, max(1, strlen(citem))) == 0;
\r
543 void debugme(void) {
\r
544 proutn("Reset levels? ");
\r
546 if (energy < inenrg) energy = inenrg;
\r
551 proutn("Reset damage? ");
\r
554 for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;
\r
557 proutn("Toggle idebug? ");
\r
560 if (idebug) prout("Debug output ON");
\r
561 else prout("Debug output OFF");
\r
563 proutn("Cause selective damage? ");
\r
566 for (i=1; i <= NDEVICES; i++) {
\r
572 if (key == IHALPHA && isit("y")) {
\r
574 if (i == DRADIO) stdamtim = game.state.date;
\r
578 proutn("Examine/change events? ");
\r
581 for (i = 1; i < NEVENTS; i++) {
\r
583 if (future[i] == 1e30) continue;
\r
585 case FSNOVA: proutn("Supernova "); break;
\r
586 case FTBEAM: proutn("T Beam "); break;
\r
587 case FSNAP: proutn("Snapshot "); break;
\r
588 case FBATTAK: proutn("Base Attack "); break;
\r
589 case FCDBAS: proutn("Base Destroy "); break;
\r
590 case FSCMOVE: proutn("SC Move "); break;
\r
591 case FSCDBAS: proutn("SC Base Destroy "); break;
\r
593 proutn("%.2f", future[i]-game.state.date);
\r
597 if (key == IHREAL) {
\r
598 future[i] = game.state.date + aaitem;
\r