X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=main.c;h=2b264b915afa4f697f800d6f9019f26de0809ca6;hb=50435465a62d630e4b61fbec38270321211c4907;hp=8f98db577ec1d199292cbb5649149392878ceacf;hpb=b5260417dd83b655a4ebe797bbe0548f7ede4099;p=open-adventure.git diff --git a/main.c b/main.c index 8f98db5..2b264b9 100644 --- a/main.c +++ b/main.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "advent.h" #include "database.h" #include "linenoise/linenoise.h" @@ -61,7 +62,7 @@ static void sig_handler(int signo) * Revived 2017 as Open Adventure. */ -static bool do_command(FILE *); +static bool do_command(void); int main(int argc, char *argv[]) { @@ -136,7 +137,7 @@ int main(int argc, char *argv[]) initialise(); /* Start-up, dwarf stuff */ - game.zzword = rndvoc(3, 0); + make_zzword(game.zzword); game.newloc = LOC_START; game.loc = LOC_START; game.limit = GAMELIMIT; @@ -153,7 +154,7 @@ int main(int argc, char *argv[]) /* interpret commands until EOF or interrupt */ for (;;) { - if (!do_command(stdin)) + if (!do_command()) break; } /* show score and exit */ @@ -170,7 +171,7 @@ static bool fallback_handler(char *buf) // autogenerated, so don't charge user time for it. --game.turns; // here we reconfigure any global game state that uses random numbers - game.zzword = rndvoc(3, 0); + make_zzword(game.zzword); return true; } return false; @@ -624,28 +625,33 @@ static bool playermove(token_t verb, int motion) */ for (;;) { /* L12 loop */ for (;;) { - game.newloc = scratchloc / 1000; - motion = MOD(game.newloc, 100); - if (!SPECIAL(game.newloc)) { - if (game.newloc <= 100) { - if (game.newloc == 0 || PCT(game.newloc)) + long cond = scratchloc / 1000; + long arg = MOD(cond, 100); + if (!SPECIAL(cond)) { + /* YAML N and [pct N] conditionals */ + if (cond <= 100) { + if (cond == 0 || PCT(cond)) break; /* else fall through */ } - /* handles the YAML "with" clause */ - if (TOTING(motion) || (game.newloc > 200 && AT(motion))) + /* YAML [with OBJ] clause */ + if (TOTING(arg) || (cond > 200 && AT(arg))) break; - /* else fall through */ - } else if (game.prop[motion] != game.newloc / 100 - 3) + /* else fall through to check [not OBJ STATE] */ + } else if (game.prop[arg] != cond / 100 - 3) break; - do { + + /* We arrive here on conditional failure. + * Skip to next non-matching destination */ + long nextup; + do { if (travel[kk].stop) BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); // LCOV_EXCL_LINE ++kk; - game.newloc = T_HIGH(travel[kk]); + nextup = T_HIGH(travel[kk]); } while - (game.newloc == scratchloc); - scratchloc = game.newloc; + (nextup == scratchloc); + scratchloc = nextup; } game.newloc = MOD(scratchloc, 1000); @@ -926,7 +932,7 @@ static void listobjects(void) } } -static bool do_command(FILE *cmdin) +static bool do_command() /* Get and execute a command */ { long V1, V2; @@ -1019,8 +1025,25 @@ L2600: game.knfloc = 0; /* This is where we get a new command from the user */ - if (!GETIN(cmdin, &command.wd1, &command.wd1x, &command.wd2, &command.wd2x)) - return false; + char* input; + for (;;) { + input = get_input(); + if (input == NULL) + return(false); + if (word_count(input) > 2) + { + rspeak(TWO_WORDS); + continue; + } + if (strcmp(input, "") != 0) + break; + } + long tokens[4]; + tokenize(input, tokens); + command.wd1 = tokens[0]; + command.wd1x = tokens[1]; + command.wd2 = tokens[2]; + command.wd2x = tokens[3]; /* Every input, check "game.foobar" flag. If zero, nothing's * going on. If pos, make neg. If neg, he skipped a word, @@ -1052,8 +1075,12 @@ L2607: } else lampcheck(); - V1 = vocab(command.wd1, -1); - V2 = vocab(command.wd2, -1); + char word1[6]; + char word2[6]; + packed_to_token(command.wd1, word1); + packed_to_token(command.wd2, word2); + V1 = get_vocab_id(word1); + V2 = get_vocab_id(word2); if (V1 == ENTER && (V2 == STREAM || V2 == 1000 + WATER)) { if (LIQLOC(game.loc) == WATER) { rspeak(FEET_WET); @@ -1071,26 +1098,27 @@ L2607: if (!((V1 != 1000 + WATER && V1 != 1000 + OIL) || (V2 != 1000 + PLANT && V2 != 1000 + DOOR))) { if (AT(V2 - 1000)) - command.wd2 = MAKEWD(WORD_POUR); + command.wd2 = token_to_packed("POUR"); } if (V1 == 1000 + CAGE && V2 == 1000 + BIRD && HERE(CAGE) && HERE(BIRD)) - command.wd1 = MAKEWD(WORD_CATCH); + command.wd1 = token_to_packed("CATCH"); } L2620: - if (wordeq(command.wd1, MAKEWD(WORD_WEST))) { + if (wordeq(command.wd1, token_to_packed("WEST"))) { ++game.iwest; if (game.iwest == 10) rspeak(W_IS_WEST); } - if (wordeq(command.wd1, MAKEWD(WORD_GO)) && !wordempty(command.wd2)) { + if (wordeq(command.wd1, token_to_packed("GO")) && !wordempty(command.wd2)) { if (++igo == 10) rspeak(GO_UNNEEDED); } Lookup: - defn = vocab(command.wd1, -1); + packed_to_token(command.wd1, word1); + defn = get_vocab_id(word1); if (defn == -1) { /* Gee, I don't understand. */ - if (fallback_handler(rawbuf)) + if (fallback_handler(input)) continue; rspeak(DONT_KNOW, command.wd1, command.wd1x); goto L2600; @@ -1111,14 +1139,14 @@ Lookup: command.verb = kmod; break; case 3: - rspeak(kmod); + rspeak(specials[kmod].message); goto L2012; default: BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3); // LCOV_EXCL_LINE } Laction: - switch (action(cmdin, &command)) { + switch (action(&command)) { case GO_TERMINATE: return true; case GO_MOVE: @@ -1153,6 +1181,7 @@ Laction: default: BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH); // LCOV_EXCL_LINE } + linenoiseFree(input); } }