-static void playermove(int motion)
-{
- int scratchloc, travel_entry = tkey[game.loc];
- game.newloc = game.loc;
- if (travel_entry == 0)
- BUG(LOCATION_HAS_NO_TRAVEL_ENTRIES); // LCOV_EXCL_LINE
- if (motion == NUL)
- return;
- else if (motion == BACK) {
- /* Handle "go back". Look for verb which goes from game.loc to
- * game.oldloc, or to game.oldlc2 If game.oldloc has forced-motion.
- * te_tmp saves entry -> forced loc -> previous loc. */
- motion = game.oldloc;
- if (FORCED(motion))
- motion = game.oldlc2;
- game.oldlc2 = game.oldloc;
- game.oldloc = game.loc;
- if (CNDBIT(game.loc, COND_NOBACK)) {
- rspeak(TWIST_TURN);
- return;
- }
- if (motion == game.loc) {
- rspeak(FORGOT_PATH);
- return;
- }
-
- 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;
- }
- }
-
- 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
- * (though it may now be dark) so he won't fall into a
- * pit while staring into the gloom. */
- if (game.detail < 3)
- rspeak(NO_MORE_DETAIL);
- ++game.detail;
- game.wzdark = false;
- game.abbrev[game.loc] = 0;
- return;
- } else if (motion == CAVE) {
- /* Cave. Different messages depending on whether above ground. */
- rspeak((OUTSID(game.loc) && game.loc != LOC_GRATE) ? FOLLOW_STREAM : NEED_DETAIL);
- return;
- } else {
- /* none of the specials */
- game.oldlc2 = game.oldloc;
- game.oldloc = game.loc;
- }
-
- /* Look for a way to fulfil the motion verb passed in - travel_entry indexes
- * the beginning of the motion entries for here (game.loc). */
- for (;;) {
- if ((travel[travel_entry].motion == HERE) ||
- travel[travel_entry].motion == motion)
- break;
- if (travel[travel_entry].stop) {
- /* Couldn't find an entry matching the motion word passed
- * in. Various messages depending on word given. */
- switch (motion) {
- case EAST:
- case WEST:
- case SOUTH:
- case NORTH:
- case NE:
- case NW:
- case SW:
- case SE:
- case UP:
- case DOWN:
- rspeak(BAD_DIRECTION);
- break;
- case FORWARD:
- case LEFT:
- case RIGHT:
- rspeak(UNSURE_FACING);
- break;
- case OUTSIDE:
- case INSIDE:
- rspeak(NO_INOUT_HERE);
- break;
- case XYZZY:
- case PLUGH:
- rspeak(NOTHING_HAPPENS);
- break;
- case CRAWL:
- rspeak(WHICH_WAY);
- break;
- default:
- rspeak(CANT_APPLY);
- }
- return;
- }
- ++travel_entry;
- }
-
- /* (ESR) We've found a destination that goes with the motion verb.
- * Next we need to check any conditional(s) on this destination, and
- * possibly on following entries. */
- do {
- for (;;) { /* L12 loop */
- for (;;) {
- enum condtype_t condtype = travel[travel_entry].condtype;
- int condarg1 = travel[travel_entry].condarg1;
- int condarg2 = travel[travel_entry].condarg2;
- if (condtype < cond_not) {
- /* YAML N and [pct N] conditionals */
- if (condtype == cond_goto || condtype == cond_pct) {
- if (condarg1 == 0 ||
- PCT(condarg1))
- break;
- /* else fall through */
- }
- /* YAML [with OBJ] clause */
- else if (TOTING(condarg1) ||
- (condtype == cond_with && AT(condarg1)))
- break;
- /* else fall through to check [not OBJ STATE] */
- } else if (game.prop[condarg1] != condarg2)
- break;
-
- /* We arrive here on conditional failure.
- * Skip to next non-matching destination */
- int te_tmp = travel_entry;
- do {
- if (travel[te_tmp].stop)
- BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); // LCOV_EXCL_LINE
- ++te_tmp;
- } while
- (traveleq(travel_entry, te_tmp));
- travel_entry = te_tmp;
- }
-
- /* Found an eligible rule, now execute it */
- enum desttype_t desttype = travel[travel_entry].desttype;
- game.newloc = travel[travel_entry].destval;
- if (desttype == dest_goto)
- return;
-
- if (desttype == dest_speak) {
- /* Execute a speak rule */
- rspeak(game.newloc);
- game.newloc = game.loc;
- return;
- } else {
- switch (game.newloc) {
- case 1:
- /* Special travel 1. Plover-alcove passage. Can carry only
- * emerald. Note: travel table must include "useless"
- * entries going through passage, which can never be used
- * for actual motion, but can be spotted by "go back". */
- game.newloc = (game.loc == LOC_PLOVER)
- ? LOC_ALCOVE
- : LOC_PLOVER;
- if (game.holdng > 1 ||
- (game.holdng == 1 && !TOTING(EMERALD))) {
- game.newloc = game.loc;
- rspeak(MUST_DROP);
- }
- return;
- case 2:
- /* Special travel 2. Plover transport. Drop the
- * emerald (only use special travel if toting
- * it), so he's forced to use the plover-passage
- * to get it out. Having dropped it, go back and
- * pretend he wasn't carrying it after all. */
- drop(EMERALD, game.loc);
- {
- int te_tmp = travel_entry;
- do {
- if (travel[te_tmp].stop)
- BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); // LCOV_EXCL_LINE
- ++te_tmp;
- } while
- (traveleq(travel_entry, te_tmp));
- travel_entry = te_tmp;
- }
- continue; /* goto L12 */
- case 3:
- /* Special travel 3. Troll bridge. Must be done
- * only as special motion so that dwarves won't
- * wander across and encounter the bear. (They
- * won't follow the player there because that
- * region is forbidden to the pirate.) If
- * game.prop[TROLL]=TROLL_PAIDONCE, he's crossed
- * since paying, so step out and block him.
- * (standard travel entries check for
- * game.prop[TROLL]=TROLL_UNPAID.) Special stuff
- * for bear. */
- if (game.prop[TROLL] == TROLL_PAIDONCE) {
- pspeak(TROLL, look, true, TROLL_PAIDONCE);
- game.prop[TROLL] = TROLL_UNPAID;
- DESTROY(TROLL2);
- move(TROLL2 + NOBJECTS, IS_FREE);
- move(TROLL, objects[TROLL].plac);
- move(TROLL + NOBJECTS, objects[TROLL].fixd);
- juggle(CHASM);
- game.newloc = game.loc;
- return;
- } else {
- game.newloc = objects[TROLL].plac + objects[TROLL].fixd - game.loc;
- if (game.prop[TROLL] == TROLL_UNPAID)
- game.prop[TROLL] = TROLL_PAIDONCE;
- if (!TOTING(BEAR))
- return;
- state_change(CHASM, BRIDGE_WRECKED);
- game.prop[TROLL] = TROLL_GONE;
- drop(BEAR, game.newloc);
- game.fixed[BEAR] = IS_FIXED;
- game.prop[BEAR] = BEAR_DEAD;
- game.oldlc2 = game.newloc;
- croak();
- return;
- }
- default: // LCOV_EXCL_LINE
- BUG(SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE
- }
- }
- break; /* Leave L12 loop */
- }
- } while
- (false);
+static void playermove(int motion) {
+ int scratchloc, travel_entry = tkey[game.loc];
+ game.newloc = game.loc;
+ if (travel_entry == 0) {
+ BUG(LOCATION_HAS_NO_TRAVEL_ENTRIES); // LCOV_EXCL_LINE
+ }
+ if (motion == NUL) {
+ return;
+ } else if (motion == BACK) {
+ /* Handle "go back". Look for verb which goes from game.loc to
+ * game.oldloc, or to game.oldlc2 If game.oldloc has
+ * forced-motion. te_tmp saves entry -> forced loc -> previous
+ * loc. */
+ motion = game.oldloc;
+ if (FORCED(motion)) {
+ motion = game.oldlc2;
+ }
+ game.oldlc2 = game.oldloc;
+ game.oldloc = game.loc;
+ if (CNDBIT(game.loc, COND_NOBACK)) {
+ rspeak(TWIST_TURN);
+ return;
+ }
+ if (motion == game.loc) {
+ rspeak(FORGOT_PATH);
+ return;
+ }
+
+ 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;
+ }
+ }
+
+ 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
+ * (though it may now be dark) so he won't fall into a
+ * pit while staring into the gloom. */
+ if (game.detail < 3) {
+ rspeak(NO_MORE_DETAIL);
+ }
+ ++game.detail;
+ game.wzdark = false;
+ game.locs[game.loc].abbrev = 0;
+ return;
+ } else if (motion == CAVE) {
+ /* Cave. Different messages depending on whether above ground.
+ */
+ rspeak((OUTSID(game.loc) && game.loc != LOC_GRATE)
+ ? FOLLOW_STREAM
+ : NEED_DETAIL);
+ return;
+ } else {
+ /* none of the specials */
+ game.oldlc2 = game.oldloc;
+ game.oldloc = game.loc;
+ }
+
+ /* Look for a way to fulfil the motion verb passed in - travel_entry
+ * indexes the beginning of the motion entries for here (game.loc). */
+ for (;;) {
+ if ((travel[travel_entry].motion == HERE) ||
+ travel[travel_entry].motion == motion) {
+ break;
+ }
+ if (travel[travel_entry].stop) {
+ /* Couldn't find an entry matching the motion word
+ * passed in. Various messages depending on word given.
+ */
+ switch (motion) {
+ case EAST:
+ case WEST:
+ case SOUTH:
+ case NORTH:
+ case NE:
+ case NW:
+ case SW:
+ case SE:
+ case UP:
+ case DOWN:
+ rspeak(BAD_DIRECTION);
+ break;
+ case FORWARD:
+ case LEFT:
+ case RIGHT:
+ rspeak(UNSURE_FACING);
+ break;
+ case OUTSIDE:
+ case INSIDE:
+ rspeak(NO_INOUT_HERE);
+ break;
+ case XYZZY:
+ case PLUGH:
+ rspeak(NOTHING_HAPPENS);
+ break;
+ case CRAWL:
+ rspeak(WHICH_WAY);
+ break;
+ default:
+ rspeak(CANT_APPLY);
+ }
+ return;
+ }
+ ++travel_entry;
+ }
+
+ /* (ESR) We've found a destination that goes with the motion verb.
+ * Next we need to check any conditional(s) on this destination, and
+ * possibly on following entries. */
+ do {
+ for (;;) { /* L12 loop */
+ for (;;) {
+ enum condtype_t condtype =
+ travel[travel_entry].condtype;
+ int condarg1 = travel[travel_entry].condarg1;
+ int condarg2 = travel[travel_entry].condarg2;
+ if (condtype < cond_not) {
+ /* YAML N and [pct N] conditionals */
+ if (condtype == cond_goto ||
+ condtype == cond_pct) {
+ if (condarg1 == 0 ||
+ PCT(condarg1)) {
+ break;
+ }
+ /* else fall through */
+ }
+ /* YAML [with OBJ] clause */
+ else if (TOTING(condarg1) ||
+ (condtype == cond_with &&
+ AT(condarg1))) {
+ break;
+ }
+ /* else fall through to check [not OBJ
+ * STATE] */
+ } else if (game.objects[condarg1].prop !=
+ condarg2) {
+ break;
+ }
+
+ /* We arrive here on conditional failure.
+ * Skip to next non-matching destination */
+ int te_tmp = travel_entry;
+ do {
+ if (travel[te_tmp].stop) {
+ BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); // LCOV_EXCL_LINE
+ }
+ ++te_tmp;
+ } while (traveleq(travel_entry, te_tmp));
+ travel_entry = te_tmp;
+ }
+
+ /* Found an eligible rule, now execute it */
+ enum desttype_t desttype =
+ travel[travel_entry].desttype;
+ game.newloc = travel[travel_entry].destval;
+ if (desttype == dest_goto) {
+ return;
+ }
+
+ if (desttype == dest_speak) {
+ /* Execute a speak rule */
+ rspeak(game.newloc);
+ game.newloc = game.loc;
+ return;
+ } else {
+ switch (game.newloc) {
+ case 1:
+ /* Special travel 1. Plover-alcove
+ * passage. Can carry only emerald.
+ * Note: travel table must include
+ * "useless" entries going through
+ * passage, which can never be used for
+ * actual motion, but can be spotted by
+ * "go back". */
+ game.newloc = (game.loc == LOC_PLOVER)
+ ? LOC_ALCOVE
+ : LOC_PLOVER;
+ if (game.holdng > 1 ||
+ (game.holdng == 1 &&
+ !TOTING(EMERALD))) {
+ game.newloc = game.loc;
+ rspeak(MUST_DROP);
+ }
+ return;
+ case 2:
+ /* Special travel 2. Plover transport.
+ * Drop the emerald (only use special
+ * travel if toting it), so he's forced
+ * to use the plover-passage to get it
+ * out. Having dropped it, go back and
+ * pretend he wasn't carrying it after
+ * all. */
+ drop(EMERALD, game.loc);
+ {
+ int te_tmp = travel_entry;
+ do {
+ if (travel[te_tmp]
+ .stop) {
+ BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION); // LCOV_EXCL_LINE
+ }
+ ++te_tmp;
+ } while (traveleq(travel_entry,
+ te_tmp));
+ travel_entry = te_tmp;
+ }
+ continue; /* goto L12 */
+ case 3:
+ /* Special travel 3. Troll bridge. Must
+ * be done only as special motion so
+ * that dwarves won't wander across and
+ * encounter the bear. (They won't
+ * follow the player there because that
+ * region is forbidden to the pirate.)
+ * If game.prop[TROLL]=TROLL_PAIDONCE,
+ * he's crossed since paying, so step
+ * out and block him. (standard travel
+ * entries check for
+ * game.prop[TROLL]=TROLL_UNPAID.)
+ * Special stuff for bear. */
+ if (game.objects[TROLL].prop ==
+ TROLL_PAIDONCE) {
+ pspeak(TROLL, look, true,
+ TROLL_PAIDONCE);
+ game.objects[TROLL].prop =
+ TROLL_UNPAID;
+ DESTROY(TROLL2);
+ move(TROLL2 + NOBJECTS,
+ IS_FREE);
+ move(TROLL,
+ objects[TROLL].plac);
+ move(TROLL + NOBJECTS,
+ objects[TROLL].fixd);
+ juggle(CHASM);
+ game.newloc = game.loc;
+ return;
+ } else {
+ game.newloc =
+ objects[TROLL].plac +
+ objects[TROLL].fixd -
+ game.loc;
+ if (game.objects[TROLL].prop ==
+ TROLL_UNPAID) {
+ game.objects[TROLL]
+ .prop =
+ TROLL_PAIDONCE;
+ }
+ if (!TOTING(BEAR)) {
+ return;
+ }
+ state_change(CHASM,
+ BRIDGE_WRECKED);
+ game.objects[TROLL].prop =
+ TROLL_GONE;
+ drop(BEAR, game.newloc);
+ game.objects[BEAR].fixed =
+ IS_FIXED;
+ game.objects[BEAR].prop =
+ BEAR_DEAD;
+ game.oldlc2 = game.newloc;
+ croak();
+ return;
+ }
+ default: // LCOV_EXCL_LINE
+ BUG(SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE
+ }
+ }
+ break; /* Leave L12 loop */
+ }
+ } while (false);