}
}
+void clear_command(command_t *cmd)
+{
+ cmd->verb = ACT_NULL;
+ game.oldobj = cmd->obj;
+ cmd->obj = NO_OBJECT;
+}
+
static bool do_command()
/* Get and execute a command */
{
static command_t command;
+ bool words_processed = false;
/* Can't leave cave once it's closing (except by main office). */
if (OUTSID(game.newloc) && game.newloc != 0 && game.closng) {
rspeak(SAYS_PLUGH);
listobjects();
-
-Lclearobj:
- command.verb = 0;
- game.oldobj = command.obj;
- command.obj = 0;
-
-L2600:
+ clear_command(&command);
+
+Lcheckhint:
checkhints();
/* If closing time, check for any objects being toted with
if (game.knfloc > 0 && game.knfloc != game.loc)
game.knfloc = 0;
- /* Preserve state from last command for reuse when required */
- command_t preserve = command;
-
// Get command input from user
if (!get_command_input(&command))
return false;
const char *types[] = {"NO_WORD_TYPE", "MOTION", "OBJECT", "ACTION", "NUMERIC"};
/* needs to stay synced with enum speechpart */
const char *roles[] = {"unknown", "intransitive", "transitive"};
- printf("Preserve: role = %s type1 = %s, id1 = %ld, type2 = %s, id2 = %ld\n",
- roles[preserve.part],
- types[preserve.word[0].type],
- preserve.word[0].id,
- types[preserve.word[1].type],
- preserve.word[1].id);
printf("Command: role = %s type1 = %s, id1 = %ld, type2 = %s, id2 = %ld\n",
roles[command.part],
types[command.word[0].type],
command.word[1].id);
#endif
- /* Handle of objectless action followed by actionless object */
- if (preserve.word[0].type == ACTION && preserve.word[1].type == NO_WORD_TYPE && command.word[1].id == 0)
- command.verb = preserve.verb;
-
++game.turns;
if (closecheck()) {
else
rspeak(WHERE_QUERY);
- goto Lclearobj;
+ clear_command(&command);
+ goto Lcheckhint;
}
if (command.word[0].type == OBJECT) {
}
}
-Lookup:
- if (strncasecmp(command.word[0].raw, "west", sizeof("west")) == 0) {
- if (++game.iwest == 10)
- rspeak(W_IS_WEST);
- }
- if (strncasecmp(command.word[0].raw, "go", sizeof("go")) == 0 && command.word[1].id != WORD_EMPTY) {
- if (++game.igo == 10)
- rspeak(GO_UNNEEDED);
- }
- if (command.word[0].id == WORD_NOT_FOUND) {
- /* Gee, I don't understand. */
- sspeak(DONT_KNOW, command.word[0].raw);
- goto Lclearobj;
- }
- switch (command.word[0].type) {
- case NO_WORD_TYPE: // FIXME: treating NO_WORD_TYPE as a motion word is confusing
- case MOTION:
- playermove(command.word[0].id);
- return true;
- case OBJECT:
- command.part = unknown;
- command.obj = command.word[0].id;
- break;
- case ACTION:
- if (command.word[1].type == NUMERIC)
- command.part = transitive;
- else
- command.part = intransitive;
- command.verb = command.word[0].id;
- break;
- case NUMERIC: // LCOV_EXCL_LINE
- if (!settings.oldstyle) {
- sspeak(DONT_KNOW, command.word[0].raw);
- goto Lclearobj;
- }
- default: // LCOV_EXCL_LINE
- BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3); // LCOV_EXCL_LINE
- }
- if (!is_valid(game)) {
- exit(1);
- }
- switch (action(command)) {
- case GO_TERMINATE:
- return true;
- case GO_MOVE:
- playermove(NUL);
- return true;
- case GO_TOP:
- continue; /* back to top of main interpreter loop */
- case GO_CLEAROBJ:
- goto Lclearobj;
- case GO_CHECKHINT:
- goto L2600;
- case GO_CHECKFOO:
- goto Lclosecheck;
- case GO_LOOKUP:
- goto Lookup;
- case GO_WORD2:
+ // loop until all words in command are procesed
+ do {
+ // assume all words in command are processed, until proven otherwise
+ words_processed = true;
+
+ if (strncasecmp(command.word[0].raw, "west", sizeof("west")) == 0) {
+ if (++game.iwest == 10)
+ rspeak(W_IS_WEST);
+ }
+ if (strncasecmp(command.word[0].raw, "go", sizeof("go")) == 0 && command.word[1].id != WORD_EMPTY) {
+ if (++game.igo == 10)
+ rspeak(GO_UNNEEDED);
+ }
+ if (command.word[0].id == WORD_NOT_FOUND) {
+ /* Gee, I don't understand. */
+ sspeak(DONT_KNOW, command.word[0].raw);
+ clear_command(&command);
+ goto Lcheckhint;
+ }
+
+ switch (command.word[0].type) {
+ case NO_WORD_TYPE: // FIXME: treating NO_WORD_TYPE as a motion word is confusing
+ case MOTION:
+ playermove(command.word[0].id);
+ return true;
+ case OBJECT:
+ command.part = unknown;
+ command.obj = command.word[0].id;
+ break;
+ case ACTION:
+ if (command.word[1].type == NUMERIC)
+ command.part = transitive;
+ else
+ command.part = intransitive;
+ command.verb = command.word[0].id;
+ break;
+ case NUMERIC:
+ if (!settings.oldstyle) {
+ sspeak(DONT_KNOW, command.word[0].raw);
+ clear_command(&command);
+ goto Lcheckhint;
+ }
+ default: // LCOV_EXCL_LINE
+ BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3); // LCOV_EXCL_LINE
+ }
+
+ switch (action(command)) {
+ case GO_TERMINATE:
+ return true;
+ case GO_MOVE:
+ playermove(NUL);
+ return true;
+ case GO_TOP:
+ continue; /* back to top of main interpreter loop */
+ case GO_CLEAROBJ:
+ clear_command(&command);
+ /* FALL THROUGH */
+ case GO_CHECKHINT:
+ goto Lcheckhint;
+ case GO_WORD2:
#ifdef GDEBUG
- printf("Word shift\n");
+ printf("Word shift\n");
#endif /* GDEBUG */
- /* Get second word for analysis. */
- command.word[0] = command.word[1];
- command.word[1] = empty_command_word;
- goto Lookup;
- case GO_UNKNOWN:
- /* Random intransitive verbs come here. Clear obj just in case
- * (see attack()). */
- command.word[0].raw[0] = toupper(command.word[0].raw[0]);
- sspeak(DO_WHAT, command.word[0].raw);
- command.obj = 0;
- goto L2600;
- case GO_DWARFWAKE:
- /* Oh dear, he's disturbed the dwarves. */
- rspeak(DWARVES_AWAKEN);
- terminate(endgame);
- default: // LCOV_EXCL_LINE
- BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH); // LCOV_EXCL_LINE
- }
- }
+ /* Get second word for analysis. */
+ command.word[0] = command.word[1];
+ command.word[1] = empty_command_word;
+ words_processed = false;
+ break;
+ case GO_UNKNOWN:
+ /* Random intransitive verbs come here. Clear obj just in case
+ * (see attack()). */
+ command.word[0].raw[0] = toupper(command.word[0].raw[0]);
+ sspeak(DO_WHAT, command.word[0].raw);
+ command.obj = 0;
+ goto Lcheckhint;
+ case GO_DWARFWAKE:
+ /* Oh dear, he's disturbed the dwarves. */
+ rspeak(DWARVES_AWAKEN);
+ terminate(endgame);
+ default: // LCOV_EXCL_LINE
+ BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH); // LCOV_EXCL_LINE
+ }
+ } while (!words_processed);
+ }
}
/* end */