X-Git-Url: https://jxself.org/git/?p=open-adventure.git;a=blobdiff_plain;f=actions.c;h=40a1928f62d99299970e9a07fef2775cd59196f1;hp=159a71cb7af3d3a7466bba04a4c70140e3f90b36;hb=49d9ef1bee7b11055b7a46e2c2b45bd888e1ccef;hpb=7be2c233ed3415a759061e003d9aa0c46f1ae265 diff --git a/actions.c b/actions.c index 159a71c..40a1928 100644 --- a/actions.c +++ b/actions.c @@ -4,7 +4,7 @@ #include "advent.h" #include "dungeon.h" -static int fill(token_t, token_t); +static int fill(verb_t, obj_t); static int attack(struct command_t *command) /* Attack. Assume target if unambiguous. "Throw" also links here. @@ -12,11 +12,10 @@ static int attack(struct command_t *command) * dwarf, etc.) and others (bird, clam, machine). Ambiguous if 2 * enemies, or no enemies but 2 others. */ { - vocab_t verb = command->verb; + verb_t verb = command->verb; obj_t obj = command->obj; - if (obj == NO_OBJECT || - obj == INTRANSITIVE) { + if (obj == INTRANSITIVE) { int changes = 0; if (atdwrf(game.loc) > 0) { obj = DWARF; @@ -43,7 +42,7 @@ static int attack(struct command_t *command) ++changes; } /* check for low-priority targets */ - if (obj == NO_OBJECT) { + if (obj == INTRANSITIVE) { /* Can't attack bird or machine by throwing axe. */ if (HERE(BIRD) && verb != THROW) { obj = BIRD; @@ -113,19 +112,19 @@ static int attack(struct command_t *command) state_change(DRAGON, DRAGON_DEAD); game.prop[RUG] = RUG_FLOOR; /* Hardcoding LOC_SECRET5 as the dragon's death location is ugly. - * The way it was computed before was wirse; it depended on the + * The way it was computed before was worse; it depended on the * two dragon locations being LOC_SECRET4 and LOC_SECRET6 and * LOC_SECRET5 being right between them. */ - move(DRAGON + NOBJECTS, -1); - move(RUG + NOBJECTS, LOC_NOWHERE); + move(DRAGON + NOBJECTS, IS_FIXED); + move(RUG + NOBJECTS, IS_FREE); move(DRAGON, LOC_SECRET5); move(RUG, LOC_SECRET5); drop(BLOOD, LOC_SECRET5); - for (obj = 1; obj <= NOBJECTS; obj++) { - if (game.place[obj] == objects[DRAGON].plac || - game.place[obj] == objects[DRAGON].fixd) - move(obj, LOC_SECRET5); + for (obj_t i = 1; i <= NOBJECTS; i++) { + if (game.place[i] == objects[DRAGON].plac || + game.place[i] == objects[DRAGON].fixd) + move(i, LOC_SECRET5); } game.loc = LOC_SECRET5; return GO_MOVE; @@ -153,7 +152,7 @@ static int attack(struct command_t *command) } switch (obj) { - case NO_OBJECT: + case INTRANSITIVE: rspeak(NO_TARGET); break; case CLAM: @@ -186,13 +185,13 @@ static int bigwords(long id) * Look up foo in special section of vocab to determine which word we've got. * Last word zips the eggs back to the giant room (unless already there). */ { - if ((game.foobar == WORD_EMPTY && id == ACTION_WORD(FEE)) || - (game.foobar == ACTION_WORD(FEE) && id == ACTION_WORD(FIE)) || - (game.foobar == ACTION_WORD(FIE) && id == ACTION_WORD(FOE)) || - (game.foobar == ACTION_WORD(FOE) && id == ACTION_WORD(FOO)) || - (game.foobar == ACTION_WORD(FOE) && id == ACTION_WORD(FUM))) { + if ((game.foobar == WORD_EMPTY && id == FEE) || + (game.foobar == FEE && id == FIE) || + (game.foobar == FIE && id == FOE) || + (game.foobar == FOE && id == FOO) || + (game.foobar == FOE && id == FUM)) { game.foobar = id; - if ((id != ACTION_WORD(FOO)) && (id != ACTION_WORD(FUM))) { + if ((id != FOO) && (id != FUM)) { rspeak(OK_MAN); return GO_CLEAROBJ; } @@ -206,11 +205,13 @@ static int bigwords(long id) * crossing. */ if (game.place[EGGS] == LOC_NOWHERE && game.place[TROLL] == LOC_NOWHERE && game.prop[TROLL] == TROLL_UNPAID) game.prop[TROLL] = TROLL_PAIDONCE; - int k = EGGS_DONE; + int k; if (HERE(EGGS)) k = EGGS_VANISHED; - if (game.loc == objects[EGGS].plac) + else if (game.loc == objects[EGGS].plac) k = EGGS_HERE; + else + k = EGGS_DONE; move(EGGS, objects[EGGS].plac); pspeak(EGGS, look, k, true); return GO_CLEAROBJ; @@ -231,40 +232,44 @@ static int bigwords(long id) static void blast(void) /* Blast. No effect unless you've got dynamite, which is a neat trick! */ { - if (game.prop[ROD2] < 0 || + if (game.prop[ROD2] == STATE_NOTFOUND || !game.closed) rspeak(REQUIRES_DYNAMITE); else { - game.bonus = VICTORY_MESSAGE; - if (game.loc == LOC_NE) - game.bonus = DEFEAT_MESSAGE; if (HERE(ROD2)) game.bonus = SPLATTER_MESSAGE; + else if (game.loc == LOC_NE) + game.bonus = DEFEAT_MESSAGE; + else + game.bonus = VICTORY_MESSAGE; rspeak(game.bonus); terminate(endgame); } } -static int vbreak(vocab_t verb, obj_t obj) +static int vbreak(verb_t verb, obj_t obj) /* Break. Only works for mirror in repository and, of course, the vase. */ { - if (obj == MIRROR) { + switch (obj) { + case MIRROR: if (game.closed) { rspeak(BREAK_MIRROR); return GO_DWARFWAKE; } else { rspeak(TOO_FAR); - return GO_CLEAROBJ; + break; } + case VASE: + if (game.prop[VASE] == VASE_WHOLE) { + if (TOTING(VASE)) + drop(VASE, game.loc); + state_change(VASE, VASE_BROKEN); + game.fixed[VASE] = IS_FIXED; + break; + } + default: + speak(actions[verb].message); } - if (obj == VASE && game.prop[VASE] == VASE_WHOLE) { - if (TOTING(VASE)) - drop(VASE, game.loc); - state_change(VASE, VASE_BROKEN); - game.fixed[VASE] = IS_FIXED; - return GO_CLEAROBJ; - } - speak(actions[verb].message); return (GO_CLEAROBJ); } @@ -277,14 +282,14 @@ static int brief(void) return GO_CLEAROBJ; } -static int vcarry(token_t verb, obj_t obj) +static int vcarry(verb_t verb, obj_t obj) /* Carry an object. Special cases for bird and cage (if bird in cage, can't * take one without the other). Liquids also special, since they depend on * status of bottle. Also various side effects, etc. */ { if (obj == INTRANSITIVE) { /* Carry, no object given yet. OK if only one object present. */ - if (game.atloc[game.loc] == 0 || + if (game.atloc[game.loc] == NO_OBJECT || game.link[game.atloc[game.loc]] != 0 || atdwrf(game.loc) > 0) return GO_UNKNOWN; @@ -292,7 +297,7 @@ static int vcarry(token_t verb, obj_t obj) } if (TOTING(obj)) { - rspeak(ALREADY_CARRYING); + speak(actions[verb].message); return GO_CLEAROBJ; } @@ -395,7 +400,7 @@ static int vcarry(token_t verb, obj_t obj) return GO_CLEAROBJ; } -static int chain(token_t verb) +static int chain(verb_t verb) /* Do something to the bear's chain */ { if (verb != LOCK) { @@ -414,8 +419,13 @@ static int chain(token_t verb) switch (game.prop[BEAR]) { case BEAR_DEAD: + // LCOV_EXCL_START + /* Can't be reached as long as the only way for the bear to die + * is from a bridge collapse. Leave in in case this changes, but + * exclude from coverage testing. */ game.fixed[BEAR] = IS_FIXED; break; + // LCOV_EXCL_STOP default: game.fixed[BEAR] = IS_FREE; } @@ -442,72 +452,70 @@ static int chain(token_t verb) return GO_CLEAROBJ; } -static int discard(token_t verb, obj_t obj, bool just_do_it) +static int discard(verb_t verb, obj_t obj) /* Discard object. "Throw" also comes here for most objects. Special cases for * bird (might attack snake or dragon) and cage (might contain bird) and vase. * Drop coins at vending machine for extra batteries. */ { - if (!just_do_it) { - if (TOTING(ROD2) && obj == ROD && !TOTING(ROD)) - obj = ROD2; - if (!TOTING(obj)) { - speak(actions[verb].message); - return GO_CLEAROBJ; - } - if (obj == BIRD && HERE(SNAKE)) { - rspeak(BIRD_ATTACKS); - if (game.closed) - return GO_DWARFWAKE; - DESTROY(SNAKE); - /* Set game.prop for use by travel options */ - game.prop[SNAKE] = SNAKE_CHASED; - - } else if ((GSTONE(obj) && AT(CAVITY) && game.prop[CAVITY] != CAVITY_FULL)) { - rspeak(GEM_FITS); - 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))) { - int spk = RUG_RISES; - if (TOTING(RUG)) - spk = RUG_WIGGLES; - if (obj == RUBY) - spk = RUG_SETTLES; - rspeak(spk); - if (spk != RUG_WIGGLES) { - int k = (game.prop[RUG] == RUG_HOVER) ? RUG_FLOOR : RUG_HOVER; - game.prop[RUG] = k; - if (k == RUG_HOVER) - k = objects[SAPPH].plac; - move(RUG + NOBJECTS, k); - } + if (TOTING(ROD2) && obj == ROD && !TOTING(ROD)) + obj = ROD2; + if (!TOTING(obj)) { + speak(actions[verb].message); + return GO_CLEAROBJ; + } + if (obj == BIRD && HERE(SNAKE)) { + rspeak(BIRD_ATTACKS); + if (game.closed) + return GO_DWARFWAKE; + DESTROY(SNAKE); + /* Set game.prop for use by travel options */ + game.prop[SNAKE] = SNAKE_CHASED; + + } else if ((GSTONE(obj) && AT(CAVITY) && game.prop[CAVITY] != CAVITY_FULL)) { + rspeak(GEM_FITS); + 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))) { + if (obj == RUBY) + rspeak(RUG_SETTLES); + else if (TOTING(RUG)) + rspeak(RUG_WIGGLES); + else + rspeak(RUG_RISES); + if (!TOTING(RUG) || obj == RUBY) { + int k = (game.prop[RUG] == RUG_HOVER) ? RUG_FLOOR : RUG_HOVER; + game.prop[RUG] = k; + if (k == RUG_HOVER) + k = objects[SAPPH].plac; + move(RUG + NOBJECTS, k); } - } else if (obj == COINS && HERE(VEND)) { - DESTROY(COINS); - drop(BATTERY, game.loc); - pspeak(BATTERY, look, FRESH_BATTERIES, true); - return GO_CLEAROBJ; - } else if (obj == BIRD && AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) { - rspeak(BIRD_BURNT); - DESTROY(BIRD); - return GO_CLEAROBJ; - } else if (obj == BEAR && AT(TROLL)) { - state_change(TROLL, TROLL_GONE); - move(TROLL, LOC_NOWHERE); - move(TROLL + NOBJECTS, LOC_NOWHERE); - move(TROLL2, objects[TROLL].plac); - move(TROLL2 + NOBJECTS, objects[TROLL].fixd); - juggle(CHASM); - } else if (obj != VASE || - game.loc == objects[PILLOW].plac) { - rspeak(OK_MAN); - } else { - state_change(VASE, AT(PILLOW) - ? VASE_WHOLE - : VASE_DROPPED); - if (game.prop[VASE] != VASE_WHOLE) - game.fixed[VASE] = IS_FIXED; } + } else if (obj == COINS && HERE(VEND)) { + DESTROY(COINS); + drop(BATTERY, game.loc); + pspeak(BATTERY, look, FRESH_BATTERIES, true); + return GO_CLEAROBJ; + } else if (obj == BIRD && AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) { + rspeak(BIRD_BURNT); + DESTROY(BIRD); + return GO_CLEAROBJ; + } else if (obj == BEAR && AT(TROLL)) { + state_change(TROLL, TROLL_GONE); + move(TROLL, LOC_NOWHERE); + move(TROLL + NOBJECTS, IS_FREE); + move(TROLL2, objects[TROLL].plac); + move(TROLL2 + NOBJECTS, objects[TROLL].fixd); + juggle(CHASM); + } else if (obj != VASE || + game.loc == objects[PILLOW].plac) { + rspeak(OK_MAN); + } else { + state_change(VASE, AT(PILLOW) + ? VASE_WHOLE + : VASE_DROPPED); + if (game.prop[VASE] != VASE_WHOLE) + game.fixed[VASE] = IS_FIXED; } int k = LIQUID(); if (k == obj) @@ -525,11 +533,11 @@ static int discard(token_t verb, obj_t obj, bool just_do_it) return GO_CLEAROBJ; } -static int drink(token_t verb, obj_t obj) +static int drink(verb_t verb, obj_t obj) /* 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 && + if (obj == INTRANSITIVE && LIQLOC(game.loc) != WATER && (LIQUID() != WATER || !HERE(BOTTLE))) { return GO_UNKNOWN; } @@ -541,7 +549,7 @@ static int drink(token_t verb, obj_t obj) return GO_CLEAROBJ; } - if (obj != NO_OBJECT && obj != WATER) { + if (obj != INTRANSITIVE && obj != WATER) { rspeak(RIDICULOUS_ATTEMPT); return GO_CLEAROBJ; } @@ -555,39 +563,36 @@ static int drink(token_t verb, obj_t obj) return GO_CLEAROBJ; } -static int eat(token_t verb, obj_t obj) +static int eat(verb_t verb, obj_t obj) /* Eat. Intransitive: assume food if present, else ask what. Transitive: food * ok, some things lose appetite, rest are ridiculous. */ { - if (obj == INTRANSITIVE) { + switch (obj) { + case INTRANSITIVE: if (!HERE(FOOD)) return GO_UNKNOWN; + case FOOD: DESTROY(FOOD); rspeak(THANKS_DELICIOUS); - return GO_CLEAROBJ; - } - if (obj == FOOD) { - DESTROY(FOOD); - rspeak(THANKS_DELICIOUS); - return GO_CLEAROBJ; - } - if (obj == BIRD || - obj == SNAKE || - obj == CLAM || - obj == OYSTER || - obj == DWARF || - obj == DRAGON || - obj == TROLL || - obj == BEAR || - obj == OGRE) { + break; + case BIRD: + case SNAKE: + case CLAM: + case OYSTER: + case DWARF: + case DRAGON: + case TROLL: + case BEAR: + case OGRE: rspeak(LOST_APPETITE); - return GO_CLEAROBJ; + break; + default: + speak(actions[verb].message); } - speak(actions[verb].message); return GO_CLEAROBJ; } -static int extinguish(token_t verb, obj_t obj) +static int extinguish(verb_t verb, obj_t obj) /* Extinguish. Lamp, urn, dragon/volcano (nice try). */ { if (obj == INTRANSITIVE) { @@ -599,34 +604,31 @@ static int extinguish(token_t verb, obj_t obj) return GO_UNKNOWN; } - if (obj == URN) { + switch (obj) { + case URN: if (game.prop[URN] != URN_EMPTY) { state_change(URN, URN_DARK); } else { pspeak(URN, change, URN_DARK, true); } - return GO_CLEAROBJ; - } - - if (obj == LAMP) { + break; + case LAMP: state_change(LAMP, LAMP_DARK); rspeak(DARK(game.loc) ? PITCH_DARK : NO_MESSAGE); - return GO_CLEAROBJ; - } - - if (obj == DRAGON || - obj == VOLCANO) { + break; + case DRAGON: + case VOLCANO: rspeak(BEYOND_POWER); - return GO_CLEAROBJ; + break; + default: + speak(actions[verb].message); } - - speak(actions[verb].message); return GO_CLEAROBJ; } -static int feed(token_t verb, obj_t obj) +static int feed(verb_t verb, obj_t obj) /* Feed. If bird, no seed. Snake, dragon, troll: quip. If dwarf, make him * mad. Bear, special. */ { @@ -686,7 +688,7 @@ static int feed(token_t verb, obj_t obj) return GO_CLEAROBJ; } -int fill(token_t verb, obj_t obj) +int fill(verb_t verb, obj_t obj) /* Fill. Bottle or urn must be empty, and liquid available. (Vase * is nasty.) */ { @@ -702,7 +704,8 @@ int fill(token_t verb, obj_t obj) rspeak(SHATTER_VASE); game.prop[VASE] = VASE_BROKEN; game.fixed[VASE] = IS_FIXED; - return (discard(verb, VASE, true)); + drop(VASE, game.loc); + return GO_CLEAROBJ; } if (obj == URN) { @@ -733,11 +736,11 @@ int fill(token_t verb, obj_t obj) game.place[k] = LOC_NOWHERE; return GO_CLEAROBJ; } - if (obj != NO_OBJECT && obj != BOTTLE) { + if (obj != INTRANSITIVE && obj != BOTTLE) { speak(actions[verb].message); return GO_CLEAROBJ; } - if (obj == NO_OBJECT && !HERE(BOTTLE)) + if (obj == INTRANSITIVE && !HERE(BOTTLE)) return GO_UNKNOWN; if (HERE(URN) && game.prop[URN] != URN_EMPTY) { @@ -761,7 +764,7 @@ int fill(token_t verb, obj_t obj) return GO_CLEAROBJ; } -static int find(token_t verb, obj_t obj) +static int find(verb_t verb, obj_t obj) /* Find. Might be carrying it, or it might be here. Else give caveat. */ { if (TOTING(obj)) { @@ -787,7 +790,7 @@ static int find(token_t verb, obj_t obj) return GO_CLEAROBJ; } -static int fly(token_t verb, obj_t obj) +static int fly(verb_t verb, obj_t obj) /* Fly. Snide remarks unless hovering rug is here. */ { if (obj == INTRANSITIVE) { @@ -844,40 +847,42 @@ static int inven(void) return GO_CLEAROBJ; } -static int light(token_t verb, obj_t obj) +static int light(verb_t verb, obj_t obj) /* Light. Applicable only to lamp and urn. */ { if (obj == INTRANSITIVE) { - if (HERE(LAMP) && game.prop[LAMP] == LAMP_DARK && game.limit >= 0) + int selects = 0; + if (HERE(LAMP) && game.prop[LAMP] == LAMP_DARK && game.limit >= 0) { obj = LAMP; - if (HERE(URN) && game.prop[URN] == URN_DARK) + selects++; + } + if (HERE(URN) && game.prop[URN] == URN_DARK) { obj = URN; - if (obj == INTRANSITIVE || - (HERE(LAMP) && game.prop[LAMP] == LAMP_DARK && game.limit >= 0 && - HERE(URN) && game.prop[URN] == URN_DARK)) + selects++; + } + if (selects != 1) return GO_UNKNOWN; } - if (obj == URN) { + switch (obj) { + case URN: state_change(URN, game.prop[URN] == URN_EMPTY ? URN_EMPTY : URN_LIT); - return GO_CLEAROBJ; - } else { - if (obj != LAMP) { - speak(actions[verb].message); - return GO_CLEAROBJ; - } + break; + case LAMP: if (game.limit < 0) { rspeak(LAMP_OUT); - return GO_CLEAROBJ; + break; } state_change(LAMP, LAMP_BRIGHT); if (game.wzdark) return GO_TOP; - else - return GO_CLEAROBJ; + break; + default: + speak(actions[verb].message); } + return GO_CLEAROBJ; } static int listen(void) @@ -896,7 +901,11 @@ static int listen(void) game.prop[i] < 0) continue; int mi = game.prop[i]; - /* FIXME: Weird magic on object states */ + /* (ESR) Some unpleasant magic on object states here. Ideally + * we'd have liked the bird to be a normal object that we can + * use state_change() on; can't do it, because there are + * actually two different series of per-state birdsounds + * depending on whether player has drunk dragon's blood. */ if (i == BIRD) mi += 3 * game.blooded; long packed_zzword = token_to_packed(game.zzword); @@ -910,7 +919,7 @@ static int listen(void) return GO_CLEAROBJ; } -static int lock(token_t verb, obj_t obj) +static int lock(verb_t verb, obj_t obj) /* Lock, unlock, no object given. Assume various things if present. */ { if (obj == INTRANSITIVE) { @@ -989,12 +998,12 @@ static int lock(token_t verb, obj_t obj) return GO_CLEAROBJ; } -static int pour(token_t verb, obj_t obj) +static int pour(verb_t verb, obj_t obj) /* Pour. If no object, or object is bottle, assume contents of bottle. * special tests for pouring water or oil on plant or rusty door. */ { if (obj == BOTTLE || - obj == NO_OBJECT) + obj == INTRANSITIVE) obj = LIQUID(); if (obj == NO_OBJECT) return GO_UNKNOWN; @@ -1089,7 +1098,7 @@ static int reservoir(void) } } -static int rub(token_t verb, obj_t obj) +static int rub(verb_t verb, obj_t obj) /* Rub. Yields various snide remarks except for lit urn. */ { if (obj == URN && game.prop[URN] == URN_LIT) { @@ -1112,20 +1121,22 @@ static int say(struct command_t *command) { if (command->wd2 > 0) { command->wd1 = command->wd2; - strcpy(command->raw1, command->raw2); + strncpy(command->raw1, command->raw2, LINESIZE - 1); } char word1[TOKLEN + 1]; packed_to_token(command->wd1, word1); - int wd = (int) get_vocab_id(word1); - if (wd == MOTION_WORD(XYZZY) || - wd == MOTION_WORD(PLUGH) || - wd == MOTION_WORD(PLOVER) || - wd == ACTION_WORD(FEE) || - wd == ACTION_WORD(FIE) || - wd == ACTION_WORD(FOE) || - wd == ACTION_WORD(FOO) || - wd == ACTION_WORD(FUM) || - wd == ACTION_WORD(PART)) { + long wd; + enum wordtype type; + get_vocab_metadata(word1, &wd, &type); + if (wd == XYZZY || + wd == PLUGH || + wd == PLOVER || + wd == FEE || + wd == FIE || + wd == FOE || + wd == FOO || + wd == FUM || + wd == PART) { /* FIXME: scribbles on the interpreter's command block */ wordclear(&command->wd2); return GO_LOOKUP; @@ -1155,7 +1166,7 @@ static int throw (struct command_t *command) /* Snarf a treasure for the troll. */ drop(command->obj, LOC_NOWHERE); move(TROLL, LOC_NOWHERE); - move(TROLL + NOBJECTS, LOC_NOWHERE); + move(TROLL + NOBJECTS, IS_FREE); drop(TROLL2, objects[TROLL].plac); drop(TROLL2 + NOBJECTS, objects[TROLL].fixd); juggle(CHASM); @@ -1168,16 +1179,16 @@ static int throw (struct command_t *command) return (feed(command->verb, command->obj)); } if (command->obj != AXE) - return (discard(command->verb, command->obj, false)); + return (discard(command->verb, command->obj)); else { if (atdwrf(game.loc) <= 0) { if (AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) return throw_support(DRAGON_SCALES); if (AT(TROLL)) return throw_support(TROLL_RETURNS); - else if (AT(OGRE)) + if (AT(OGRE)) return throw_support(OGRE_DODGE); - else if (HERE(BEAR) && game.prop[BEAR] == UNTAMED_BEAR) { + if (HERE(BEAR) && game.prop[BEAR] == UNTAMED_BEAR) { /* This'll teach him to throw the axe at the bear! */ drop(AXE, game.loc); game.fixed[AXE] = IS_FIXED; @@ -1185,7 +1196,7 @@ static int throw (struct command_t *command) state_change(AXE, AXE_LOST); return GO_CLEAROBJ; } - command->obj = NO_OBJECT; + command->obj = INTRANSITIVE; return (attack(command)); } @@ -1202,7 +1213,7 @@ static int throw (struct command_t *command) } } -static int wake(token_t verb, obj_t obj) +static int wake(verb_t verb, obj_t obj) /* Wake. Only use is to disturb the dwarves. */ { if (obj != DWARF || @@ -1215,7 +1226,7 @@ static int wake(token_t verb, obj_t obj) } } -static int wave(token_t verb, obj_t obj) +static int wave(verb_t verb, obj_t obj) /* Wave. No effect unless waving rod at fissure or at bird. */ { if (obj != ROD || @@ -1294,10 +1305,10 @@ int action(struct command_t *command) else if ((LIQUID() == command->obj && HERE(BOTTLE)) || command->obj == LIQLOC(game.loc)) /* FALL THROUGH */; - else if (command->obj == OIL && HERE(URN) && game.prop[URN] != 0) { + else if (command->obj == OIL && HERE(URN) && game.prop[URN] != URN_EMPTY) { command->obj = URN; /* FALL THROUGH */; - } else if (command->obj == PLANT && AT(PLANT2) && game.prop[PLANT2] != 0) { + } else if (command->obj == PLANT && AT(PLANT2) && game.prop[PLANT2] != PLANT_THIRSTY) { command->obj = PLANT2; /* FALL THROUGH */; } else if (command->obj == KNIFE && game.knfloc == game.loc) { @@ -1358,13 +1369,14 @@ int action(struct command_t *command) return GO_CLEAROBJ; } case ATTACK: + command->obj = INTRANSITIVE; return attack(command); case POUR: - return pour(command->verb, command->obj); + return pour(command->verb, INTRANSITIVE); case EAT: return eat(command->verb, INTRANSITIVE); case DRINK: - return drink(command->verb, command->obj); + return drink(command->verb, INTRANSITIVE); case RUB: return GO_UNKNOWN; case THROW: @@ -1378,7 +1390,7 @@ int action(struct command_t *command) case FEED: return GO_UNKNOWN; case FILL: - return fill(command->verb, command->obj); + return fill(command->verb, INTRANSITIVE); case BLAST: blast(); return GO_CLEAROBJ; @@ -1421,7 +1433,7 @@ int action(struct command_t *command) case CARRY: return vcarry(command->verb, command->obj); case DROP: - return discard(command->verb, command->obj, false); + return discard(command->verb, command->obj); case SAY: return say(command); case UNLOCK: