- ++game.abbrev[game.loc];
- for (int i=game.atloc[game.loc]; i != 0; i=game.link[i]) {
- long obj=i;
- if (obj > NOBJECTS)obj=obj-NOBJECTS;
- if (obj == STEPS && TOTING(NUGGET))
- continue;
- if (game.prop[obj] < 0) {
- if (game.closed)
- continue;
- game.prop[obj]=0;
- if (obj == RUG || obj == CHAIN)
- game.prop[obj]=1;
- --game.tally;
- /* Note: There used to be a test here to see whether the
- * player had blown it so badly that he could never ever see
- * the remaining treasures, and if so the lamp was zapped to
- * 35 turns. But the tests were too simple-minded; things
- * like killing the bird before the snake was gone (can never
- * see jewelry), and doing it "right" was hopeless. E.G.,
- * could cross troll bridge several times, using up all
- * available treasures, breaking vase, using coins to buy
- * batteries, etc., and eventually never be able to get
- * across again. If bottle were left on far side, could then
- * never get eggs or trident, and the effects propagate. So
- * the whole thing was flushed. anyone who makes such a
- * gross blunder isn't likely to find everything else anyway
- * (so goes the rationalisation). */
- }
- int kk=game.prop[obj];
- if (obj == STEPS && game.loc == game.fixed[STEPS])
- kk=1;
- PSPEAK(obj,kk);
- }
+ ++game.abbrev[game.loc];
+ for (int i = game.atloc[game.loc]; i != 0; i = game.link[i]) {
+ obj_t obj = i;
+ if (obj > NOBJECTS)
+ obj = obj - NOBJECTS;
+ if (obj == STEPS && TOTING(NUGGET))
+ continue;
+ if (game.prop[obj] < 0) {
+ if (game.closed)
+ continue;
+ game.prop[obj] = STATE_FOUND;
+ if (obj == RUG)
+ game.prop[RUG] = RUG_DRAGON;
+ if (obj == CHAIN)
+ game.prop[CHAIN] = CHAINING_BEAR;
+ --game.tally;
+ /* Note: There used to be a test here to see whether the
+ * player had blown it so badly that he could never ever see
+ * the remaining treasures, and if so the lamp was zapped to
+ * 35 turns. But the tests were too simple-minded; things
+ * like killing the bird before the snake was gone (can never
+ * see jewelry), and doing it "right" was hopeless. E.G.,
+ * could cross troll bridge several times, using up all
+ * available treasures, breaking vase, using coins to buy
+ * batteries, etc., and eventually never be able to get
+ * across again. If bottle were left on far side, could then
+ * never get eggs or trident, and the effects propagate. So
+ * the whole thing was flushed. anyone who makes such a
+ * gross blunder isn't likely to find everything else anyway
+ * (so goes the rationalisation). */
+ }
+ int kk = game.prop[obj];
+ if (obj == STEPS)
+ kk = (game.loc == game.fixed[STEPS])
+ ? STEPS_UP
+ : STEPS_DOWN;
+ pspeak(obj, look, true, kk);
+ }
+ }
+}
+
+void clear_command(command_t *cmd)
+{
+ cmd->verb = ACT_NULL;
+ game.oldobj = cmd->obj;
+ cmd->obj = NO_OBJECT;
+}
+
+void close_cleanup_before_command(void)
+/* If closing time, check for any objects being toted with
+ * game.prop < 0 and stash them. This way objects won't be
+ * described until they've been picked up and put down
+ * separate from their respective piles. */
+{
+ if (game.closed) {
+ if (game.prop[OYSTER] < 0 && TOTING(OYSTER))
+ pspeak(OYSTER, look, true, 1);
+ for (size_t i = 1; i <= NOBJECTS; i++) {
+ if (TOTING(i) && game.prop[i] < 0)
+ game.prop[i] = STASHED(i);
+ }
+ }
+}
+
+bool preprocess_command(command_t *command)
+/* Pre-processes a command input to see if we need to tease out a few specific cases:
+ * - "enter water" or "enter stream":
+ * wierd specific case that gets the user wet, and then kicks us back to get another command
+ * - <object> <verb>:
+ * Irregular form of input, but should be allowed. We switch back to <verb> <object> form for
+ * furtherprocessing.
+ * - "grate":
+ * If in location with grate, we move to that grate. If we're in a number of other places,
+ * we move to the entrance.
+ * - "water plant", "oil plant", "water door", "oil door":
+ * Change to "pour water" or "pour oil" based on context
+ * - "cage bird":
+ * If bird is present, we change to "carry bird"
+ *
+ * Returns true if pre-processing is complete, and we're ready to move to the primary command
+ * processing, false otherwise. */
+{
+ if (command->word[0].type == MOTION && command->word[0].id == ENTER
+ && (command->word[1].id == STREAM || command->word[1].id == WATER)) {
+ if (LIQLOC(game.loc) == WATER)
+ rspeak(FEET_WET);
+ else
+ rspeak(WHERE_QUERY);
+ } else {
+ if (command->word[0].type == OBJECT) {
+ /* From OV to VO form */
+ if (command->word[1].type == ACTION) {
+ command_word_t stage = command->word[0];
+ command->word[0] = command->word[1];
+ command->word[1] = stage;
+ }
+
+ if (command->word[0].id == GRATE) {
+ command->word[0].type = MOTION;
+ if (game.loc == LOC_START ||
+ game.loc == LOC_VALLEY ||
+ game.loc == LOC_SLIT) {
+ command->word[0].id = DEPRESSION;
+ }
+ if (game.loc == LOC_COBBLE ||
+ game.loc == LOC_DEBRIS ||
+ game.loc == LOC_AWKWARD ||
+ game.loc == LOC_BIRD ||
+ game.loc == LOC_PITTOP) {
+ command->word[0].id = ENTRANCE;
+ }
+ }
+ if ((command->word[0].id == WATER || command->word[0].id == OIL) &&
+ (command->word[1].id == PLANT || command->word[1].id == DOOR)) {
+ if (AT(command->word[1].id)) {
+ command->word[1] = command->word[0];
+ command->word[0].id = POUR;
+ command->word[0].type = ACTION;
+ strncpy(command->word[0].raw, "pour", LINESIZE - 1);
+ }
+ }
+ if (command->word[0].id == CAGE && command->word[1].id == BIRD && HERE(CAGE) && HERE(BIRD)) {
+ command->word[0].id = CARRY;
+ command->word[0].type = ACTION;
+ }
+ }
+
+ return true;