X-Git-Url: https://jxself.org/git/?p=open-adventure.git;a=blobdiff_plain;f=main.c;h=a558f7eb21100751c726778d0ae2acd1bcfc5659;hp=10d284500d80ec2cd91d84d5b639a9ac3fb74f84;hb=fb86d64b20f05e5a2920ba76fb908486c8a67ba0;hpb=00cf2a937381701921ade375ab1c6f681af85b91 diff --git a/main.c b/main.c index 10d2845..a558f7e 100644 --- a/main.c +++ b/main.c @@ -397,7 +397,8 @@ static bool dwarfmove(void) else if (j > 1 && game.newloc == tk[j - 1]) continue; else if (j >= DIM(tk) - 1) - continue; + /* This can't actually happen. */ + continue; // LCOV_EXCL_LINE else if (game.newloc == game.dloc[i]) continue; else if (FORCED(game.newloc)) @@ -486,8 +487,8 @@ static void croak(void) * death and exit. */ rspeak(DEATH_CLOSING); terminate(endgame); - } else if (game.numdie == NDEATHS || - !yes(query, yes_response, arbitrary_messages[OK_MAN])) + } else if ( !yes(query, yes_response, arbitrary_messages[OK_MAN]) + || game.numdie == NDEATHS) terminate(endgame); else { game.place[WATER] = game.place[OIL] = LOC_NOWHERE; @@ -539,40 +540,39 @@ static void playermove( int motion) motion = game.oldlc2; game.oldlc2 = game.oldloc; game.oldloc = game.loc; - int spk = 0; - if (motion == game.loc) - spk = FORGOT_PATH; - if (CNDBIT(game.loc, COND_NOBACK)) - spk = TWIST_TURN; - if (spk == 0) { - int te_tmp = 0; - for (;;) { - enum desttype_t desttype = travel[travel_entry].desttype; - scratchloc = travel[travel_entry].destval; - if (desttype != dest_goto || scratchloc != motion) { - if (desttype == dest_goto) { - if (FORCED(scratchloc) && travel[tkey[scratchloc]].destval == motion) - te_tmp = travel_entry; - } - if (!travel[travel_entry].stop) { - ++travel_entry; /* go to next travel entry for this location */ - continue; - } - /* we've reached the end of travel entries for game.loc */ - travel_entry = te_tmp; - if (travel_entry == 0) { - rspeak(NOT_CONNECTED); - return; - } - } + if (CNDBIT(game.loc, COND_NOBACK)) { + rspeak(TWIST_TURN); + return; + } + if (motion == game.loc) { + rspeak(FORGOT_PATH); + return; + } - motion = travel[travel_entry].motion; - travel_entry = tkey[game.loc]; - break; /* fall through to ordinary travel */ + int te_tmp = 0; + for (;;) { + enum desttype_t desttype = travel[travel_entry].desttype; + scratchloc = travel[travel_entry].destval; + if (desttype != dest_goto || scratchloc != motion) { + if (desttype == dest_goto) { + if (FORCED(scratchloc) && travel[tkey[scratchloc]].destval == motion) + te_tmp = travel_entry; + } + if (!travel[travel_entry].stop) { + ++travel_entry; /* go to next travel entry for this location */ + continue; + } + /* we've reached the end of travel entries for game.loc */ + travel_entry = te_tmp; + if (travel_entry == 0) { + rspeak(NOT_CONNECTED); + return; + } } - } else { - rspeak(spk); - return; + + motion = travel[travel_entry].motion; + travel_entry = tkey[game.loc]; + break; /* fall through to ordinary travel */ } } else if (motion == LOOK) { /* Look. Can't give more detail. Pretend it wasn't dark @@ -898,7 +898,7 @@ 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)) { @@ -1005,8 +1005,8 @@ static bool get_command_input(struct command_t *command) packed_to_token(command->wd1, word1); packed_to_token(command->wd2, word2); - command->id1 = get_vocab_id(word1); - command->id2 = get_vocab_id(word2); + get_vocab_metadata(word1, &(command->id1), &(command->type1)); + get_vocab_metadata(word2, &(command->id2), &(command->type2)); return true; } @@ -1014,7 +1014,6 @@ static bool get_command_input(struct command_t *command) static bool do_command() /* Get and execute a command */ { - long kmod, defn; static struct command_t command; char word1[TOKLEN + 1]; @@ -1114,7 +1113,7 @@ Lclosecheck: lampcheck(); if (command.id1 == ENTER && (command.id2 == STREAM || - command.id2 == PROMOTE_WORD(WATER))) { + command.id2 == WATER)) { if (LIQLOC(game.loc) == WATER) rspeak(FEET_WET); else @@ -1124,51 +1123,64 @@ Lclosecheck: } if (command.id1 == ENTER && command.id2 != WORD_NOT_FOUND && command.id2 != WORD_EMPTY) { command.id1 = command.id2; + command.type1 = command.type2; + strncpy(command.raw1, command.raw2, LINESIZE - 1); command.id2 = WORD_EMPTY; + command.type2 = NO_WORD_TYPE; + strncpy(command.raw2, "", LINESIZE - 1); } else { - /* FIXME: Magic numbers related to vocabulary */ - if (!((command.id1 != PROMOTE_WORD(WATER) && command.id1 != PROMOTE_WORD(OIL)) || - (command.id2 != PROMOTE_WORD(PLANT) && command.id2 != PROMOTE_WORD(DOOR)))) { - if (AT(DEMOTE_WORD(command.id2))) + if (!((command.id1 != WATER && command.id1 != OIL) || (command.id2 != PLANT && command.id2 != DOOR))) { + if (AT(command.id2)) + { + command.id2 = POUR; + command.type2 = ACTION; + strncpy(command.raw2, "POUR", LINESIZE - 1); command.wd2 = token_to_packed("POUR"); + } } - if (command.id1 == PROMOTE_WORD(CAGE) && command.id2 == PROMOTE_WORD(BIRD) && HERE(CAGE) && HERE(BIRD)) + if (command.id1 == CAGE && command.id2 == BIRD && HERE(CAGE) && HERE(BIRD)) + { + command.id1 = CARRY; + command.type1 = ACTION; + strncpy(command.raw2, "CATCH", LINESIZE - 1); command.wd1 = token_to_packed("CATCH"); + } } Lookup: - if (wordeq(command.wd1, token_to_packed("WEST"))) { + if (strncasecmp(command.raw1, "west", sizeof("west")) == 0) { if (++game.iwest == 10) rspeak(W_IS_WEST); } - if (wordeq(command.wd1, token_to_packed("GO")) && !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); - defn = get_vocab_id(word1); - if (defn == WORD_NOT_FOUND) { + long defn; + enum wordtype type; + get_vocab_metadata(word1, &defn, &type); + if (command.id1 == WORD_NOT_FOUND) { if (fallback_handler(command)) continue; /* Gee, I don't understand. */ sspeak(DONT_KNOW, command.raw1); goto Lclearobj; } - /* FIXME: magic numbers related to vocabulary */ - kmod = MOD(defn, 1000); - switch (defn / 1000) { - case 0: - playermove(kmod); + switch (type) { + case NO_WORD_TYPE: // FIXME: treating NO_WORD_TYPE as a motion word is confusing + case MOTION: + playermove(command.id1); return true; - case 1: + case OBJECT: command.part = unknown; - command.obj = kmod; + command.obj = command.id1; break; - case 2: + case ACTION: command.part = intransitive; - command.verb = kmod; + command.verb = defn; break; - case 3: - speak(specials[kmod].message); + case SPECIAL: + speak(specials[command.id1].message); goto Lclearobj; default: BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3); // LCOV_EXCL_LINE @@ -1188,10 +1200,14 @@ Lookup: goto Lookup; case GO_WORD2: /* Get second word for analysis. */ - command.wd1 = command.wd2; - strncpy(command.raw1, command.raw2, LINESIZE - 1); + command.id1 = command.id2; + command.type1 = command.type2; + strncpy(command.raw1, command.raw2, LINESIZE - 1); + command.wd1 = command.wd2; + command.id2 = WORD_EMPTY; + command.type2 = NO_WORD_TYPE; + command.raw2[0] = '\0'; wordclear(&command.wd2); - command.raw2[0] = '\0'; goto Lookup; case GO_UNKNOWN: /* Random intransitive verbs come here. Clear obj just in case