X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=actions.c;h=2b432f371470eb0645532951774149d7ce2d3925;hb=0e540429b017c950702aee6644f17058f6f338fb;hp=34d0e48ef8d291bbfd364bf0bedfb73908cebe3a;hpb=abf820bb5c8bcf51207ef941dbe00b7c425bf023;p=open-adventure.git diff --git a/actions.c b/actions.c index 34d0e48..2b432f3 100644 --- a/actions.c +++ b/actions.c @@ -6,13 +6,6 @@ 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); -} - static int attack(struct command_t *command) /* Attack. Assume target if unambiguous. "Throw" also links here. * Attackable objects fall into two categories: enemies (snake, @@ -185,46 +178,51 @@ static int attack(struct command_t *command) return GO_CLEAROBJ; } -static int bigwords(token_t foo) +static int bigwords(long id) /* FEE FIE FOE FOO (AND FUM). Advance to next state if given in proper order. * 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). */ { - char word[TOKLEN + 1]; - packed_to_token(foo, word); - int k = (int) get_special_vocab_id(word); - if (game.foobar != 1 - k) { - if (game.foobar != 0 && game.loc == LOC_GIANTROOM) { - rspeak( START_OVER); - } else { - rspeak(NOTHING_HAPPENS); - } - return GO_CLEAROBJ; - } else { - game.foobar = k; - if (k != 4) { - rspeak(OK_MAN); - return GO_CLEAROBJ; - } - game.foobar = 0; - if (game.place[EGGS] == objects[EGGS].plac || - (TOTING(EGGS) && game.loc == objects[EGGS].plac)) { - rspeak(NOTHING_HAPPENS); - return GO_CLEAROBJ; - } else { - /* Bring back troll if we steal the eggs back from him before - * crossing. */ - if (game.place[EGGS] == LOC_NOWHERE && game.place[TROLL] == LOC_NOWHERE && game.prop[TROLL] == TROLL_UNPAID) - game.prop[TROLL] = TROLL_PAIDONCE; - k = EGGS_DONE; - if (HERE(EGGS)) - k = EGGS_VANISHED; - if (game.loc == objects[EGGS].plac) - k = EGGS_HERE; - move(EGGS, objects[EGGS].plac); - pspeak(EGGS, look, k, true); - return GO_CLEAROBJ; - } + 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))) + { + game.foobar = id; + if ((id != ACTION_WORD(FOO)) && (id != ACTION_WORD(FUM))) { + rspeak(OK_MAN); + return GO_CLEAROBJ; + } + game.foobar = WORD_EMPTY; + if (game.place[EGGS] == objects[EGGS].plac || + (TOTING(EGGS) && game.loc == objects[EGGS].plac)) { + rspeak(NOTHING_HAPPENS); + return GO_CLEAROBJ; + } else { + /* Bring back troll if we steal the eggs back from him before + * 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; + if (HERE(EGGS)) + k = EGGS_VANISHED; + if (game.loc == objects[EGGS].plac) + k = EGGS_HERE; + move(EGGS, objects[EGGS].plac); + pspeak(EGGS, look, k, true); + return GO_CLEAROBJ; + } + } + else + { + if (game.loc == LOC_GIANTROOM) { + rspeak( START_OVER); + } else { + rspeak(NOTHING_HAPPENS); + } + game.foobar = WORD_EMPTY; + return GO_CLEAROBJ; } } @@ -261,7 +259,7 @@ static int vbreak(token_t verb, token_t obj) if (TOTING(VASE)) drop(VASE, game.loc); state_change(VASE, VASE_BROKEN); - game.fixed[VASE] = -1; + game.fixed[VASE] = IS_FIXED; return GO_CLEAROBJ; } rspeak(actions[verb].message); @@ -302,8 +300,9 @@ static int vcarry(token_t verb, token_t obj) return GO_CLEAROBJ; } - if (game.fixed[obj] != 0) { - if (obj == PLANT && game.prop[PLANT] <= 0) { + if (game.fixed[obj] != IS_FREE) { + /* Next guard tests whether plant is tiny or stashed */ + if (obj == PLANT && game.prop[PLANT] <= PLANT_THIRSTY) { rspeak(DEEP_ROOTS); return GO_CLEAROBJ; } @@ -381,7 +380,7 @@ static int vcarry(token_t verb, token_t obj) if ((obj == BIRD || obj == CAGE) && (game.prop[BIRD] == BIRD_CAGED || STASHED(BIRD) == BIRD_CAGED)) - /* expression maps BIRD to CAGE and CAGE to BIRD */ + /* 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) @@ -407,16 +406,16 @@ static int chain(token_t verb) return GO_CLEAROBJ; } game.prop[CHAIN] = CHAIN_HEAP; - game.fixed[CHAIN] = CHAIN_HEAP; + game.fixed[CHAIN] = IS_FREE; if (game.prop[BEAR] != BEAR_DEAD) game.prop[BEAR] = CONTENTED_BEAR; switch (game.prop[BEAR]) { case BEAR_DEAD: - game.fixed[BEAR] = -1; + game.fixed[BEAR] = IS_FIXED; break; default: - game.fixed[BEAR] = 0; + game.fixed[BEAR] = IS_FREE; } rspeak(CHAIN_UNLOCKED); return GO_CLEAROBJ; @@ -435,7 +434,7 @@ static int chain(token_t verb) if (TOTING(CHAIN)) drop(CHAIN, game.loc); - game.fixed[CHAIN] = -1; + game.fixed[CHAIN] = IS_FIXED; rspeak(CHAIN_LOCKED); return GO_CLEAROBJ; @@ -475,9 +474,9 @@ static int discard(token_t verb, token_t obj, bool just_do_it) rspeak(spk); if (spk != RUG_WIGGLES) { /* FIXME: Arithmetic on state numbers */ - int k = 2 - game.prop[RUG]; + int k = (game.prop[RUG] == RUG_HOVER) ? RUG_FLOOR : RUG_HOVER; game.prop[RUG] = k; - if (k == 2) + if (k == RUG_HOVER) k = objects[SAPPH].plac; move(RUG + NOBJECTS, k); } @@ -502,12 +501,11 @@ static int discard(token_t verb, token_t obj, bool just_do_it) game.loc == objects[PILLOW].plac) { rspeak(OK_MAN); } else { - game.prop[VASE] = VASE_BROKEN; - if (AT(PILLOW)) - game.prop[VASE] = VASE_WHOLE; - pspeak(VASE, look, game.prop[VASE] + 1, true); + state_change(VASE, AT(PILLOW) + ? VASE_WHOLE + : VASE_DROPPED); if (game.prop[VASE] != VASE_WHOLE) - game.fixed[VASE] = -1; + game.fixed[VASE] = IS_FIXED; } } int k = LIQUID(); @@ -547,9 +545,8 @@ static int drink(token_t verb, token_t obj) return GO_CLEAROBJ; } if (LIQUID() == WATER && HERE(BOTTLE)) { - game.prop[BOTTLE] = EMPTY_BOTTLE; game.place[WATER] = LOC_NOWHERE; - rspeak(BOTTLE_EMPTY); + state_change(BOTTLE, EMPTY_BOTTLE); return GO_CLEAROBJ; } @@ -632,46 +629,59 @@ static int feed(token_t verb, token_t obj) /* Feed. If bird, no seed. Snake, dragon, troll: quip. If dwarf, make him * mad. Bear, special. */ { - int spk = actions[verb].message; - if (obj == BIRD) { + switch (obj) { + case BIRD: rspeak(BIRD_PINING); - return GO_CLEAROBJ; - } else if (obj == SNAKE || - obj == DRAGON || - obj == TROLL) { - spk = NOTHING_EDIBLE; - if (obj == DRAGON && game.prop[DRAGON] != DRAGON_BARS) - spk = RIDICULOUS_ATTEMPT; - if (obj == TROLL) - spk = TROLL_VICES; - if (obj == SNAKE && !game.closed && HERE(BIRD)) { + break; + case DRAGON: + if (game.prop[DRAGON] != DRAGON_BARS) + rspeak(RIDICULOUS_ATTEMPT); + else + rspeak(NOTHING_EDIBLE); + break; + case SNAKE: + if (!game.closed && HERE(BIRD)) { DESTROY(BIRD); - spk = BIRD_DEVOURED; - } - } else if (obj == DWARF) { + rspeak(BIRD_DEVOURED); + } else + rspeak(NOTHING_EDIBLE); + break; + case TROLL: + rspeak(TROLL_VICES); + break; + case DWARF: if (HERE(FOOD)) { game.dflag += 2; - spk = REALLY_MAD; + rspeak(REALLY_MAD); + } else + rspeak(actions[verb].message); + break; + case BEAR: + if (game.prop[BEAR] == BEAR_DEAD) { + rspeak(RIDICULOUS_ATTEMPT); + break; } - } else if (obj == BEAR) { - if (game.prop[BEAR] == UNTAMED_BEAR) - spk = NOTHING_EDIBLE; - if (game.prop[BEAR] == BEAR_DEAD) - spk = RIDICULOUS_ATTEMPT; - if (HERE(FOOD)) { - DESTROY(FOOD); - game.prop[BEAR] = SITTING_BEAR; - game.fixed[AXE] = 0; - game.prop[AXE] = AXE_HERE; - spk = BEAR_TAMED; + if (game.prop[BEAR] == UNTAMED_BEAR) { + if (HERE(FOOD)) { + DESTROY(FOOD); + game.fixed[AXE] = IS_FREE; + game.prop[AXE] = AXE_HERE; + state_change(BEAR, SITTING_BEAR); + } else + rspeak(NOTHING_EDIBLE); + break; } - } else if (obj == OGRE) { + rspeak(actions[verb].message); + break; + case OGRE: if (HERE(FOOD)) - spk = OGRE_FULL; - } else { - spk = AM_GAME; + rspeak(OGRE_FULL); + else + rspeak(actions[verb].message); + break; + default: + rspeak(AM_GAME); } - rspeak(spk); return GO_CLEAROBJ; } @@ -690,7 +700,7 @@ int fill(token_t verb, token_t obj) } rspeak(SHATTER_VASE); game.prop[VASE] = VASE_BROKEN; - game.fixed[VASE] = -1; + game.fixed[VASE] = IS_FIXED; return (discard(verb, VASE, true)); } @@ -742,13 +752,11 @@ int fill(token_t verb, token_t obj) return GO_CLEAROBJ; } - game.prop[BOTTLE] = (LIQLOC(game.loc) == OIL) ? OIL_BOTTLE : WATER_BOTTLE; + state_change(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; } @@ -806,10 +814,10 @@ static int fly(token_t verb, token_t obj) /* FIXME: Arithmetic on location values */ game.newloc = game.place[RUG] + game.fixed[RUG] - game.loc; - if (game.prop[SAPPH] >= 0) { - rspeak(RUG_RETURNS); - } else { + if (game.prop[SAPPH] == STATE_NOTFOUND) { rspeak(RUG_GOES); + } else { + rspeak(RUG_RETURNS); } return GO_TERMINATE; } @@ -872,7 +880,7 @@ static int light(token_t verb, token_t obj) } static int listen(void) -/* Listen. Intransitive only. Print stuff based on objsnd/locsnd. */ +/* Listen. Intransitive only. Print stuff based on object sound proprties. */ { long sound = locations[game.loc].sound; if (sound != SILENT) { @@ -892,8 +900,7 @@ static int listen(void) long packed_zzword = token_to_packed(game.zzword); pspeak(i, hear, mi, true, packed_zzword); rspeak(NO_MESSAGE); - /* FIXME: Magic number, sensitive to bird state logic */ - if (i == BIRD && game.prop[i] == 5) + if (i == BIRD && mi == BIRD_ENDSTATE) DESTROY(BIRD); return GO_CLEAROBJ; } @@ -1113,7 +1120,11 @@ static int say(struct command_t *command) if (wd == MOTION_WORD(XYZZY) || wd == MOTION_WORD(PLUGH) || wd == MOTION_WORD(PLOVER) || - wd == ACTION_WORD(GIANTWORDS) || + wd == ACTION_WORD(FEE) || + wd == ACTION_WORD(FIE) || + wd == ACTION_WORD(FOE) || + wd == ACTION_WORD(FOO) || + wd == ACTION_WORD(FUM) || wd == ACTION_WORD(PART)) { /* FIXME: scribbles on the interpreter's command block */ wordclear(&command->wd2); @@ -1136,8 +1147,6 @@ static int throw (struct command_t *command) * (Only way to do so!) Axe also special for dragon, bear, and * troll. Treasures special for troll. */ { - if (TOTING(ROD2) && command->obj == ROD && !TOTING(ROD)) - command->obj = ROD2; if (!TOTING(command->obj)) { rspeak(actions[command->verb].message); return GO_CLEAROBJ; @@ -1171,7 +1180,7 @@ static int throw (struct command_t *command) else 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] = -1; + game.fixed[AXE] = IS_FIXED; juggle(BEAR); state_change(AXE, AXE_LOST); return GO_CLEAROBJ; @@ -1376,8 +1385,12 @@ int action(struct command_t *command) case SCORE: score(scoregame); return GO_CLEAROBJ; - case GIANTWORDS: - return bigwords(command->wd1); + case FEE: + case FIE: + case FOE: + case FOO: + case FUM: + return bigwords(command->id1); case BRIEF: return brief(); case READ: @@ -1464,7 +1477,11 @@ int action(struct command_t *command) rspeak(actions[command->verb].message); return GO_CLEAROBJ; } - case GIANTWORDS: { + case FEE: + case FIE: + case FOE: + case FOO: + case FUM: { rspeak(actions[command->verb].message); return GO_CLEAROBJ; }