static int fill(token_t, token_t);
static void state_change(long obj, long state)
+/* Object must have a change-message list for this to be useful; only some do */
{
game.prop[obj] = state;
pspeak(obj, change, state, true);
}
game.prop[BIRD] = BIRD_CAGED;
}
- /* FIXME: Arithmetic on state numbers */
if ((obj == BIRD ||
obj == CAGE) &&
(game.prop[BIRD] == BIRD_CAGED || STASHED(BIRD) == BIRD_CAGED))
+ /* expression maps BIRD to CAGE and CAGE to BIRD */
carry(BIRD + CAGE - obj, game.loc);
carry(obj, game.loc);
if (obj == BOTTLE && LIQUID() != NO_OBJECT)
game.place[LIQUID()] = CARRIED;
- if (GSTONE(obj) && game.prop[obj] != 0) {
- game.prop[obj]
- = STATE_GROUND;
+ if (GSTONE(obj) && game.prop[obj] != STATE_GROUND) {
+ game.prop[obj] = STATE_GROUND;
game.prop[CAVITY] = CAVITY_EMPTY;
}
rspeak(OK_MAN);
} else if ((GSTONE(obj) && AT(CAVITY) && game.prop[CAVITY] != CAVITY_FULL)) {
rspeak(GEM_FITS);
- game.prop[obj] = 1;
+ game.prop[obj] = STATE_IN_CAVITY;
game.prop[CAVITY] = CAVITY_FULL;
if (HERE(RUG) && ((obj == EMERALD && game.prop[RUG] != RUG_HOVER) ||
(obj == RUBY && game.prop[RUG] == RUG_HOVER))) {
/* Special object-state values - integers > 0 are object-specific */
#define STATE_NOTFOUND -1 // 'Not found" state of treasures */
#define STATE_GROUND 0 // After discovered, before messed with
+#define STATE_IN_CAVITY 1 // State value common to all gemstones
/* Map a state property value to a negative range, where the object cannot be
* picked up but the value can be recovered later. Avoid colliding with -1,
token_t wd2;
long id1;
long id2;
- char raw1[BUFSIZ], raw2[BUFSIZ];
+ char raw1[LINESIZE], raw2[LINESIZE];
};
extern struct game_t game;
inventory: '*steps'
locations: [LOC_PITTOP, LOC_MISTHALL]
immovable: true
+ states: [STEPS_DOWN, STEPS_UP]
descriptions:
- 'Rough stone steps lead down the pit.'
- 'Rough stone steps lead up the dome.'
* problems arise from the use of negative prop numbers to suppress
* the object descriptions until he's actually moved the objects. */
{
+ /* Don't tick game.clock1 unless well into cave (and not at Y2). */
if (game.tally == 0 && INDEEP(game.loc) && game.loc != LOC_Y2)
--game.clock1;
* (so goes the rationalisation). */
}
int kk = game.prop[obj];
- if (obj == STEPS && game.loc == game.fixed[STEPS])
- kk = 1;
+ if (obj == STEPS)
+ kk = (game.loc == game.fixed[STEPS])
+ ? STEPS_UP
+ : STEPS_DOWN;
pspeak(obj, look, kk, true);
}
}
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). */
+ * 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, 1, true);
{
memset(cmd, '\0', sizeof(struct command_t));
- /* FIXME: put a bound prefix on the %s to prevent buffer overflow */
+ /* Bound prefix on the %s would be needed to prevent buffer
+ * overflow. but we shortstop this more simply by making each
+ * raw-input buffer as long as the enrire inout buffer. */
sscanf(raw, "%s%s", cmd->raw1, cmd->raw2);
// pack the substrings