X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=actions.c;h=062c3721aaaf9b90936794b8b02bc35dc9162b39;hb=fc5267fe8b856de9480f2b5400fbe3a22519f0a3;hp=95a94b821d15c888041e288d483e42933e6559b7;hpb=89e1833d8fcdc92e82198c2a39d85d9d94c729ae;p=open-adventure.git diff --git a/actions.c b/actions.c index 95a94b8..062c372 100644 --- a/actions.c +++ b/actions.c @@ -20,11 +20,8 @@ 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 (obj == NO_OBJECT || obj == INTRANSITIVE) { int changes = 0; if (atdwrf(game.loc) > 0) { obj = DWARF; @@ -51,7 +48,7 @@ static int attack(struct command_t *command) ++changes; } /* check for low-priority targets */ - if (obj == 0) { + if (obj == NO_OBJECT) { /* Can't attack bird or machine by throwing axe. */ if (HERE(BIRD) && verb != THROW) { obj = BIRD; @@ -85,7 +82,7 @@ static int attack(struct command_t *command) return GO_CLEAROBJ; } - if (obj == 0) + if (obj == NO_OBJECT) spk = NO_TARGET; if (obj == CLAM || obj == OYSTER) spk = SHELL_IMPERVIOUS; @@ -208,21 +205,26 @@ static int bigwords(token_t foo) static int bivalve(token_t verb, token_t obj) /* Clam/oyster actions */ { - int spk; bool is_oyster = (obj == OYSTER); - spk = is_oyster ? OYSTER_OPENS : PEARL_FALLS; - if (TOTING(obj)) - spk = is_oyster ? DROP_OYSTER : DROP_CLAM; - if (!TOTING(TRIDENT)) - spk = is_oyster ? OYSTER_OPENER : CLAM_OPENER; - if (verb == LOCK) - spk = HUH_MAN; - if (spk == PEARL_FALLS) { + if (verb == LOCK) { + rspeak(HUH_MAN); + return GO_CLEAROBJ; + } + if (!TOTING(TRIDENT)) { + rspeak(is_oyster ? OYSTER_OPENER : CLAM_OPENER); + return GO_CLEAROBJ; + } + if (TOTING(obj)) { + rspeak( is_oyster ? DROP_OYSTER : DROP_CLAM); + return GO_CLEAROBJ; + } + + if (!is_oyster) { DESTROY(CLAM); drop(OYSTER, game.loc); drop(PEARL, LOC_CULDESAC); } - rspeak(spk); + rspeak(is_oyster ? OYSTER_OPENS : PEARL_FALLS); return GO_CLEAROBJ; } @@ -460,8 +462,8 @@ static int discard(token_t verb, token_t obj, bool just_do_it) return GO_CLEAROBJ; } else if (obj == BEAR && AT(TROLL)) { rspeak(TROLL_SCAMPERS); - move(TROLL, 0); - move(TROLL + NOBJECTS, 0); + move(TROLL, LOC_NOWHERE); + move(TROLL + NOBJECTS, LOC_NOWHERE); move(TROLL2, objects[TROLL].plac); move(TROLL2 + NOBJECTS, objects[TROLL].fixd); juggle(CHASM); @@ -497,18 +499,18 @@ static int drink(token_t verb, token_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. */ { - int spk = actions[verb].message; - if (obj == 0 && LIQLOC(game.loc) != WATER && (LIQUID() != WATER || !HERE(BOTTLE))) + if (obj == NO_OBJECT && LIQLOC(game.loc) != WATER && (LIQUID() != WATER || !HERE(BOTTLE))) return GO_UNKNOWN; if (obj != BLOOD) { - if (obj != 0 && obj != WATER) - spk = RIDICULOUS_ATTEMPT; - if (spk != RIDICULOUS_ATTEMPT && LIQUID() == WATER && HERE(BOTTLE)) { + if (obj != NO_OBJECT && obj != WATER) { + rspeak(RIDICULOUS_ATTEMPT); + } else if (LIQUID() == WATER && HERE(BOTTLE)) { game.prop[BOTTLE] = EMPTY_BOTTLE; game.place[WATER] = LOC_NOWHERE; - spk = BOTTLE_EMPTY; + rspeak(BOTTLE_EMPTY); + } else { + rspeak(actions[verb].message); } - rspeak(spk); } else { DESTROY(BLOOD); state_change(DRAGON, DRAGON_BLOODLESS); @@ -521,23 +523,25 @@ static int eat(token_t verb, token_t obj) /* Eat. Intransitive: assume food if present, else ask what. Transitive: food * ok, some things lose appetite, rest are ridiculous. */ { - int spk = actions[verb].message; if (obj == INTRANSITIVE) { if (!HERE(FOOD)) return GO_UNKNOWN; DESTROY(FOOD); - spk = THANKS_DELICIOUS; - } else { - if (obj == FOOD) { - DESTROY(FOOD); - spk = THANKS_DELICIOUS; - } - if (obj == BIRD || obj == SNAKE || obj == CLAM || obj == OYSTER || obj == - DWARF || obj == DRAGON || obj == TROLL || obj == BEAR || obj == - OGRE) - spk = LOST_APPETITE; + rspeak(THANKS_DELICIOUS); + return GO_CLEAROBJ; } - rspeak(spk); + 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) { + rspeak(LOST_APPETITE); + return GO_CLEAROBJ; + } + rspeak(actions[verb].message); return GO_CLEAROBJ; } @@ -559,7 +563,7 @@ static int extinguish(token_t verb, int obj) if (game.prop[URN] != URN_EMPTY) { state_change(URN, URN_DARK); } else { - pspeak(URN, change, URN_DARK, true); + pspeak(URN, change, URN_DARK, true); } } else if (obj == LAMP) { @@ -656,10 +660,10 @@ int fill(token_t verb, token_t obj) spk = WATER_URN + game.prop[URN]; rspeak(spk); return GO_CLEAROBJ; - } else if (obj != 0 && obj != BOTTLE) { + } else if (obj != NO_OBJECT && obj != BOTTLE) { rspeak(spk); return GO_CLEAROBJ; - } else if (obj == 0 && !HERE(BOTTLE)) + } else if (obj == NO_OBJECT && !HERE(BOTTLE)) return GO_UNKNOWN; spk = BOTTLED_WATER; if (LIQLOC(game.loc) == 0) @@ -701,36 +705,36 @@ static int find(token_t verb, token_t obj) static int fly(token_t verb, token_t obj) /* Fly. Snide remarks unless hovering rug is here. */ { - int spk = actions[verb].message; if (obj == INTRANSITIVE) { - if (game.prop[RUG] != RUG_HOVER) - spk = RUG_NOTHING2; - if (!HERE(RUG)) - spk = FLAP_ARMS; - if (spk == RUG_NOTHING2 || spk == FLAP_ARMS) { - rspeak(spk); + if (!HERE(RUG)) { + rspeak(FLAP_ARMS); + return GO_CLEAROBJ; + } + if (game.prop[RUG] != RUG_HOVER) { + rspeak(RUG_NOTHING2); return GO_CLEAROBJ; } obj = RUG; } if (obj != RUG) { - rspeak(spk); + rspeak(actions[verb].message); return GO_CLEAROBJ; } - spk = RUG_NOTHING1; if (game.prop[RUG] != RUG_HOVER) { - rspeak(spk); + rspeak(RUG_NOTHING1); 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) - spk = RUG_RETURNS; - rspeak(spk); + + if (game.prop[SAPPH] >= 0) { + rspeak(RUG_RETURNS); + } else { + rspeak(RUG_GOES); + } return GO_TERMINATE; } @@ -789,15 +793,12 @@ static int light(token_t verb, token_t obj) static int listen(void) /* Listen. Intransitive only. Print stuff based on objsnd/locsnd. */ { - long k; - int spk = ALL_SILENT; - k = locations[game.loc].sound; - if (k != SILENT) { - rspeak(k); - if (locations[game.loc].loud) - return GO_CLEAROBJ; - else - spk = NO_MESSAGE; + long sound = locations[game.loc].sound; + if (sound != SILENT) { + rspeak(sound); + if (!locations[game.loc].loud) + rspeak(NO_MESSAGE); + return GO_CLEAROBJ; } for (int i = 1; i <= NOBJECTS; i++) { if (!HERE(i) || objects[i].sounds[0] == NULL || game.prop[i] < 0) @@ -807,21 +808,20 @@ static int listen(void) mi += 3 * game.blooded; long packed_zzword = token_to_packed(game.zzword); pspeak(i, hear, mi, true, packed_zzword); - spk = NO_MESSAGE; + rspeak(NO_MESSAGE); /* FIXME: Magic number, sensitive to bird state logic */ if (i == BIRD && game.prop[i] == 5) DESTROY(BIRD); + return GO_CLEAROBJ; } - rspeak(spk); + rspeak(ALL_SILENT); return GO_CLEAROBJ; } static int lock(token_t verb, token_t obj) /* Lock, unlock, no object given. Assume various things if present. */ { - int spk = actions[verb].message; if (obj == INTRANSITIVE) { - spk = NOTHING_LOCKED; if (HERE(CLAM)) obj = CLAM; if (HERE(OYSTER)) @@ -832,20 +832,19 @@ static int lock(token_t verb, token_t obj) obj = GRATE; if (HERE(CHAIN)) obj = CHAIN; - if (obj == 0 || obj == INTRANSITIVE) { - rspeak(spk); + if (obj == NO_OBJECT || obj == INTRANSITIVE) { + rspeak(NOTHING_LOCKED); return GO_CLEAROBJ; } } /* Lock, unlock object. Special stuff for opening clam/oyster * and for chain. */ + int spk = actions[verb].message; if (obj == CLAM || obj == OYSTER) return bivalve(verb, obj); if (obj == DOOR) - spk = RUSTY_DOOR; - if (obj == DOOR && game.prop[DOOR] == DOOR_UNRUSTED) - spk = OK_MAN; + spk = (game.prop[DOOR] == DOOR_UNRUSTED) ? OK_MAN : RUSTY_DOOR; if (obj == CAGE) spk = NO_LOCK; if (obj == KEYS) @@ -874,33 +873,30 @@ static int pour(token_t verb, token_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. */ { - int spk = actions[verb].message; - if (obj == BOTTLE || obj == 0) + if (obj == BOTTLE || obj == NO_OBJECT) obj = LIQUID(); - if (obj == 0) + if (obj == NO_OBJECT) return GO_UNKNOWN; if (!TOTING(obj)) { - rspeak(spk); + rspeak(actions[verb].message); return GO_CLEAROBJ; } - spk = CANT_POUR; + if (obj != OIL && obj != WATER) { - rspeak(spk); + rspeak(CANT_POUR); return GO_CLEAROBJ; } if (HERE(URN) && game.prop[URN] == URN_EMPTY) return fill(verb, URN); game.prop[BOTTLE] = EMPTY_BOTTLE; game.place[obj] = LOC_NOWHERE; - spk = GROUND_WET; if (!(AT(PLANT) || AT(DOOR))) { - rspeak(spk); + rspeak(GROUND_WET); return GO_CLEAROBJ; } if (!AT(DOOR)) { - spk = SHAKING_LEAVES; if (obj != WATER) { - rspeak(spk); + rspeak(SHAKING_LEAVES); return GO_CLEAROBJ; } pspeak(PLANT, look, game.prop[PLANT] + 3, true); @@ -941,7 +937,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], true); + pspeak(command.obj, study, game.prop[command.obj], true); return GO_CLEAROBJ; } @@ -952,7 +948,7 @@ static int reservoir(void) rspeak(NOTHING_HAPPENS); return GO_CLEAROBJ; } else { - pspeak(RESER, look, game.prop[RESER] + 1, true); + pspeak(RESER, look, game.prop[RESER] + 1, true); game.prop[RESER] = 1 - game.prop[RESER]; if (AT(RESER)) return GO_CLEAROBJ; @@ -968,18 +964,18 @@ static int reservoir(void) static int rub(token_t verb, token_t obj) /* Rub. Yields various snide remarks except for lit urn. */ { - int spk = actions[verb].message; - if (obj != LAMP) - spk = PECULIAR_NOTHING; if (obj == URN && game.prop[URN] == URN_LIT) { DESTROY(URN); drop(AMBER, game.loc); game.prop[AMBER] = AMBER_IN_ROCK; --game.tally; drop(CAVITY, game.loc); - spk = URN_GENIES; + rspeak(URN_GENIES); + } else if (obj != LAMP) { + rspeak(PECULIAR_NOTHING); + } else { + rspeak(actions[verb].message); } - rspeak(spk); return GO_CLEAROBJ; } @@ -1018,23 +1014,21 @@ static int throw (struct command_t *command) * (Only way to do so!) Axe also special for dragon, bear, and * troll. Treasures special for troll. */ { - int spk = actions[command->verb].message; if (TOTING(ROD2) && command->obj == ROD && !TOTING(ROD)) command->obj = ROD2; if (!TOTING(command->obj)) { - rspeak(spk); + rspeak(actions[command->verb].message); return GO_CLEAROBJ; } if (objects[command->obj].is_treasure && AT(TROLL)) { - spk = TROLL_SATISFIED; /* Snarf a treasure for the troll. */ - drop(command->obj, 0); - move(TROLL, 0); - move(TROLL + NOBJECTS, 0); + drop(command->obj, LOC_NOWHERE); + move(TROLL, LOC_NOWHERE); + move(TROLL + NOBJECTS, LOC_NOWHERE); drop(TROLL2, objects[TROLL].plac); drop(TROLL2 + NOBJECTS, objects[TROLL].fixd); juggle(CHASM); - rspeak(spk); + rspeak(TROLL_SATISFIED); return GO_CLEAROBJ; } if (command->obj == FOOD && HERE(BEAR)) { @@ -1045,8 +1039,7 @@ static int throw (struct command_t *command) if (command->obj != AXE) return (discard(command->verb, command->obj, false)); else { - int i = atdwrf(game.loc); - if (i <= 0) { + if (atdwrf(game.loc) <= 0) { if (AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) return throw_support(DRAGON_SCALES); if (AT(TROLL)) @@ -1057,18 +1050,18 @@ static int throw (struct command_t *command) /* This'll teach him to throw the axe at the bear! */ drop(AXE, game.loc); game.fixed[AXE] = -1; - game.prop[AXE] = 1; juggle(BEAR); - rspeak(AXE_LOST); + state_change(AXE, AXE_LOST); return GO_CLEAROBJ; } - command->obj = 0; + command->obj = NO_OBJECT; return (attack(command)); } if (randrange(NDWARVES + 1) < game.dflag) { return throw_support(DWARF_DODGES); } else { + long i = atdwrf(game.loc); game.dseen[i] = false; game.dloc[i] = 0; return throw_support((++game.dkill == 1) @@ -1092,36 +1085,32 @@ static int wake(token_t verb, token_t obj) static int wave(token_t verb, token_t obj) /* Wave. No effect unless waving rod at fissure or at bird. */ { - int spk = actions[verb].message; - if ((!TOTING(obj)) && (obj != ROD || !TOTING(ROD2))) - spk = ARENT_CARRYING; if (obj != ROD || !TOTING(obj) || (!HERE(BIRD) && (game.closng || !AT(FISSURE)))) { - rspeak(spk); + rspeak(((!TOTING(obj)) && (obj != ROD || !TOTING(ROD2))) ? ARENT_CARRYING : actions[verb].message); return GO_CLEAROBJ; } - /* 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) { + + if (game.prop[BIRD] == BIRD_UNCAGED && game.loc == game.place[STEPS] && game.prop[JADE] < 0) { drop(JADE, game.loc); game.prop[JADE] = 0; --game.tally; - spk = NECKLACE_FLY; - rspeak(spk); + rspeak(NECKLACE_FLY); return GO_CLEAROBJ; } else { if (game.closed) { - rspeak(spk); + rspeak((game.prop[BIRD] == BIRD_CAGED) ? CAGE_FLY : FREE_FLY); return GO_DWARFWAKE; } if (game.closng || !AT(FISSURE)) { - rspeak(spk); + rspeak((game.prop[BIRD] == BIRD_CAGED) ? CAGE_FLY : FREE_FLY); return GO_CLEAROBJ; } if (HERE(BIRD)) - rspeak(spk); + rspeak((game.prop[BIRD] == BIRD_CAGED) ? CAGE_FLY : FREE_FLY); + + /* FIXME: Arithemetic on property values */ game.prop[FISSURE] = 1 - game.prop[FISSURE]; pspeak(FISSURE, look, 2 - game.prop[FISSURE], true); return GO_CLEAROBJ; @@ -1133,8 +1122,6 @@ int action(struct command_t *command) * unless verb is "say", which snarfs arbitrary second word. */ { - token_t spk = actions[command->verb].message; - if (command->part == unknown) { /* Analyse an object word. See if the thing is here, whether * we've got a verb yet, and so on. Object must be here @@ -1163,8 +1150,7 @@ int action(struct command_t *command) /* FALL THROUGH */; } else if (command->obj == KNIFE && game.knfloc == game.loc) { game.knfloc = -1; - spk = KNIVES_VANISH; - rspeak(spk); + rspeak(KNIVES_VANISH); return GO_CLEAROBJ; } else if (command->obj == ROD && HERE(ROD2)) { command->obj = ROD2; @@ -1214,7 +1200,7 @@ int action(struct command_t *command) case TAME: return GO_UNKNOWN; case GO: { - rspeak(spk); + rspeak(actions[command->verb].message); return GO_CLEAROBJ; } case ATTACK: @@ -1295,11 +1281,11 @@ int action(struct command_t *command) case WAVE: return wave(command->verb, command->obj); case TAME: { - rspeak(spk); + rspeak(actions[command->verb].message); return GO_CLEAROBJ; } case GO: { - rspeak(spk); + rspeak(actions[command->verb].message); return GO_CLEAROBJ; } case ATTACK: @@ -1315,7 +1301,7 @@ int action(struct command_t *command) case THROW: return throw (command); case QUIT: { - rspeak(spk); + rspeak(actions[command->verb].message); return GO_CLEAROBJ; } case FIND: @@ -1330,15 +1316,15 @@ int action(struct command_t *command) blast(); return GO_CLEAROBJ; case SCORE: { - rspeak(spk); + rspeak(actions[command->verb].message); return GO_CLEAROBJ; } case GIANTWORDS: { - rspeak(spk); + rspeak(actions[command->verb].message); return GO_CLEAROBJ; } case BRIEF: { - rspeak(spk); + rspeak(actions[command->verb].message); return GO_CLEAROBJ; } case READ: @@ -1348,17 +1334,17 @@ int action(struct command_t *command) case WAKE: return wake(command->verb, command->obj); case SAVE: { - rspeak(spk); + rspeak(actions[command->verb].message); return GO_CLEAROBJ; } case RESUME: { - rspeak(spk); + rspeak(actions[command->verb].message); return GO_CLEAROBJ; } case FLY: return fly(command->verb, command->obj); case LISTEN: { - rspeak(spk); + rspeak(actions[command->verb].message); return GO_CLEAROBJ; } case PART: