-L2012:
- command.verb = 0;
- game.oldobj = command.obj;
- command.obj = 0;
-
-L2600:
- checkhints();
-
- /* If closing time, check for any objects being toted with
- * game.prop < 0 and set the prop to -1-game.prop. This way
- * objects won't be described until they've been picked up
- * and put down separate from their respective piles. Don't
- * tick game.clock1 unless well into cave (and not at Y2). */
- if (game.closed) {
- if (game.prop[OYSTER] < 0 && TOTING(OYSTER))
- PSPEAK(OYSTER, 1);
- for (size_t i = 1; i <= NOBJECTS; i++) {
- if (TOTING(i) && game.prop[i] < 0)
- game.prop[i] = -1 - game.prop[i];
- }
- }
- game.wzdark = DARK(game.loc);
- if (game.knfloc > 0 && game.knfloc != game.loc)
- 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;
-
- /* Every input, check "game.foobar" flag. If zero, nothing's
- * going on. If pos, make neg. If neg, he skipped a word,
- * so make it zero. */
-L2607:
- game.foobar = (game.foobar > 0 ? -game.foobar : 0);
- ++game.turns;
-
- /* If a turn threshold has been met, apply penalties and tell
- * the player about it. */
- for (int i = 0; i < turn_threshold_count; ++i)
- {
- if (game.turns == turn_thresholds[i].threshold + 1)
- {
- game.trnluz += turn_thresholds[i].point_loss;
- speak(turn_thresholds[i].message);
- }
- }
-
- if (command.verb == SAY && command.wd2 > 0)
- command.verb = 0;
- if (command.verb == SAY) {
- command.part = transitive;
- goto Laction;
- }
- if (closecheck()) {
- if (game.closed)
- return true;
- } else
- lampcheck();
-
- V1 = VOCAB(command.wd1, -1);
- V2 = VOCAB(command.wd2, -1);
- if (V1 == ENTER && (V2 == STREAM || V2 == 1000 + WATER)) {
- if (LIQLOC(game.loc) == WATER) {
- RSPEAK(FEET_WET);
- } else {
- RSPEAK(WHERE_QUERY);
- }
- goto L2012;
- }
- if (V1 == ENTER && command.wd2 > 0) {
- command.wd1 = command.wd2;
- command.wd1x = command.wd2x;
- wordclear(&command.wd2);
- } else {
- /* FIXME: Magic numbers */
- if (!((V1 != 1000 + WATER && V1 != 1000 + OIL) ||
- (V2 != 1000 + PLANT && V2 != 1000 + DOOR))) {
- if (AT(V2 - 1000))
- command.wd2 = MAKEWD(WORD_POUR);
- }
- if (V1 == 1000 + CAGE && V2 == 1000 + BIRD && HERE(CAGE) && HERE(BIRD))
- command.wd1 = MAKEWD(WORD_CATCH);
- }
-L2620:
- if (wordeq(command.wd1, MAKEWD(WORD_WEST))) {
- ++game.iwest;
- if (game.iwest == 10)
- RSPEAK(W_IS_WEST);
- }
- if (wordeq(command.wd1, MAKEWD(WORD_GO)) && !wordempty(command.wd2)) {
- if (++igo == 10)
- RSPEAK(GO_UNNEEDED);
- }
-Lookup:
- defn = VOCAB(command.wd1, -1);
- if (defn == -1) {
- /* Gee, I don't understand. */
- if (fallback_handler(rawbuf))
- continue;
- SETPRM(1, command.wd1, command.wd1x);
- RSPEAK(DONT_KNOW);
- goto L2600;
- }
- kmod = MOD(defn, 1000);
- switch (defn / 1000) {
- case 0:
- if (playermove(command.verb, kmod))
+ // Keep getting commands from user until valid command is both given and executed.
+ do {
+ // Check some quick-time game state items, get input from user, increment turn,
+ // and pre-process commands. Keep going until pre-processing is done.
+ do {
+ checkhints();
+ close_cleanup_before_command();
+
+ game.wzdark = DARK(game.loc);
+ if (game.knfloc > 0 && game.knfloc != game.loc)
+ game.knfloc = 0;
+
+ // Get command input from user
+ if (!get_command_input(&command))
+ return false;
+
+ ++game.turns;
+ } while ( !preprocess_command(&command));
+ command_given = true;
+
+ // check if game is closed
+ if (closecheck() )