X-Git-Url: https://jxself.org/git/?p=super-star-trek.git;a=blobdiff_plain;f=src%2Fsst.c;h=16199e6df68ccb8acd5fd54b1fcf2ab7e4b7f966;hp=5d34a0dd43c58caee73dfeb6c61c8584c5c92162;hb=ad1478c7cc24b761592a1e355015b44b243aeeda;hpb=fd5a1ba781a0c37fa6181aa8e856d77d321df7a5 diff --git a/src/sst.c b/src/sst.c index 5d34a0d..16199e6 100644 --- a/src/sst.c +++ b/src/sst.c @@ -155,9 +155,19 @@ for a lot of magic numbers and refactored the heck out of it. 5. Half the quadrants now have inhabited planets, from which one cannot mine dilithium (there will still be the same additional number - of dilithium-bearing planets). Right now this is just color, but - eventually we'll fold in BSD-Trek-like logic for Klingons to attack - and enslave inhabited worlds. + of dilithium-bearing planets). Torpedoing an inhabited world is *bad*. + There is BSD-Trek-like logic for Klingons to attack and enslave + inhabited worlds, producing more ships (only is skill is 'good' or + better). (Controlled by OPTION_WORLDS and turned off if game + 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. */ /* the input queue */ @@ -165,15 +175,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", @@ -274,6 +283,8 @@ commands[] = { {"QUIT", QUIT, 0}, #define HELP 36 {"HELP", HELP, 0}, +#define SEED 37 + {"SEED", SEED, 0}, }; #define NUMCOMMANDS sizeof(commands)/sizeof(commands[0]) @@ -379,7 +390,7 @@ void enqueue(char *s) static void makemoves(void) { - int i, v = 0; + int key, i, v = 0; bool hitme; clrscr(); setwnd(message_window); @@ -398,7 +409,7 @@ static void makemoves(void) makechart(); continue; } - game.ididit=0; + game.ididit = false; clrscr(); setwnd(message_window); clrscr(); @@ -441,7 +452,7 @@ static void makemoves(void) if (game.ididit) hitme = true; break; case MOVE: // move - warp(1); + warp(false); break; case SHIELDS: // shields doshield(1); @@ -458,7 +469,7 @@ static void makemoves(void) dreprt(); break; case CHART: // chart - chart(0); + chart(false); break; case IMPULSE: // impulse impuls(); @@ -520,7 +531,7 @@ static void makemoves(void) abandn(); break; case DESTRUCT: // Self Destruct - dstrct(); + selfdestruct(); break; case SAVE: // Save Game freeze(false); @@ -543,7 +554,12 @@ static void makemoves(void) game.alldone = 1; // quit the game break; case HELP: - helpme(); // get help + helpme(); // get help + break; + case SEED: // set random-number seed + key = scan(); + if (key == IHREAL) + seed = (int)aaitem; break; } commandhook(commands[i].name, false); @@ -554,14 +570,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; } @@ -584,8 +600,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; @@ -598,8 +626,13 @@ int main(int argc, char **argv) exit(0); } } + /* 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'; @@ -623,7 +656,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); } @@ -669,9 +702,9 @@ char *cramlc(enum loctype key, coord w) return buf; } -void crmena(int i, int enemy, int key, coord w) +void crmena(bool stars, int enemy, enum loctype key, coord w) { - if (i == 1) proutn("***"); + if (stars) proutn("***"); cramen(enemy); proutn(" at "); proutn(cramlc(key, w)); @@ -701,14 +734,6 @@ double expran(double avrage) double Rand(void) { - if (!randready) { - if (seed == 0) - seed = (unsigned)time(NULL); - if (idebug) - fprintf(logfp, "seed %d\n", seed); - srand(seed); - randready = true; - } return rand()/(1.0 + (double)RAND_MAX); } @@ -817,27 +842,27 @@ int isit(char *s) void debugme(void) { 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 game.idebug? "); - if (ja() != 0) { + proutn("Toggle debug flag? "); + 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 "); @@ -851,11 +876,12 @@ void debugme(void) } } proutn("Examine/change events? "); - if (ja() != 0) { + if (ja() == true) { + event *ev; + coord w; int i; for (i = 1; i < NEVENTS; i++) { int key; - if (!is_scheduled(i)) continue; switch (i) { case FSNOVA: proutn("Supernova "); break; case FTBEAM: proutn("T Beam "); break; @@ -864,20 +890,56 @@ void debugme(void) case FCDBAS: proutn("Base Destroy "); break; case FSCMOVE: proutn("SC Move "); break; case FSCDBAS: proutn("SC Base Destroy "); break; + case FDSPROB: proutn("Probe Move "); break; + case FDISTR: proutn("Distress Call "); break; + case FENSLV: proutn("Enlavement "); break; + case FREPRO: proutn("Klingon Build "); break; } - proutn("%.2f", scheduled(i)-game.state.date); + if (is_scheduled(i)) { + proutn("%.2f", scheduled(i)-game.state.date); + if (i == FENSLV || i == FREPRO) { + ev = findevent(i); + proutn(" in %d-%d", ev->quadrant.x,ev->quadrant.y); + } + } else + proutn("never"); + proutn("? "); chew(); - proutn(" ?"); key = scan(); - if (key == IHREAL) { - schedule(i, aaitem); + if (key == 'n') { + unschedule(i); + chew(); + } else if (key == IHREAL) { + ev = schedule(i, aaitem); + if (i == FENSLV || i == FREPRO) { + chew(); + proutn("In quadrant- "); + key = scan(); + /* 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; + } + } } } chew(); } proutn("Induce supernova here? "); - if (ja() != 0) { + if (ja() == true) { game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova = true; - atover(1); + atover(true); } }