X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=actions.c;h=dd6d64b6e3bf01cda79554758b47a287fa26f305;hb=8456b866ff02b468944eb54713108d51d7538305;hp=e3768d91af9f4567e3186f188b239e9ca7b6fd92;hpb=45820bc8cd6e01279d94703fd18b73f6848f09aa;p=open-adventure.git diff --git a/actions.c b/actions.c index e3768d9..dd6d64b 100644 --- a/actions.c +++ b/actions.c @@ -19,40 +19,62 @@ static int attack(struct command_t *command) { vocab_t verb = command->verb; vocab_t obj = command->obj; + + if (obj == INTRANSITIVE) { + return GO_UNKNOWN; + } long spk = actions[verb].message; if (obj == 0 || obj == INTRANSITIVE) { - if (atdwrf(game.loc) > 0) + int changes = 0; + if (atdwrf(game.loc) > 0) { obj = DWARF; - if (HERE(SNAKE)) - obj = obj * NOBJECTS + SNAKE; - if (AT(DRAGON) && game.prop[DRAGON] == 0) - obj = obj * NOBJECTS + DRAGON; - if (AT(TROLL)) - obj = obj * NOBJECTS + TROLL; - if (AT(OGRE)) - obj = obj * NOBJECTS + OGRE; - if (HERE(BEAR) && game.prop[BEAR] == UNTAMED_BEAR) - obj = obj * NOBJECTS + BEAR; - if (obj > NOBJECTS) - return GO_UNKNOWN; + ++changes; + } + if (HERE(SNAKE)) { + obj = SNAKE; + ++changes; + } + if (AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) { + obj = DRAGON; + ++changes; + } + if (AT(TROLL)) { + obj = TROLL; + ++changes; + } + if (AT(OGRE)) { + obj = OGRE; + ++changes; + } + if (HERE(BEAR) && game.prop[BEAR] == UNTAMED_BEAR) { + obj = BEAR; + ++changes; + } + /* check for low-priority targets */ if (obj == 0) { /* Can't attack bird or machine by throwing axe. */ - if (HERE(BIRD) && verb != THROW) + if (HERE(BIRD) && verb != THROW) { obj = BIRD; - if (HERE(VEND) && verb != THROW) - obj = obj * NOBJECTS + VEND; + ++changes; + } + if (HERE(VEND) && verb != THROW) { + obj = VEND; + ++changes; + } /* Clam and oyster both treated as clam for intransitive case; * no harm done. */ - if (HERE(CLAM) || HERE(OYSTER)) - obj = NOBJECTS * obj + CLAM; - if (obj > NOBJECTS) - return GO_UNKNOWN; + if (HERE(CLAM) || HERE(OYSTER)) { + obj = CLAM; + ++changes; + } } + if (changes >= 2) + return GO_UNKNOWN; + } if (obj == BIRD) { - spk = UNHAPPY_BIRD; if (game.closed) { - rspeak(spk); + rspeak(UNHAPPY_BIRD); return GO_CLEAROBJ; } DESTROY(BIRD); @@ -107,7 +129,7 @@ static int attack(struct command_t *command) spk = ALREADY_DEAD; break; } - } else if (obj == DRAGON && game.prop[DRAGON] == 0) { + } else if (obj == DRAGON && game.prop[DRAGON] == DRAGON_BARS) { /* Fun stuff for dragon. If he insists on attacking it, win! * Set game.prop to dead, move dragon to central loc (still * fixed), move rug there (not fixed), and move him there, @@ -121,9 +143,9 @@ static int attack(struct command_t *command) command->wd1 = token_to_packed("N"); return GO_CHECKFOO; } - pspeak(DRAGON, look, 3); - game.prop[DRAGON] = 1; - game.prop[RUG] = 0; + state_change(DRAGON, DRAGON_DEAD); + game.prop[RUG] = RUG_FLOOR; + /* FIXME: Arithmetic on location values */ int k = (objects[DRAGON].plac + objects[DRAGON].fixd) / 2; move(DRAGON + NOBJECTS, -1); move(RUG + NOBJECTS, 0); @@ -170,13 +192,13 @@ static int bigwords(token_t foo) } 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] == 0) - game.prop[TROLL] = 1; - k = 2; + 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 = 1; + k = EGGS_VANISHED; if (game.loc == objects[EGGS].plac) - k = 0; + k = EGGS_HERE; move(EGGS, objects[EGGS].plac); pspeak(EGGS, look, k); return GO_CLEAROBJ; @@ -224,23 +246,24 @@ static void blast(void) static int vbreak(token_t verb, token_t obj) /* Break. Only works for mirror in repository and, of course, the vase. */ { - int spk = actions[verb].message; - if (obj == MIRROR) - spk = TOO_FAR; - if (obj == VASE && game.prop[VASE] == 0) { - if (TOTING(VASE)) - drop(VASE, game.loc); - game.prop[VASE] = 2; - game.fixed[VASE] = -1; - spk = BREAK_VASE; - } else { - if (obj == MIRROR && game.closed) { + if (obj == MIRROR) { + if (game.closed) { rspeak(BREAK_MIRROR); return GO_DWARFWAKE; + } else { + rspeak(TOO_FAR); + return GO_CLEAROBJ; } } - rspeak(spk); - return GO_CLEAROBJ; + if (obj == VASE && game.prop[VASE] == VASE_WHOLE) { + if (TOTING(VASE)) + drop(VASE, game.loc); + state_change(VASE, VASE_BROKEN); + game.fixed[VASE] = -1; + return GO_CLEAROBJ; + } + rspeak(actions[verb].message); + return (GO_CLEAROBJ); } static int brief(void) @@ -284,7 +307,7 @@ static int vcarry(token_t verb, token_t obj) spk = DOUGHNUT_HOLES; if (obj == BLOOD) spk = FEW_DROPS; - if (obj == RUG && game.prop[RUG] == 2) + if (obj == RUG && game.prop[RUG] == RUG_HOVER) spk = RUG_HOVERS; if (obj == SIGN) spk = HAND_PASSTHROUGH; @@ -354,21 +377,21 @@ static int chain(token_t verb) spk = CHAIN_UNLOCKED; if (game.prop[BEAR] == UNTAMED_BEAR) spk = BEAR_BLOCKS; - if (game.prop[CHAIN] == 0) + if (game.prop[CHAIN] == CHAIN_HEAP) spk = ALREADY_UNLOCKED; if (spk != CHAIN_UNLOCKED) { rspeak(spk); return GO_CLEAROBJ; } - game.prop[CHAIN] = 0; - game.fixed[CHAIN] = 0; + 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] != 0) + if (game.prop[CHAIN] != CHAIN_HEAP) spk = ALREADY_LOCKED; if (game.loc != objects[CHAIN].plac) spk = NO_LOCKSITE; @@ -376,7 +399,7 @@ static int chain(token_t verb) rspeak(spk); return GO_CLEAROBJ; } - game.prop[CHAIN] = 2; + game.prop[CHAIN] = CHAIN_FIXED; if (TOTING(CHAIN)) drop(CHAIN, game.loc); game.fixed[CHAIN] = -1; @@ -410,8 +433,8 @@ static int discard(token_t verb, token_t obj, bool just_do_it) rspeak(GEM_FITS); game.prop[obj] = 1; game.prop[CAVITY] = CAVITY_FULL; - if (HERE(RUG) && ((obj == EMERALD && game.prop[RUG] != 2) || (obj == RUBY && - game.prop[RUG] == 2))) { + if (HERE(RUG) && ((obj == EMERALD && game.prop[RUG] != RUG_HOVER) || (obj == RUBY && + game.prop[RUG] == RUG_HOVER))) { spk = RUG_RISES; if (TOTING(RUG)) spk = RUG_WIGGLES; @@ -419,6 +442,7 @@ static int discard(token_t verb, token_t obj, bool just_do_it) spk = RUG_SETTLES; rspeak(spk); if (spk != RUG_WIGGLES) { + /* FIXME: Arithmetic on state numbers */ int k = 2 - game.prop[RUG]; game.prop[RUG] = k; if (k == 2) @@ -431,7 +455,7 @@ static int discard(token_t verb, token_t obj, bool just_do_it) drop(BATTERY, game.loc); pspeak(BATTERY, look, FRESH_BATTERIES); return GO_CLEAROBJ; - } else if (obj == BIRD && AT(DRAGON) && game.prop[DRAGON] == 0) { + } else if (obj == BIRD && AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) { rspeak(BIRD_BURNT); DESTROY(BIRD); return GO_CLEAROBJ; @@ -442,15 +466,15 @@ static int discard(token_t verb, token_t obj, bool just_do_it) move(TROLL2, objects[TROLL].plac); move(TROLL2 + NOBJECTS, objects[TROLL].fixd); juggle(CHASM); - game.prop[TROLL] = 2; + game.prop[TROLL] = TROLL_GONE; } else if (obj != VASE || game.loc == objects[PILLOW].plac) { rspeak(OK_MAN); } else { - game.prop[VASE] = 2; + game.prop[VASE] = VASE_BROKEN; if (AT(PILLOW)) - game.prop[VASE] = 0; + game.prop[VASE] = VASE_WHOLE; pspeak(VASE, look, game.prop[VASE] + 1); - if (game.prop[VASE] != 0) + if (game.prop[VASE] != VASE_WHOLE) game.fixed[VASE] = -1; } } @@ -485,13 +509,12 @@ static int drink(token_t verb, token_t obj) game.place[WATER] = LOC_NOWHERE; spk = BOTTLE_EMPTY; } + rspeak(spk); } else { DESTROY(BLOOD); - game.prop[DRAGON] = 2; + state_change(DRAGON, DRAGON_BLOODLESS); game.blooded = true; - spk = HEAD_BUZZES; } - rspeak(spk); return GO_CLEAROBJ; } @@ -522,25 +545,33 @@ static int eat(token_t verb, token_t obj) static int extinguish(token_t verb, int obj) /* Extinguish. Lamp, urn, dragon/volcano (nice try). */ { - int spk = actions[verb].message; if (obj == INTRANSITIVE) { if (HERE(LAMP) && game.prop[LAMP] == LAMP_BRIGHT) obj = LAMP; - if (HERE(URN) && game.prop[URN] == 2) - obj = obj * NOBJECTS + URN; - if (obj == INTRANSITIVE || obj == 0 || obj > NOBJECTS) + 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)) return GO_UNKNOWN; } if (obj == URN) { - game.prop[URN] = game.prop[URN] / 2; - spk = URN_DARK; + if (game.prop[URN] != URN_EMPTY) { + state_change(URN, URN_DARK); + } else { + pspeak(URN, change, URN_DARK); + } + } else if (obj == LAMP) { state_change(LAMP, LAMP_DARK); - spk = DARK(game.loc) ? PITCH_DARK : NO_MESSAGE; - } else if (obj == DRAGON || obj == VOLCANO) - spk = BEYOND_POWER; - rspeak(spk); + rspeak(DARK(game.loc) ? PITCH_DARK : NO_MESSAGE); + } else if (obj == DRAGON || obj == VOLCANO) { + rspeak(BEYOND_POWER); + + } else { + rspeak(actions[verb].message); + } return GO_CLEAROBJ; } @@ -554,7 +585,7 @@ static int feed(token_t verb, token_t obj) return GO_CLEAROBJ; } else if (obj == SNAKE || obj == DRAGON || obj == TROLL) { spk = NOTHING_EDIBLE; - if (obj == DRAGON && game.prop[DRAGON] != 0) + if (obj == DRAGON && game.prop[DRAGON] != DRAGON_BARS) spk = RIDICULOUS_ATTEMPT; if (obj == TROLL) spk = TROLL_VICES; @@ -604,7 +635,7 @@ int fill(token_t verb, token_t obj) return GO_CLEAROBJ; } rspeak(SHATTER_VASE); - game.prop[VASE] = 2; + game.prop[VASE] = VASE_BROKEN; game.fixed[VASE] = -1; return (discard(verb, obj, true)); } else if (obj == URN) { @@ -673,7 +704,7 @@ static int fly(token_t verb, token_t obj) { int spk = actions[verb].message; if (obj == INTRANSITIVE) { - if (game.prop[RUG] != 2) + if (game.prop[RUG] != RUG_HOVER) spk = RUG_NOTHING2; if (!HERE(RUG)) spk = FLAP_ARMS; @@ -689,12 +720,13 @@ static int fly(token_t verb, token_t obj) return GO_CLEAROBJ; } spk = RUG_NOTHING1; - if (game.prop[RUG] != 2) { + if (game.prop[RUG] != RUG_HOVER) { rspeak(spk); return GO_CLEAROBJ; } game.oldlc2 = game.oldloc; game.oldloc = game.loc; + /* FIXME: Arithmetic on location values */ game.newloc = game.place[RUG] + game.fixed[RUG] - game.loc; spk = RUG_GOES; if (game.prop[SAPPH] >= 0) @@ -726,32 +758,27 @@ static int inven(void) static int light(token_t verb, token_t obj) /* Light. Applicable only to lamp and urn. */ { - int spk = actions[verb].message; if (obj == INTRANSITIVE) { if (HERE(LAMP) && game.prop[LAMP] == LAMP_DARK && game.limit >= 0) obj = LAMP; - if (HERE(URN) && game.prop[URN] == 1) - obj = obj * NOBJECTS + URN; - if (obj == INTRANSITIVE || obj == 0 || obj > NOBJECTS) + 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)) return GO_UNKNOWN; } if (obj == URN) { - if (game.prop[URN] == 0) { - rspeak(URN_EMPTY); - } else { - game.prop[URN] = 2; - rspeak(URN_LIT); - } + state_change(URN, game.prop[URN] == URN_EMPTY ? URN_EMPTY : URN_LIT); return GO_CLEAROBJ; } else { if (obj != LAMP) { - rspeak(spk); + rspeak(actions[verb].message); return GO_CLEAROBJ; } - spk = LAMP_OUT; if (game.limit < 0) { - rspeak(spk); + rspeak(LAMP_OUT); return GO_CLEAROBJ; } state_change(LAMP, LAMP_BRIGHT); @@ -806,8 +833,6 @@ static int lock(token_t verb, token_t obj) obj = DOOR; if (AT(GRATE)) obj = GRATE; - if (obj != 0 && HERE(CHAIN)) - return GO_UNKNOWN; if (HERE(CHAIN)) obj = CHAIN; if (obj == 0 || obj == INTRANSITIVE) { @@ -822,7 +847,7 @@ static int lock(token_t verb, token_t obj) return bivalve(verb, obj); if (obj == DOOR) spk = RUSTY_DOOR; - if (obj == DOOR && game.prop[DOOR] == 1) + if (obj == DOOR && game.prop[DOOR] == DOOR_UNRUSTED) spk = OK_MAN; if (obj == CAGE) spk = NO_LOCK; @@ -866,7 +891,7 @@ static int pour(token_t verb, token_t obj) rspeak(spk); return GO_CLEAROBJ; } - if (HERE(URN) && game.prop[URN] == 0) + if (HERE(URN) && game.prop[URN] == URN_EMPTY) return fill(verb, URN); game.prop[BOTTLE] = EMPTY_BOTTLE; game.place[obj] = LOC_NOWHERE; @@ -886,11 +911,7 @@ static int pour(token_t verb, token_t obj) game.prop[PLANT2] = game.prop[PLANT]; return GO_MOVE; } else { - game.prop[DOOR] = 0; - if (obj == OIL) - game.prop[DOOR] = 1; - spk = RUSTED_HINGES + game.prop[DOOR]; - rspeak(spk); + state_change(DOOR, (obj == OIL) ? DOOR_UNRUSTED : DOOR_RUSTED); return GO_CLEAROBJ; } } @@ -953,7 +974,7 @@ static int rub(token_t verb, token_t obj) int spk = actions[verb].message; if (obj != LAMP) spk = PECULIAR_NOTHING; - if (obj == URN && game.prop[URN] == 2) { + if (obj == URN && game.prop[URN] == URN_LIT) { DESTROY(URN); drop(AMBER, game.loc); game.prop[AMBER] = 1; @@ -1030,7 +1051,7 @@ static int throw (struct command_t *command) else { int i = atdwrf(game.loc); if (i <= 0) { - if (AT(DRAGON) && game.prop[DRAGON] == 0) + if (AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) return throw_support(DRAGON_SCALES); if (AT(TROLL)) return throw_support(TROLL_RETURNS); @@ -1084,7 +1105,7 @@ static int wave(token_t verb, token_t obj) rspeak(spk); return GO_CLEAROBJ; } - /* FIXME: Arithemetic on proprty values */ + /* FIXME: Arithemetic on property values */ if (HERE(BIRD)) spk = FREE_FLY + MOD(game.prop[BIRD], 2); if (spk == FREE_FLY && game.loc == game.place[STEPS] && game.prop[JADE] < 0) {