-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 && command.id2 != WORD_EMPTY) {
- if (++game.igo == 10)
- rspeak(GO_UNNEEDED);
- }
- if (command.id1 == WORD_NOT_FOUND) {
- if (fallback_handler(command))
- continue;
- /* Gee, I don't understand. */
- sspeak(DONT_KNOW, command.raw1);
- goto Lclearobj;
- }
- switch (command.type1) {
- case NO_WORD_TYPE: // FIXME: treating NO_WORD_TYPE as a motion word is confusing
- case MOTION:
- playermove(command.id1);
- return true;
- case OBJECT:
- command.part = unknown;
- command.obj = command.id1;
+ switch (action(command)) {
+ case GO_TERMINATE:
+ command.state = EXECUTED;
+ break;
+ case GO_MOVE:
+ playermove(NUL);
+ command.state = EXECUTED;
+ break;
+ case GO_WORD2:
+#ifdef GDEBUG
+ printf("Word shift\n");
+#endif /* GDEBUG */
+ /* Get second word for analysis. */
+ command.word[0] = command.word[1];
+ command.word[1] = empty_command_word;
+ command.state = PREPROCESSED;
+ 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 = NO_OBJECT;
+
+ /* object cleared; we need to go back to the preprocessing step */
+ command.state = GIVEN;
+ break;
+ case GO_CHECKHINT: // FIXME: re-name to be more contextual; this was previously a label
+ command.state = GIVEN;
+ break;
+ case GO_DWARFWAKE:
+ /* Oh dear, he's disturbed the dwarves. */
+ rspeak(DWARVES_AWAKEN);
+ terminate(endgame);
+ case GO_CLEAROBJ: // FIXME: re-name to be more contextual; this was previously a label
+ clear_command(&command);
+ break;
+ case GO_TOP: // FIXME: re-name to be more contextual; this was previously a label
+ break;
+ default: // LCOV_EXCL_LINE
+ BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH); // LCOV_EXCL_LINE
+ }
+ } /* while command has not been fully processed */
+ } /* while command is not yet given */
+ } /* while command is not executed */
+
+ /* command completely executed; we return true. */
+ return true;
+}
+
+/*
+ * MAIN PROGRAM
+ *
+ * Adventure (rev 2: 20 treasures)
+ * History: Original idea & 5-treasure version (adventures) by Willie Crowther
+ * 15-treasure version (adventure) by Don Woods, April-June 1977
+ * 20-treasure version (rev 2) by Don Woods, August 1978
+ * Errata fixed: 78/12/25
+ * Revived 2017 as Open Adventure.
+ */
+
+int main(int argc, char *argv[])
+{
+ int ch;
+
+ /* Options. */
+
+#if defined ADVENT_AUTOSAVE
+ const char* opts = "l:oa:";
+ const char* usage = "Usage: %s [-l logfilename] [-o] [-a filename] [script...]\n";
+ FILE *rfp = NULL;
+ const char* autosave_filename = NULL;
+#elif !defined ADVENT_NOSAVE
+ const char* opts = "l:or:";
+ const char* usage = "Usage: %s [-l logfilename] [-o] [-r restorefilename] [script...]\n";
+ FILE *rfp = NULL;
+#else
+ const char* opts = "l:o";
+ const char* usage = "Usage: %s [-l logfilename] [-o] [script...]\n";
+#endif
+ while ((ch = getopt(argc, argv, opts)) != EOF) {
+ switch (ch) {
+ case 'l':
+ settings.logfp = fopen(optarg, "w");
+ if (settings.logfp == NULL)
+ fprintf(stderr,
+ "advent: can't open logfile %s for write\n",
+ optarg);
+ signal(SIGINT, sig_handler);
+ break;
+ case 'o':
+ settings.oldstyle = true;
+ settings.prompt = false;