X-Git-Url: https://jxself.org/git/?p=open-adventure.git;a=blobdiff_plain;f=actions.c;h=5cf1fae0a77bbe7cd0f44081d08622217c5d8983;hp=ec7fb1c0a481d44d335da93ebe61e97e74cb7b41;hb=cca3686f2f5ab3f5a5bf17d2e56560aad2c55c0f;hpb=acf303a57f389a42298f49ec3c6eb7bbc540e802 diff --git a/actions.c b/actions.c index ec7fb1c..5cf1fae 100644 --- a/actions.c +++ b/actions.c @@ -15,8 +15,7 @@ static int attack(struct command_t *command) vocab_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,12 +112,12 @@ 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); @@ -153,7 +152,7 @@ static int attack(struct command_t *command) } switch (obj) { - case NO_OBJECT: + case INTRANSITIVE: rspeak(NO_TARGET); break; case CLAM: @@ -231,15 +230,16 @@ 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); } @@ -248,23 +248,26 @@ static void blast(void) static int vbreak(vocab_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); } @@ -493,7 +496,7 @@ static int discard(token_t verb, obj_t obj) } else if (obj == BEAR && AT(TROLL)) { state_change(TROLL, TROLL_GONE); move(TROLL, LOC_NOWHERE); - move(TROLL + NOBJECTS, LOC_NOWHERE); + move(TROLL + NOBJECTS, IS_FREE); move(TROLL2, objects[TROLL].plac); move(TROLL2 + NOBJECTS, objects[TROLL].fixd); juggle(CHASM); @@ -527,7 +530,7 @@ static int drink(token_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; } @@ -539,7 +542,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; } @@ -557,31 +560,28 @@ static int eat(token_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; } @@ -597,30 +597,27 @@ 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; } @@ -732,11 +729,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) { @@ -847,36 +844,38 @@ static int light(token_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) @@ -993,7 +992,7 @@ static int pour(token_t verb, obj_t obj) * 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; @@ -1154,7 +1153,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); @@ -1174,9 +1173,9 @@ static int throw (struct command_t *command) 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; @@ -1184,7 +1183,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)); } @@ -1293,10 +1292,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) { @@ -1357,13 +1356,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: @@ -1377,7 +1377,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;