Coverage -- giant words
[open-adventure.git] / actions.c
index f2ec65adac01a042d5b8b7283d4e89f9bee2ca4f..13fc8c5dfdf7bee165612b5c0e3b5af818b84231 100644 (file)
--- 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)
+    if (obj == NO_OBJECT || obj == INTRANSITIVE) {
+        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;
-        if (obj == 0) {
+            ++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 == NO_OBJECT) {
             /* 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);
@@ -63,7 +85,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;
@@ -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);
@@ -439,8 +460,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);
@@ -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;
         }
@@ -476,18 +497,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);
@@ -529,8 +550,8 @@ static int extinguish(token_t verb, int obj)
         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)
+            (HERE(LAMP) && game.prop[LAMP] == LAMP_BRIGHT &&
+             HERE(URN) && game.prop[URN] == URN_LIT))
             return GO_UNKNOWN;
     }
 
@@ -538,7 +559,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);
+            pspeak(URN, change, URN_DARK, true);
         }
 
     } else if (obj == LAMP) {
@@ -618,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;
         }
@@ -631,19 +652,19 @@ 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;
-    } 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)
         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;
@@ -722,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))
@@ -742,8 +761,8 @@ static int light(token_t verb, token_t obj)
         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)
+            (HERE(LAMP) && game.prop[LAMP] == LAMP_DARK && game.limit >= 0 &&
+             HERE(URN) && game.prop[URN] == URN_DARK))
             return GO_UNKNOWN;
     }
 
@@ -787,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)
@@ -811,11 +830,9 @@ 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) {
+        if (obj == NO_OBJECT || obj == INTRANSITIVE) {
             rspeak(spk);
             return GO_CLEAROBJ;
         }
@@ -827,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;
@@ -858,9 +875,9 @@ static int pour(token_t verb, token_t obj)
  *  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);
@@ -871,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;
@@ -886,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;
@@ -924,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;
 }
 
@@ -935,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,18 +968,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] == 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;
+        rspeak(URN_GENIES);
+    } else if (obj != LAMP) {
+        rspeak(PECULIAR_NOTHING);
+    } else {
+        rspeak(actions[verb].message);
     }
-    rspeak(spk);
     return GO_CLEAROBJ;
 }
 
@@ -975,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;
@@ -1002,23 +1018,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)) {
@@ -1029,8 +1043,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))
@@ -1041,18 +1054,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)
@@ -1073,41 +1086,47 @@ static int wake(token_t verb, token_t obj)
     }
 }
 
+static token_t birdspeak(void)
+{
+    switch (game.prop[BIRD]) {
+    case BIRD_CAGED:
+        return CAGE_FLY;
+    default:
+        return FREE_FLY;
+    }
+}
+
 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(birdspeak());
             return GO_DWARFWAKE;
         }
         if (game.closng || !AT(FISSURE)) {
-            rspeak(spk);
+            rspeak(birdspeak());
             return GO_CLEAROBJ;
         }
         if (HERE(BIRD))
-            rspeak(spk);
+            rspeak(birdspeak());
+
+        /* FIXME: Arithemetic on property values */
         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;
     }
 }
@@ -1117,8 +1136,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
@@ -1147,8 +1164,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;
@@ -1198,7 +1214,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:
@@ -1279,11 +1295,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:
@@ -1299,7 +1315,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:
@@ -1314,15 +1330,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:
@@ -1332,17 +1348,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: