}
}
-static int bivalve(token_t verb, token_t obj)
-/* Clam/oyster actions */
-{
- bool is_oyster = (obj == OYSTER);
- if (verb == LOCK) {
- rspeak(HUH_MAN);
- return GO_CLEAROBJ;
- }
- if (!TOTING(TRIDENT)) {
- rspeak(is_oyster ?
- OYSTER_OPENER :
- CLAM_OPENER);
- return GO_CLEAROBJ;
- }
- if (TOTING(obj)) {
- rspeak( is_oyster ?
- DROP_OYSTER :
- DROP_CLAM);
- return GO_CLEAROBJ;
- }
-
- if (!is_oyster) {
- DESTROY(CLAM);
- drop(OYSTER, game.loc);
- drop(PEARL, LOC_CULDESAC);
- }
- rspeak(is_oyster ?
- OYSTER_OPENS :
- PEARL_FALLS);
- return GO_CLEAROBJ;
-}
-
static void blast(void)
/* Blast. No effect unless you've got dynamite, which is a neat trick! */
{
static int chain(token_t verb)
/* Do something to the bear's chain */
{
- int spk;
if (verb != LOCK) {
- spk = CHAIN_UNLOCKED;
- if (game.prop[BEAR] == UNTAMED_BEAR)
- spk = BEAR_BLOCKS;
- if (game.prop[CHAIN] == CHAIN_HEAP)
- spk = ALREADY_UNLOCKED;
- if (spk != CHAIN_UNLOCKED) {
- rspeak(spk);
+ if (game.prop[BEAR] == UNTAMED_BEAR) {
+ rspeak(BEAR_BLOCKS);
+ return GO_CLEAROBJ;
+ }
+ if (game.prop[CHAIN] == CHAIN_HEAP) {
+ rspeak(ALREADY_UNLOCKED);
return GO_CLEAROBJ;
}
game.prop[CHAIN] = CHAIN_HEAP;
game.fixed[CHAIN] = CHAIN_HEAP;
if (game.prop[BEAR] != BEAR_DEAD)
game.prop[BEAR] = CONTENTED_BEAR;
- /* FIXME: Arithmetic on state numbers */
- game.fixed[BEAR] = 2 - game.prop[BEAR];
- } else {
- spk = CHAIN_LOCKED;
- if (game.prop[CHAIN] != CHAIN_HEAP)
- spk = ALREADY_LOCKED;
- if (game.loc != objects[CHAIN].plac)
- spk = NO_LOCKSITE;
- if (spk != CHAIN_LOCKED) {
- rspeak(spk);
- return GO_CLEAROBJ;
+
+ switch (game.prop[BEAR]) {
+ case BEAR_DEAD:
+ game.fixed[BEAR] = -1;
+ break;
+ default:
+ game.fixed[BEAR] = 0;
}
- game.prop[CHAIN] = CHAIN_FIXED;
- if (TOTING(CHAIN))
- drop(CHAIN, game.loc);
- game.fixed[CHAIN] = -1;
+ rspeak(CHAIN_UNLOCKED);
+ return GO_CLEAROBJ;
}
- rspeak(spk);
+
+ if (game.prop[CHAIN] != CHAIN_HEAP) {
+ rspeak(ALREADY_LOCKED);
+ return GO_CLEAROBJ;
+ }
+ if (game.loc != objects[CHAIN].plac) {
+ rspeak(NO_LOCKSITE);
+ return GO_CLEAROBJ;
+ }
+
+ game.prop[CHAIN] = CHAIN_FIXED;
+
+ if (TOTING(CHAIN))
+ drop(CHAIN, game.loc);
+ game.fixed[CHAIN] = -1;
+
+ rspeak(CHAIN_LOCKED);
return GO_CLEAROBJ;
}
/* Drink. If no object, assume water and look for it here. If water is in
* the bottle, drink that, else must be at a water loc, so drink stream. */
{
- if (obj == NO_OBJECT && LIQLOC(game.loc) != WATER && (LIQUID() != WATER ||
- !HERE(BOTTLE)))
+ if (obj == NO_OBJECT && LIQLOC(game.loc) != WATER &&
+ (LIQUID() != WATER || !HERE(BOTTLE))) {
return GO_UNKNOWN;
- if (obj != BLOOD) {
- if (obj != NO_OBJECT && obj != WATER) {
- rspeak(RIDICULOUS_ATTEMPT);
- } else if (LIQUID() == WATER && HERE(BOTTLE)) {
- game.prop[BOTTLE] = EMPTY_BOTTLE;
- game.place[WATER] = LOC_NOWHERE;
- rspeak(BOTTLE_EMPTY);
- } else {
- rspeak(actions[verb].message);
- }
- } else {
+ }
+
+ if (obj == BLOOD) {
DESTROY(BLOOD);
state_change(DRAGON, DRAGON_BLOODLESS);
game.blooded = true;
+ return GO_CLEAROBJ;
+ }
+
+ if (obj != NO_OBJECT && obj != WATER) {
+ rspeak(RIDICULOUS_ATTEMPT);
+ return GO_CLEAROBJ;
+ }
+ if (LIQUID() == WATER && HERE(BOTTLE)) {
+ game.prop[BOTTLE] = EMPTY_BOTTLE;
+ game.place[WATER] = LOC_NOWHERE;
+ rspeak(BOTTLE_EMPTY);
+ return GO_CLEAROBJ;
}
+
+ rspeak(actions[verb].message);
return GO_CLEAROBJ;
}
obj = LAMP;
if (HERE(URN) && game.prop[URN] == URN_LIT)
obj = URN;
- if (obj == INTRANSITIVE ||
- (HERE(LAMP) && game.prop[LAMP] == LAMP_BRIGHT &&
- HERE(URN) && game.prop[URN] == URN_LIT))
+ if (obj == INTRANSITIVE)
return GO_UNKNOWN;
}
} else {
pspeak(URN, change, URN_DARK, true);
}
+ return GO_CLEAROBJ;
+ }
- } else if (obj == LAMP) {
+ if (obj == LAMP) {
state_change(LAMP, LAMP_DARK);
rspeak(DARK(game.loc) ?
PITCH_DARK :
NO_MESSAGE);
+ return GO_CLEAROBJ;
+ }
- } else if (obj == DRAGON ||
- obj == VOLCANO) {
+ if (obj == DRAGON ||
+ obj == VOLCANO) {
rspeak(BEYOND_POWER);
-
- } else {
- rspeak(actions[verb].message);
+ return GO_CLEAROBJ;
}
+
+ rspeak(actions[verb].message);
return GO_CLEAROBJ;
}
/* Fill. Bottle or urn must be empty, and liquid available. (Vase
* is nasty.) */
{
- int k;
- int spk = actions[verb].message;
if (obj == VASE) {
- spk = ARENT_CARRYING;
- if (LIQLOC(game.loc) == 0)
- spk = FILL_INVALID;
- if (LIQLOC(game.loc) == 0 ||
- !TOTING(VASE)) {
- rspeak(spk);
+ if (LIQLOC(game.loc) == NO_OBJECT) {
+ rspeak(FILL_INVALID);
+ return GO_CLEAROBJ;
+ }
+ if (!TOTING(VASE)) {
+ rspeak(ARENT_CARRYING);
return GO_CLEAROBJ;
}
rspeak(SHATTER_VASE);
game.prop[VASE] = VASE_BROKEN;
game.fixed[VASE] = -1;
return (discard(verb, obj, true));
- } else if (obj == URN) {
- spk = FULL_URN;
+ }
+
+ if (obj == URN) {
if (game.prop[URN] != URN_EMPTY) {
- rspeak(spk);
+ rspeak(FULL_URN);
return GO_CLEAROBJ;
}
- spk = FILL_INVALID;
- k = LIQUID();
- if (k == 0 ||
- !HERE(BOTTLE)) {
- rspeak(spk);
+ if (!HERE(BOTTLE)) {
+ rspeak(FILL_INVALID);
return GO_CLEAROBJ;
}
- game.place[k] = LOC_NOWHERE;
- game.prop[BOTTLE] = EMPTY_BOTTLE;
- if (k == OIL)
+ int k = LIQUID();
+ switch (k) {
+ case WATER:
+ game.prop[BOTTLE] = EMPTY_BOTTLE;
+ rspeak(WATER_URN);
+ break;
+ case OIL:
game.prop[URN] = URN_DARK;
- spk = WATER_URN + game.prop[URN];
- rspeak(spk);
+ game.prop[BOTTLE] = EMPTY_BOTTLE;
+ rspeak(OIL_URN);
+ break;
+ case NO_OBJECT:
+ default:
+ rspeak(FILL_INVALID);
+ return GO_CLEAROBJ;
+ }
+ game.place[k] = LOC_NOWHERE;
return GO_CLEAROBJ;
- } else if (obj != NO_OBJECT && obj != BOTTLE) {
- rspeak(spk);
+ }
+ if (obj != NO_OBJECT && obj != BOTTLE) {
+ rspeak(actions[verb].message);
return GO_CLEAROBJ;
- } else if (obj == NO_OBJECT && !HERE(BOTTLE))
+ }
+ if (obj == NO_OBJECT && !HERE(BOTTLE))
return GO_UNKNOWN;
- spk = BOTTLED_WATER;
- if (LIQLOC(game.loc) == 0)
- spk = NO_LIQUID;
- if (HERE(URN) && game.prop[URN] != URN_EMPTY)
- spk = URN_NOPOUR;
- if (LIQUID() != 0)
- spk = BOTTLE_FULL;
- if (spk == BOTTLED_WATER) {
- /* FIXME: Arithmetic on property values */
- game.prop[BOTTLE] = MOD(conditions[game.loc], 4) / 2 * 2;
- k = LIQUID();
- if (TOTING(BOTTLE))
- game.place[k] = CARRIED;
- if (k == OIL)
- spk = BOTTLED_OIL;
+
+ if (HERE(URN) && game.prop[URN] != URN_EMPTY) {
+ rspeak(URN_NOPOUR);
+ return GO_CLEAROBJ;
}
- rspeak(spk);
+ if (LIQUID() != NO_OBJECT) {
+ rspeak(BOTTLE_FULL);
+ return GO_CLEAROBJ;
+ }
+ if (LIQLOC(game.loc) == NO_OBJECT) {
+ rspeak(NO_LIQUID);
+ return GO_CLEAROBJ;
+ }
+
+ game.prop[BOTTLE] = (LIQLOC(game.loc) == OIL) ? OIL_BOTTLE : WATER_BOTTLE;
+ if (TOTING(BOTTLE))
+ game.place[LIQUID()] = CARRIED;
+ if (LIQUID() == OIL)
+ rspeak(BOTTLED_OIL);
+ else
+ rspeak(BOTTLED_WATER);
return GO_CLEAROBJ;
}
static int find(token_t verb, token_t obj)
/* Find. Might be carrying it, or it might be here. Else give caveat. */
{
- int spk = actions[verb].message;
+ if (TOTING(obj)) {
+ rspeak(ALREADY_CARRYING);
+ return GO_CLEAROBJ;
+ }
+
+ if (game.closed) {
+ rspeak(NEEDED_NEARBY);
+ return GO_CLEAROBJ;
+ }
+
if (AT(obj) ||
(LIQUID() == obj && AT(BOTTLE)) ||
obj == LIQLOC(game.loc) ||
- (obj == DWARF && atdwrf(game.loc) > 0))
- spk = YOU_HAVEIT;
- if (game.closed)
- spk = NEEDED_NEARBY;
- if (TOTING(obj))
- spk = ALREADY_CARRYING;
- rspeak(spk);
+ (obj == DWARF && atdwrf(game.loc) > 0)) {
+ rspeak(YOU_HAVEIT);
+ return GO_CLEAROBJ;
+ }
+
+
+ rspeak(actions[verb].message);
return GO_CLEAROBJ;
}
static int inven(void)
/* Inventory. If object, treat same as find. Else report on current burden. */
{
- int spk = NO_CARRY;
+ bool empty = true;
for (int i = 1; i <= NOBJECTS; i++) {
if (i == BEAR ||
!TOTING(i))
continue;
- if (spk == NO_CARRY)
+ if (empty) {
rspeak(NOW_HOLDING);
+ empty = false;
+ }
pspeak(i, touch, -1, false);
- spk = NO_MESSAGE;
}
if (TOTING(BEAR))
- spk = TAME_BEAR;
- rspeak(spk);
+ rspeak(TAME_BEAR);
+ if (empty)
+ rspeak(NO_CARRY);
return GO_CLEAROBJ;
}
switch (obj) {
case CLAM:
+ if (verb == LOCK)
+ rspeak(HUH_MAN);
+ else if (!TOTING(TRIDENT))
+ rspeak(OYSTER_OPENER);
+ else {
+ DESTROY(CLAM);
+ drop(OYSTER, game.loc);
+ drop(PEARL, LOC_CULDESAC);
+ rspeak(PEARL_FALLS);
+ }
+ return GO_CLEAROBJ;
case OYSTER:
- return bivalve(verb, obj);
+ if (verb == LOCK)
+ rspeak(HUH_MAN);
+ else
+ rspeak(OYSTER_OPENER);
+
+ return GO_CLEAROBJ;
case DOOR:
rspeak((game.prop[DOOR] == DOOR_UNRUSTED) ? OK_MAN : RUSTY_DOOR);
break;
rspeak(NOTHING_HAPPENS);
return GO_CLEAROBJ;
} else {
- /* FIXME: Arithmetic on state numbers */
- pspeak(RESER, look, game.prop[RESER] + 1, true);
- game.prop[RESER] = 1 - game.prop[RESER];
+ state_change(RESER,
+ game.prop[RESER] == WATERS_PARTED ? WATERS_UNPARTED : WATERS_PARTED);
if (AT(RESER))
return GO_CLEAROBJ;
else {
CAGE_FLY :
FREE_FLY);
- /* FIXME: Arithemetic on property values */
- game.prop[FISSURE] = 1 - game.prop[FISSURE];
- pspeak(FISSURE, look, 2 - game.prop[FISSURE], true);
+ state_change(FISSURE,
+ game.prop[FISSURE] == BRIDGED ? UNBRIDGED : BRIDGED);
return GO_CLEAROBJ;
}
}