X-Git-Url: https://jxself.org/git/?p=open-adventure.git;a=blobdiff_plain;f=main.c;h=8a5545adbb3d42ff230ccfcdba83bf801d14a3f5;hp=61f75850d6a1ef36f7d9a36d2ddbbcf34a9f85ba;hb=878efdddfbb1cd134c4ceed6cbc80e64aa43d2a5;hpb=e696fed6dbd36555548aba77fb754d87f282a564 diff --git a/main.c b/main.c index 61f7585..8a5545a 100644 --- a/main.c +++ b/main.c @@ -133,23 +133,6 @@ int main(int argc, char *argv[]) terminate(quitgame); } -static bool fallback_handler(struct command_t command) -/* fallback handler for commands not handled by FORTRANish parser */ -{ - long sv; - char buf[LINESIZE]; - sprintf(buf, "%s %s", command.raw1, command.raw2); - - if (sscanf(buf, "seed %ld", &sv) == 1) { - set_seed(sv); - printf("Seed set to %ld\n", sv); - // autogenerated, so don't charge user time for it. - --game.turns; - return true; - } - return false; -} - /* Check if this loc is eligible for any hints. If been here long * enough, display. Ignore "HINTS" < 4 (special stuff, see database * notes). */ @@ -223,9 +206,8 @@ static void checkhints(void) break; game.hintlc[hint] = 0; return; - default: + default: // LCOV_EXCL_LINE BUG(HINT_NUMBER_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE - break; } /* Fall through to hint display */ @@ -315,7 +297,7 @@ static bool dwarfmove(void) /* Dwarves move. Return true if player survives, false if he dies. */ { int kk, stick, attack; - long tk[21]; + loc_t tk[21]; /* Dwarf stuff. See earlier comments for description of * variables. Remember sixth dwarf is pirate and is thus @@ -448,7 +430,7 @@ static bool dwarfmove(void) rspeak(stick > 1 ? MULTIPLE_HITS : (stick == 1 ? ONE_HIT : NONE_HIT), stick); } else { rspeak(KNIFE_THROWN); - rspeak(MISSES_YOU); + rspeak(stick ? GETS_YOU : MISSES_YOU); } if (stick == 0) return true; @@ -505,7 +487,7 @@ static void croak(void) } } -static bool traveleq(long a, long b) +static bool traveleq(int a, int b) /* Are two travel entries equal for purposes of skip after failed condition? */ { return (travel[a].condtype == travel[b].condtype) @@ -667,7 +649,7 @@ static void playermove( int motion) /* We arrive here on conditional failure. * Skip to next non-matching destination */ - long te_tmp = travel_entry; + int te_tmp = travel_entry; do { if (travel[te_tmp].stop) BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); // LCOV_EXCL_LINE @@ -756,7 +738,7 @@ static void playermove( int motion) croak(); return; } - default: + default: // LCOV_EXCL_LINE BUG(SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE } } @@ -898,14 +880,20 @@ static void lampcheck(void) * lamp give out. When it gets close, we come here to warn him. * First following arm checks if the lamp and fresh batteries are * here, in which case we replace the batteries and continue. - * Second is for other cases of lamp dying. Eve after it goes + * Second is for other cases of lamp dying. Even after it goes * out, he can explore outside for a while if desired. */ if (game.limit <= WARNTIME) { if (HERE(BATTERY) && game.prop[BATTERY] == FRESH_BATTERIES && HERE(LAMP)) { rspeak(REPLACE_BATTERIES); game.prop[BATTERY] = DEAD_BATTERIES; +#ifdef __unused__ + /* This code from the original game seems to have been faulty. + * No tests ever passed the guard, and with the guard removed + * the game hangs when the lamp limit is reached. + */ if (TOTING(BATTERY)) drop(BATTERY, game.loc); +#endif game.limit += BATTERYLIFE; game.lmwarn = false; } else if (!game.lmwarn && HERE(LAMP)) { @@ -938,7 +926,7 @@ static void listobjects(void) if (!DARK(game.loc)) { ++game.abbrev[game.loc]; for (int i = game.atloc[game.loc]; i != 0; i = game.link[i]) { - long obj = i; + obj_t obj = i; if (obj > NOBJECTS) obj = obj - NOBJECTS; if (obj == STEPS && TOTING(NUGGET)) @@ -977,47 +965,10 @@ static void listobjects(void) } } -static bool get_command_input(struct command_t *command) -{ - char inputbuf[LINESIZE]; - char word1[TOKLEN + 1]; - char word2[TOKLEN + 1]; - char* input; - - for (;;) { - input = get_input(); - if (input == NULL) - return false; - if (word_count(input) > 2) { - rspeak(TWO_WORDS); - free(input); - continue; - } - if (strcmp(input, "") != 0) - break; - free(input); - } - - strncpy(inputbuf, input, LINESIZE - 1); - free(input); - - tokenize(inputbuf, command); - - packed_to_token(command->wd1, word1); - packed_to_token(command->wd2, word2); - get_vocab_metadata(word1, &(command->id1), &(command->type1)); - get_vocab_metadata(word2, &(command->id2), &(command->type2)); - - return true; -} - static bool do_command() /* Get and execute a command */ { static struct command_t command; - char word1[TOKLEN + 1]; - - command.verb = 0; /* Can't leave cave once it's closing (except by main office). */ if (OUTSID(game.newloc) && game.newloc != 0 && game.closng) { @@ -1103,7 +1054,6 @@ Lclearobj: if (!get_command_input(&command)) return false; -Lclosecheck: ++game.turns; if (closecheck()) { @@ -1112,8 +1062,8 @@ Lclosecheck: } else lampcheck(); - if (command.id1 == ENTER && (command.id2 == STREAM || - command.id2 == WATER)) { + if (command.type1 == MOTION && command.id1 == ENTER + && (command.id2 == STREAM || command.id2 == WATER)) { if (LIQLOC(game.loc) == WATER) rspeak(FEET_WET); else @@ -1121,58 +1071,73 @@ Lclosecheck: goto Lclearobj; } - if (command.id1 == ENTER && command.id2 != WORD_NOT_FOUND && command.id2 != WORD_EMPTY) { - command.id1 = command.id2; - command.id2 = WORD_EMPTY; - } else { + + if (command.type1 == OBJECT) { + if (command.id1 == GRATE) { + command.type1 = MOTION; + if (game.loc == LOC_START || + game.loc == LOC_VALLEY || + game.loc == LOC_SLIT) { + command.id1 = DEPRESSION; + } + if (game.loc == LOC_COBBLE || + game.loc == LOC_DEBRIS || + game.loc == LOC_AWKWARD || + game.loc == LOC_BIRD || + game.loc == LOC_PITTOP) { + command.id1 = ENTRANCE; + } + } if (!((command.id1 != WATER && command.id1 != OIL) || (command.id2 != PLANT && command.id2 != DOOR))) { - if (AT(command.id2)) - command.wd2 = token_to_packed("POUR"); + if (AT(command.id2)) { + command.id2 = POUR; + command.type2 = ACTION; + strncpy(command.raw2, "POUR", LINESIZE - 1); + } + } + if (command.id1 == CAGE && command.id2 == BIRD && HERE(CAGE) && HERE(BIRD)) { + command.id1 = CARRY; + command.type1 = ACTION; + strncpy(command.raw2, "CATCH", LINESIZE - 1); } - if (command.id1 == CAGE && command.id2 == BIRD && HERE(CAGE) && HERE(BIRD)) - command.wd1 = token_to_packed("CATCH"); } + Lookup: if (strncasecmp(command.raw1, "west", sizeof("west")) == 0) { if (++game.iwest == 10) rspeak(W_IS_WEST); } - if (strncasecmp(command.raw1, "go", sizeof("go")) == 0 && !wordempty(command.wd2)) { + if (strncasecmp(command.raw1, "go", sizeof("go")) == 0 && command.id2 != WORD_EMPTY) { if (++game.igo == 10) rspeak(GO_UNNEEDED); } - packed_to_token(command.wd1, word1); - long defn; - enum wordtype type; - get_vocab_metadata(word1, &defn, &type); - if (defn == WORD_NOT_FOUND) { - if (fallback_handler(command)) - continue; + if (command.id1 == WORD_NOT_FOUND) { /* Gee, I don't understand. */ sspeak(DONT_KNOW, command.raw1); goto Lclearobj; } - switch (type) { + switch (command.type1) { case NO_WORD_TYPE: // FIXME: treating NO_WORD_TYPE as a motion word is confusing case MOTION: - playermove(defn); + playermove(command.id1); return true; case OBJECT: command.part = unknown; - command.obj = defn; + command.obj = command.id1; break; case ACTION: - command.part = intransitive; - command.verb = defn; + if(command.type2 == NUMERIC) + command.part = transitive; + else + command.part = intransitive; + command.verb = command.id1; break; - case SPECIAL: - speak(specials[defn].message); - goto Lclearobj; - default: + case NUMERIC: // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3); // LCOV_EXCL_LINE } - switch (action(&command)) { + switch (action(command)) { case GO_TERMINATE: return true; case GO_MOVE: @@ -1180,15 +1145,13 @@ Lookup: return true; case GO_TOP: continue; /* back to top of main interpreter loop */ - case GO_CHECKFOO: - goto Lclosecheck; - case GO_LOOKUP: - goto Lookup; case GO_WORD2: /* Get second word for analysis. */ - command.wd1 = command.wd2; + command.id1 = command.id2; + command.type1 = command.type2; strncpy(command.raw1, command.raw2, LINESIZE - 1); - wordclear(&command.wd2); + command.id2 = WORD_EMPTY; + command.type2 = NO_WORD_TYPE; command.raw2[0] = '\0'; goto Lookup; case GO_UNKNOWN: @@ -1205,7 +1168,7 @@ Lookup: /* Oh dear, he's disturbed the dwarves. */ rspeak(DWARVES_AWAKEN); terminate(endgame); - default: + default: // LCOV_EXCL_LINE BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH); // LCOV_EXCL_LINE } }