X-Git-Url: https://jxself.org/git/?p=super-star-trek.git;a=blobdiff_plain;f=src%2Fsst.c;h=d19698491d71a64611cf7b7a0fd6a99591a9d6cd;hp=90b2b307a6ba536b964e2b89cf00621e93633248;hb=0f68a074434296ae409accdc39ba0142600ea255;hpb=dc45b3ccf42344c238ddb146d79dc62086624848 diff --git a/src/sst.c b/src/sst.c index 90b2b30..d196984 100644 --- a/src/sst.c +++ b/src/sst.c @@ -162,6 +162,17 @@ for a lot of magic numbers and refactored the heck out of it. type is "plain" or "almy".) 6. User input is now logged so we can do regression testing. + + 7. More BSD-Trek features: You can now lose if your entire crew + dies in battle. When abandoning ship in a game with inhabited + worlds enabled, they must have one in the quadrant to beam down + to; otherwise they die in space and this counts heavily against + your score. Docking at a starbase replenishes your crew. + + 8. Still more BSD-Trek: we now have a weighted damage table. + Also, the nav subsystem (enabling automatic course + setting) can be damaged separately from the main computer (which + handles weapons targeting, ETA calculation, and self-destruct). */ /* the input queue */ @@ -169,15 +180,14 @@ static char line[128], *linep = line; struct game game; coord thing; -int iqhere, iqengry; +bool iqhere, iqengry; int iscore, iskill; // Common PLAQ double aaitem; double perdate; char citem[10]; int seed; // the random-number seed bool idebug; // debug mode -bool randready; // Has the random-number generator initialized? -FILE *logfp; +FILE *logfp, *replayfp; char *device[NDEVICES] = { "S. R. Sensors", @@ -191,6 +201,7 @@ char *device[NDEVICES] = { "Subspace Radio", "Shuttle Craft", "Computer", + "Navigation System", "Transporter", "Shield Control", "Death Ray", @@ -285,7 +296,9 @@ commands[] = { #define NUMCOMMANDS sizeof(commands)/sizeof(commands[0]) #define ACCEPT(i) (!commands[i].option || (commands[i].option & game.options)) -static void listCommands(void) { +static void listCommands(void) +/* generate a list of legal commands */ +{ int i, k = 0; proutn("LEGAL COMMANDS ARE:"); for (i = 0; i < NUMCOMMANDS; i++) { @@ -299,7 +312,8 @@ static void listCommands(void) { skip(1); } -static void helpme(void) +static void helpme(void) +/* browse on-line help */ { int i, j; char cmdbuf[32], *cp; @@ -378,12 +392,14 @@ static void helpme(void) fclose(fp); } -void enqueue(char *s) +void enqueue(char *s) +/* enqueue input for the command parser */ { strcpy(line, s); } -static void makemoves(void) +static void makemoves(void) +/* command-interpretation loop */ { int key, i, v = 0; bool hitme; @@ -393,7 +409,7 @@ static void makemoves(void) drawmaps(1); for(;;) { /* get a command */ hitme = false; - game.justin = 0; + game.justin = false; game.optime = 0.0; i = -1; chew(); @@ -404,7 +420,7 @@ static void makemoves(void) makechart(); continue; } - game.ididit=0; + game.ididit = false; clrscr(); setwnd(message_window); clrscr(); @@ -450,10 +466,10 @@ static void makemoves(void) warp(false); break; case SHIELDS: // shields - doshield(1); + doshield(false); if (game.ididit) { - hitme=true; - game.shldchg = 0; + hitme = true; + game.shldchg = false; } break; case DOCK: // dock @@ -464,7 +480,7 @@ static void makemoves(void) dreprt(); break; case CHART: // chart - chart(0); + chart(false); break; case IMPULSE: // impulse impuls(); @@ -526,7 +542,7 @@ static void makemoves(void) abandn(); break; case DESTRUCT: // Self Destruct - dstrct(); + selfdestruct(); break; case SAVE: // Save Game freeze(false); @@ -546,7 +562,7 @@ static void makemoves(void) if (game.ididit) hitme = true; break; case QUIT: - game.alldone = 1; // quit the game + game.alldone = true; // quit the game break; case HELP: helpme(); // get help @@ -565,14 +581,14 @@ static void makemoves(void) if (game.alldone) break; // Events did us in } if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova) { // Galaxy went Nova! - atover(0); + atover(false); continue; } - if (hitme && game.justin==0) { + if (hitme && !game.justin) { attack(2); if (game.alldone) break; if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova) { // went NOVA! - atover(0); + atover(false); hitme = true; continue; } @@ -595,8 +611,20 @@ int main(int argc, char **argv) else game.options |= OPTION_TTY; - while ((option = getopt(argc, argv, "tx")) != -1) { + seed = (int)time(NULL); + while ((option = getopt(argc, argv, "r:tx")) != -1) { switch (option) { + case 'r': + replayfp = fopen(optarg, "r"); + if (replayfp == NULL) { + fprintf(stderr, "sst: can't open replay file %s\n", optarg); + exit(1); + } + if (fscanf(replayfp, "seed %d\n", &seed) != 1) { + fprintf(stderr, "sst: replay file %s is ill-formed\n", optarg); + exit(1); + } + /* FALL THROUGH */ case 't': game.options |= OPTION_TTY; game.options &=~ OPTION_CURSES; @@ -612,8 +640,10 @@ int main(int argc, char **argv) /* where to save the input in case of bugs */ logfp = fopen("sst-input.log", "w"); setlinebuf(logfp); + fprintf(logfp, "seed %d\n", seed); + srand(seed); - randomize(); + srand(seed); iostart(); line[0] = '\0'; @@ -628,7 +658,7 @@ int main(int argc, char **argv) setup(line[0] == '\0'); if (game.alldone) { score(); - game.alldone = 0; + game.alldone = false; } else makemoves(); skip(1); @@ -637,7 +667,7 @@ int main(int argc, char **argv) if (game.tourn && game.alldone) { proutn("Do you want your score recorded?"); - if (ja()) { + if (ja() == true) { chew2(); freeze(false); } @@ -651,7 +681,8 @@ int main(int argc, char **argv) } -void cramen(int i) +void cramen(feature i) +/* print the name of an enemy */ { /* return an enemy */ char *s; @@ -674,6 +705,7 @@ void cramen(int i) } char *cramlc(enum loctype key, coord w) +/* name a location */ { static char buf[32]; buf[0] = '\0'; @@ -683,15 +715,17 @@ char *cramlc(enum loctype key, coord w) return buf; } -void crmena(int i, int enemy, int key, coord w) +void crmena(bool stars, feature enemy, enum loctype key, coord w) +/* print an enemy and his location */ { - if (i == 1) proutn("***"); + if (stars) proutn("***"); cramen(enemy); proutn(" at "); proutn(cramlc(key, w)); } -void crmshp(void) +void crmshp(void) +/* print our ship name */ { char *s; switch (game.ship) { @@ -702,7 +736,8 @@ void crmshp(void) proutn(s); } -void stars(void) +void stars(void) +/* print a line of stars */ { prouts("******************************************************"); skip(1); @@ -715,21 +750,16 @@ double expran(double avrage) double Rand(void) { - if (!randready) { - if (seed == 0) - seed = (unsigned)time(NULL); - if (logfp) - fprintf(logfp, "seed %d\n", seed); - srand(seed); - randready = true; - } return rand()/(1.0 + (double)RAND_MAX); } -void iran(int size, int *i, int *j) +coord randplace(int size) +/* choose a random location */ { - *i = Rand()*(size*1.0) + 1.0; - *j = Rand()*(size*1.0) + 1.0; + coord w; + w.x = Rand()*(size*1.0) + 1.0; + w.y = Rand()*(size*1.0) + 1.0; + return w; } void chew(void) @@ -800,7 +830,8 @@ int scan(void) return IHALPHA; } -bool ja(void) +bool ja(void) +/* yes-or-no confirmation */ { chew(); for(;;) { @@ -812,46 +843,45 @@ bool ja(void) } } -void huh(void) +void huh(void) +/* complain about unparseable input */ { chew(); skip(1); prout("Beg your pardon, Captain?"); } -int isit(char *s) +bool isit(char *s) +/* compares s to citem and returns true if it matches to the length of s */ { - /* New function -- compares s to scanned citem and returns true if it - matches to the length of s */ - return strncasecmp(s, citem, max(1, strlen(citem))) == 0; - } -void debugme(void) +void debugme(void) +/* access to the internals for debugging */ { proutn("Reset levels? "); - if (ja() != 0) { + if (ja() == true) { if (game.energy < game.inenrg) game.energy = game.inenrg; game.shield = game.inshld; game.torps = game.intorps; game.lsupres = game.inlsr; } proutn("Reset damage? "); - if (ja() != 0) { + if (ja() == true) { int i; for (i=0; i < NDEVICES; i++) if (game.damage[i] > 0.0) game.damage[i] = 0.0; } proutn("Toggle debug flag? "); - if (ja() != 0) { + if (ja() == true) { idebug = !idebug; if (idebug) prout("Debug output ON"); else prout("Debug output OFF"); } proutn("Cause selective damage? "); - if (ja() != 0) { + if (ja() == true) { int i, key; for (i=0; i < NDEVICES; i++) { proutn("Kill "); @@ -865,7 +895,7 @@ void debugme(void) } } proutn("Examine/change events? "); - if (ja() != 0) { + if (ja() == true) { event *ev; coord w; int i; @@ -884,12 +914,16 @@ void debugme(void) case FENSLV: proutn("Enlavement "); break; case FREPRO: proutn("Klingon Build "); break; } - if (is_scheduled(i)) + if (is_scheduled(i)) { proutn("%.2f", scheduled(i)-game.state.date); - else + if (i == FENSLV || i == FREPRO) { + ev = findevent(i); + proutn(" in %d-%d", ev->quadrant.x,ev->quadrant.y); + } + } else proutn("never"); - chew(); proutn("? "); + chew(); key = scan(); if (key == 'n') { unschedule(i); @@ -900,28 +934,31 @@ void debugme(void) chew(); proutn("In quadrant- "); key = scan(); - if (key != IHREAL) { - prout("Event %d canceled, no y coordinate.", i); - unschedule(i); - continue; - } - w.y = (int)aaitem; - key = scan(); - if (key != IHREAL) { - prout("Event %d canceled, no x coordinate.", i); - unschedule(i); - continue; + /* IHEOL says to leave coordinates as they are */ + if (key != IHEOL) { + if (key != IHREAL) { + prout("Event %d canceled, no x coordinate.", i); + unschedule(i); + continue; + } + w.x = (int)aaitem; + key = scan(); + if (key != IHREAL) { + prout("Event %d canceled, no y coordinate.", i); + unschedule(i); + continue; + } + w.y = (int)aaitem; + ev->quadrant = w; } - w.x = (int)aaitem; - ev->quadrant = w; } } } chew(); } proutn("Induce supernova here? "); - if (ja()) { + if (ja() == true) { game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova = true; - atover(1); + atover(true); } }