X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=actions.c;h=95a94b821d15c888041e288d483e42933e6559b7;hb=89e1833d8fcdc92e82198c2a39d85d9d94c729ae;hp=409e58e110eaaceb23718318dab19583f7dc7692;hpb=a5478639b6ea18b84fcd2eac15b82a0f5dff20d4;p=open-adventure.git diff --git a/actions.c b/actions.c index 409e58e..95a94b8 100644 --- a/actions.c +++ b/actions.c @@ -8,7 +8,7 @@ static int fill(token_t, token_t); static void state_change(long obj, long state) { game.prop[obj] = state; - pspeak(obj, change, state); + pspeak(obj, change, state, true); } static int attack(struct command_t *command) @@ -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] == DRAGON_BARS) - 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); @@ -144,10 +166,9 @@ static int attack(struct command_t *command) static int bigwords(token_t foo) /* FEE FIE FOE FOO (AND FUM). Advance to next state if given in proper order. - * Look up foo in section 3 of vocab to determine which word we've got. Last - * word zips the eggs back to the giant room (unless already there). */ + * 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). */ { - //int k = vocab(foo, 3); char word[6]; packed_to_token(foo, word); int k = (int) get_special_vocab_id(word); @@ -178,7 +199,7 @@ static int bigwords(token_t foo) if (game.loc == objects[EGGS].plac) k = EGGS_HERE; move(EGGS, objects[EGGS].plac); - pspeak(EGGS, look, k); + pspeak(EGGS, look, k, true); return GO_CLEAROBJ; } } @@ -340,7 +361,7 @@ static int vcarry(token_t verb, token_t obj) if (obj == BOTTLE && LIQUID() != 0) game.place[LIQUID()] = CARRIED; if (GSTONE(obj) && game.prop[obj] != 0) { - game.prop[obj] = 0; + game.prop[obj] = STATE_GROUND; game.prop[CAVITY] = CAVITY_EMPTY; } rspeak(OK_MAN); @@ -431,7 +452,7 @@ static int discard(token_t verb, token_t obj, bool just_do_it) } else if (obj == COINS && HERE(VEND)) { DESTROY(COINS); drop(BATTERY, game.loc); - pspeak(BATTERY, look, FRESH_BATTERIES); + pspeak(BATTERY, look, FRESH_BATTERIES, true); return GO_CLEAROBJ; } else if (obj == BIRD && AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) { rspeak(BIRD_BURNT); @@ -451,7 +472,7 @@ static int discard(token_t verb, token_t obj, bool just_do_it) game.prop[VASE] = VASE_BROKEN; if (AT(PILLOW)) game.prop[VASE] = VASE_WHOLE; - pspeak(VASE, look, game.prop[VASE] + 1); + pspeak(VASE, look, game.prop[VASE] + 1, true); if (game.prop[VASE] != VASE_WHOLE) game.fixed[VASE] = -1; } @@ -523,25 +544,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, true); + } + } 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; } @@ -610,7 +639,7 @@ int fill(token_t verb, token_t obj) return (discard(verb, obj, true)); } else if (obj == URN) { spk = FULL_URN; - if (game.prop[URN] != 0) { + if (game.prop[URN] != URN_EMPTY) { rspeak(spk); return GO_CLEAROBJ; } @@ -623,7 +652,7 @@ int fill(token_t verb, token_t obj) game.place[k] = LOC_NOWHERE; game.prop[BOTTLE] = EMPTY_BOTTLE; if (k == OIL) - game.prop[URN] = 1; + game.prop[URN] = URN_DARK; spk = WATER_URN + game.prop[URN]; rspeak(spk); return GO_CLEAROBJ; @@ -635,7 +664,7 @@ int fill(token_t verb, token_t obj) spk = BOTTLED_WATER; if (LIQLOC(game.loc) == 0) spk = NO_LIQUID; - if (HERE(URN) && game.prop[URN] != 0) + if (HERE(URN) && game.prop[URN] != URN_EMPTY) spk = URN_NOPOUR; if (LIQUID() != 0) spk = BOTTLE_FULL; @@ -714,9 +743,7 @@ static int inven(void) continue; if (spk == NO_CARRY) rspeak(NOW_HOLDING); - game.blklin = false; - pspeak(i, touch, -1); - game.blklin = true; + pspeak(i, touch, -1, false); spk = NO_MESSAGE; } if (TOTING(BEAR)) @@ -728,32 +755,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); @@ -784,7 +806,7 @@ static int listen(void) if (i == BIRD) mi += 3 * game.blooded; long packed_zzword = token_to_packed(game.zzword); - pspeak(i, hear, mi, packed_zzword); + pspeak(i, hear, mi, true, packed_zzword); spk = NO_MESSAGE; /* FIXME: Magic number, sensitive to bird state logic */ if (i == BIRD && game.prop[i] == 5) @@ -808,8 +830,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) { @@ -824,7 +844,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; @@ -868,7 +888,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; @@ -883,7 +903,7 @@ static int pour(token_t verb, token_t obj) rspeak(spk); return GO_CLEAROBJ; } - pspeak(PLANT, look, game.prop[PLANT] + 3); + pspeak(PLANT, look, game.prop[PLANT] + 3, true); game.prop[PLANT] = MOD(game.prop[PLANT] + 1, 3); game.prop[PLANT2] = game.prop[PLANT]; return GO_MOVE; @@ -921,7 +941,7 @@ static int read(struct command_t command) } else if (objects[command.obj].texts[0] == NULL || game.prop[command.obj] < 0) { rspeak(actions[command.verb].message); } else - pspeak(command.obj, study, game.prop[command.obj]); + pspeak(command.obj, study, game.prop[command.obj], true); return GO_CLEAROBJ; } @@ -932,7 +952,7 @@ static int reservoir(void) rspeak(NOTHING_HAPPENS); return GO_CLEAROBJ; } else { - pspeak(RESER, look, game.prop[RESER] + 1); + pspeak(RESER, look, game.prop[RESER] + 1, true); game.prop[RESER] = 1 - game.prop[RESER]; if (AT(RESER)) return GO_CLEAROBJ; @@ -951,10 +971,10 @@ 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; + game.prop[AMBER] = AMBER_IN_ROCK; --game.tally; drop(CAVITY, game.loc); spk = URN_GENIES; @@ -972,12 +992,11 @@ static int say(struct command_t *command) b = command->wd2x; command->wd1 = command->wd2; } - //int wd = vocab(command->wd1, -1); char word1[6]; packed_to_token(command->wd1, word1); int wd = (int) get_vocab_id(word1); /* FIXME: magic numbers */ - if (wd == XYZZY || wd == PLUGH || wd == PLOVER || wd == ACTION_WORD(GIANTWORDS) || wd == ACTION_WORD(PART)) { + if (wd == MOTION_WORD(XYZZY) || wd == MOTION_WORD(PLUGH) || wd == MOTION_WORD(PLOVER) || wd == ACTION_WORD(GIANTWORDS) || wd == ACTION_WORD(PART)) { /* FIXME: scribbles on the interpreter's command block */ wordclear(&command->wd2); return GO_LOOKUP; @@ -1104,7 +1123,7 @@ static int wave(token_t verb, token_t obj) if (HERE(BIRD)) rspeak(spk); game.prop[FISSURE] = 1 - game.prop[FISSURE]; - pspeak(FISSURE, look, 2 - game.prop[FISSURE]); + pspeak(FISSURE, look, 2 - game.prop[FISSURE], true); return GO_CLEAROBJ; } }