Wire Section 8 YAML to runtime.
[open-adventure.git] / actions.c
index 4cfcbdcd4f2b709ba538ef8a36aa51dcc02b1c79..0e09682bb730d17f0c9fc18a4f5080450c1c724f 100644 (file)
--- a/actions.c
+++ b/actions.c
@@ -14,7 +14,7 @@ static int attack(FILE *input, struct command_t *command)
 {
     vocab_t verb = command->verb;
     vocab_t obj = command->obj;
-    int spk = ACTSPK[verb];
+    int spk = actspk[verb];
     if (obj == 0 || obj == INTRANSITIVE) {
         if (ATDWRF(game.loc) > 0)
             obj = DWARF;
@@ -44,8 +44,9 @@ static int attack(FILE *input, struct command_t *command)
         DESTROY(BIRD);
         spk = BIRD_DEAD;
     } else if (obj == VEND) {
-        pspeak(VEND, game.prop[VEND] + 2);
-        game.prop[VEND] = 3 - game.prop[VEND];
+       bool blocking = (game.prop[VEND] == VEND_BLOCKS);
+        game.prop[VEND] = blocking ? VEND_UNBLOCKS : VEND_BLOCKS;
+        rspeak(blocking ? MACHINE_SWINGOUT : MACHINE_SWINGBACK);
         return GO_CLEAROBJ;
     }
 
@@ -82,17 +83,17 @@ static int attack(FILE *input, struct command_t *command)
         GETIN(input, &command->wd1, &command->wd1x, &command->wd2, &command->wd2x);
         if (command->wd1 != MAKEWD(WORD_YINIT) && command->wd1 != MAKEWD(WORD_YES))
             return GO_CHECKFOO;
-        pspeak(DRAGON, 3);
+        pspeak(DRAGON, look, 3);
         game.prop[DRAGON] = 1;
         game.prop[RUG] = 0;
-        int k = (PLAC[DRAGON] + FIXD[DRAGON]) / 2;
+        int k = (object_descriptions[DRAGON].plac + object_descriptions[DRAGON].fixd) / 2;
         MOVE(DRAGON + NOBJECTS, -1);
         MOVE(RUG + NOBJECTS, 0);
         MOVE(DRAGON, k);
         MOVE(RUG, k);
         DROP(BLOOD, k);
         for (obj = 1; obj <= NOBJECTS; obj++) {
-            if (game.place[obj] == PLAC[DRAGON] || game.place[obj] == FIXD[DRAGON])
+            if (game.place[obj] == object_descriptions[DRAGON].plac || game.place[obj] == object_descriptions[DRAGON].fixd)
                 MOVE(obj, k);
         }
         game.loc = k;
@@ -121,7 +122,7 @@ static int bigwords(token_t foo)
             return GO_CLEAROBJ;
         }
         game.foobar = 0;
-        if (game.place[EGGS] == PLAC[EGGS] || (TOTING(EGGS) && game.loc == PLAC[EGGS])) {
+        if (game.place[EGGS] == object_descriptions[EGGS].plac || (TOTING(EGGS) && game.loc == object_descriptions[EGGS].plac)) {
             rspeak(spk);
             return GO_CLEAROBJ;
         } else {
@@ -131,9 +132,9 @@ static int bigwords(token_t foo)
                 game.prop[TROLL] = 1;
             k = 2;
             if (HERE(EGGS))k = 1;
-            if (game.loc == PLAC[EGGS])k = 0;
-            MOVE(EGGS, PLAC[EGGS]);
-            pspeak(EGGS, k);
+            if (game.loc == object_descriptions[EGGS].plac)k = 0;
+            MOVE(EGGS, object_descriptions[EGGS].plac);
+            pspeak(EGGS, look, k);
             return GO_CLEAROBJ;
         }
     }
@@ -176,7 +177,7 @@ 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 = ACTSPK[verb];
+    int spk = actspk[verb];
     if (obj == MIRROR)spk = TOO_FAR;
     if (obj == VASE && game.prop[VASE] == 0) {
         if (TOTING(VASE))DROP(VASE, game.loc);
@@ -304,7 +305,7 @@ static int chain(token_t verb)
     } else {
         spk = CHAIN_LOCKED;
         if (game.prop[CHAIN] != 0)spk = ALREADY_LOCKED;
-        if (game.loc != PLAC[CHAIN])spk = NO_LOCKSITE;
+        if (game.loc != object_descriptions[CHAIN].plac)spk = NO_LOCKSITE;
         if (spk != CHAIN_LOCKED) {
             rspeak(spk);
             return GO_CLEAROBJ;
@@ -322,7 +323,7 @@ static int discard(token_t verb, token_t obj, bool just_do_it)
  *  bird (might attack snake or dragon) and cage (might contain bird) and vase.
  *  Drop coins at vending machine for extra batteries. */
 {
-    int spk = ACTSPK[verb];
+    int spk = actspk[verb];
     if (!just_do_it) {
         if (TOTING(ROD2) && obj == ROD && !TOTING(ROD))obj = ROD2;
         if (!TOTING(obj)) {
@@ -349,14 +350,14 @@ static int discard(token_t verb, token_t obj, bool just_do_it)
                 if (spk != RUG_WIGGLES) {
                     int k = 2 - game.prop[RUG];
                     game.prop[RUG] = k;
-                    if (k == 2) k = PLAC[SAPPH];
+                    if (k == 2) k = object_descriptions[SAPPH].plac;
                     MOVE(RUG + NOBJECTS, k);
                 }
             }
         } else if (obj == COINS && HERE(VEND)) {
             DESTROY(COINS);
             DROP(BATTERY, game.loc);
-            pspeak(BATTERY, FRESH_BATTERIES);
+            pspeak(BATTERY, look, FRESH_BATTERIES);
             return GO_CLEAROBJ;
         } else if (obj == BIRD && AT(DRAGON) && game.prop[DRAGON] == 0) {
             rspeak(BIRD_BURNT);
@@ -366,16 +367,16 @@ static int discard(token_t verb, token_t obj, bool just_do_it)
             rspeak(TROLL_SCAMPERS);
             MOVE(TROLL, 0);
             MOVE(TROLL + NOBJECTS, 0);
-            MOVE(TROLL2, PLAC[TROLL]);
-            MOVE(TROLL2 + NOBJECTS, FIXD[TROLL]);
+            MOVE(TROLL2, object_descriptions[TROLL].plac);
+            MOVE(TROLL2 + NOBJECTS, object_descriptions[TROLL].fixd);
             JUGGLE(CHASM);
             game.prop[TROLL] = 2;
-        } else if (obj != VASE || game.loc == PLAC[PILLOW]) {
+        } else if (obj != VASE || game.loc == object_descriptions[PILLOW].plac) {
             rspeak(OK_MAN);
         } else {
             game.prop[VASE] = 2;
             if (AT(PILLOW))game.prop[VASE] = 0;
-            pspeak(VASE, game.prop[VASE] + 1);
+            pspeak(VASE, look, game.prop[VASE] + 1);
             if (game.prop[VASE] != 0)game.fixed[VASE] = -1;
         }
     }
@@ -397,7 +398,7 @@ 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 = ACTSPK[verb];
+    int spk = actspk[verb];
     if (obj == 0 && LIQLOC(game.loc) != WATER && (LIQUID() != WATER || !HERE(BOTTLE)))
         return GO_UNKNOWN;
     if (obj != BLOOD) {
@@ -410,7 +411,7 @@ static int drink(token_t verb, token_t obj)
     } else {
         DESTROY(BLOOD);
         game.prop[DRAGON] = 2;
-        OBJSND[BIRD] = OBJSND[BIRD] + 3;
+        game.blooded = true;
         spk = HEAD_BUZZES;
     }
     rspeak(spk);
@@ -421,7 +422,7 @@ 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 = ACTSPK[verb];
+    int spk = actspk[verb];
     if (obj == INTRANSITIVE) {
         if (!HERE(FOOD))
             return GO_UNKNOWN;
@@ -443,7 +444,7 @@ 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 = ACTSPK[verb];
+    int spk = actspk[verb];
     if (obj == INTRANSITIVE) {
         if (HERE(LAMP) && game.prop[LAMP] == LAMP_BRIGHT)
            obj = LAMP;
@@ -468,7 +469,7 @@ 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 = ACTSPK[verb];
+    int spk = actspk[verb];
     if (obj == BIRD) {
         rspeak(BIRD_PINING);
         return GO_CLEAROBJ;
@@ -510,7 +511,7 @@ int fill(token_t verb, token_t obj)
  *  is nasty.) */
 {
     int k;
-    int spk = ACTSPK[verb];
+    int spk = actspk[verb];
     if (obj == VASE) {
         spk = ARENT_CARRYING;
         if (LIQLOC(game.loc) == 0)spk = FILL_INVALID;
@@ -568,7 +569,7 @@ int fill(token_t verb, token_t obj)
 static int find(token_t verb, token_t obj)
 /* Find.  Might be carrying it, or it might be here.  Else give caveat. */
 {
-    int spk = ACTSPK[verb];
+    int spk = actspk[verb];
     if (AT(obj) ||
         (LIQUID() == obj && AT(BOTTLE)) ||
         obj == LIQLOC(game.loc) ||
@@ -583,7 +584,7 @@ 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 = ACTSPK[verb];
+    int spk = actspk[verb];
     if (obj == INTRANSITIVE) {
         if (game.prop[RUG] != 2)spk = RUG_NOTHING2;
         if (!HERE(RUG))spk = FLAP_ARMS;
@@ -623,7 +624,7 @@ static int inven(void)
         if (spk == NO_CARRY)
             rspeak(NOW_HOLDING);
         game.blklin = false;
-        pspeak(i, -1);
+        pspeak(i, touch, -1);
         game.blklin = true;
         spk = NO_MESSAGE;
     }
@@ -636,7 +637,7 @@ static int inven(void)
 static int light(token_t verb, token_t obj)
 /*  Light.  Applicable only to lamp and urn. */
 {
-    int spk = ACTSPK[verb];
+    int spk = actspk[verb];
     if (obj == INTRANSITIVE) {
         if (HERE(LAMP) && game.prop[LAMP] == LAMP_DARK && game.limit >= 0)
            obj = LAMP;
@@ -685,11 +686,15 @@ static int listen(void)
            spk = NO_MESSAGE;
     }
     for (int i = 1; i <= NOBJECTS; i++) {
-        if (!HERE(i) || OBJSND[i] == 0 || game.prop[i] < 0)
+        if (!HERE(i) || object_descriptions[i].sounds[0] == NULL || game.prop[i] < 0)
             continue;
-        pspeak(i, OBJSND[i] + game.prop[i], game.zzword);
+       int mi =  game.prop[i];
+       if (i == BIRD)
+           mi += 3 * game.blooded;
+        pspeak(i, hear, mi, game.zzword);
         spk = NO_MESSAGE;
-        if (i == BIRD && OBJSND[i] + game.prop[i] == 8)
+       /* FIXME: Magic number, sensitive to bird state logic */
+       if (i == BIRD && game.prop[i] == 5)
             DESTROY(BIRD);
     }
     rspeak(spk);
@@ -699,7 +704,7 @@ static int listen(void)
 static int lock(token_t verb, token_t obj)
 /* Lock, unlock, no object given.  Assume various things if present. */
 {
-    int spk = ACTSPK[verb];
+    int spk = actspk[verb];
     if (obj == INTRANSITIVE) {
         spk = NOTHING_LOCKED;
         if (HERE(CLAM))obj = CLAM;
@@ -745,7 +750,7 @@ 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 = ACTSPK[verb];
+    int spk = actspk[verb];
     if (obj == BOTTLE || obj == 0)obj = LIQUID();
     if (obj == 0) return GO_UNKNOWN;
     if (!TOTING(obj)) {
@@ -772,7 +777,7 @@ static int pour(token_t verb, token_t obj)
             rspeak(spk);
             return GO_CLEAROBJ;
         }
-        pspeak(PLANT, game.prop[PLANT] + 3);
+        pspeak(PLANT, look, game.prop[PLANT] + 3);
         game.prop[PLANT] = MOD(game.prop[PLANT] + 1, 3);
         game.prop[PLANT2] = game.prop[PLANT];
         return GO_MOVE;
@@ -799,7 +804,7 @@ static int read(struct command_t command)
     if (command.obj == INTRANSITIVE) {
         command.obj = 0;
         for (int i = 1; i <= NOBJECTS; i++) {
-            if (HERE(i) && OBJTXT[i] != 0 && game.prop[i] >= 0)
+            if (HERE(i) && object_descriptions[i].texts[0] != NULL && game.prop[i] >= 0)
                 command.obj = command.obj * NOBJECTS + i;
         }
         if (command.obj > NOBJECTS || command.obj == 0 || DARK(game.loc))
@@ -808,12 +813,12 @@ static int read(struct command_t command)
 
     if (DARK(game.loc)) {
         rspeak(NO_SEE, command.wd1, command.wd1x);
-    } else if (OBJTXT[command.obj] == 0 || game.prop[command.obj] < 0) {
-        rspeak(ACTSPK[command.verb]);
-    } else if (command.obj == OYSTER && !game.clshnt) {
+    } else if (command.obj == OYSTER && !game.clshnt && game.closed) {
         game.clshnt = YES(arbitrary_messages[CLUE_QUERY], arbitrary_messages[WAYOUT_CLUE], arbitrary_messages[OK_MAN]);
+    } else if (object_descriptions[command.obj].texts[0] == NULL || game.prop[command.obj] < 0) {
+        rspeak(actspk[command.verb]);
     } else
-        pspeak(command.obj, OBJTXT[command.obj] + game.prop[command.obj]);
+        pspeak(command.obj, study, game.prop[command.obj]);
     return GO_CLEAROBJ;
 }
 
@@ -824,7 +829,7 @@ static int reservoir(void)
         rspeak(NOTHING_HAPPENS);
         return GO_CLEAROBJ;
     } else {
-        pspeak(RESER, game.prop[RESER] + 1);
+        pspeak(RESER, look, game.prop[RESER] + 1);
         game.prop[RESER] = 1 - game.prop[RESER];
         if (AT(RESER))
             return GO_CLEAROBJ;
@@ -840,7 +845,7 @@ static int reservoir(void)
 static int rub(token_t verb, token_t obj)
 /* Rub.  Yields various snide remarks except for lit urn. */
 {
-    int spk = ACTSPK[verb];
+    int spk = actspk[verb];
     if (obj != LAMP)
         spk = PECULIAR_NOTHING;
     if (obj == URN && game.prop[URN] == 2) {
@@ -888,20 +893,20 @@ static int throw (FILE *cmdin, struct command_t *command)
  *  (Only way to do so!)  Axe also special for dragon, bear, and
  *  troll.  Treasures special for troll. */
 {
-    int spk = ACTSPK[command->verb];
+    int spk = actspk[command->verb];
     if (TOTING(ROD2) && command->obj == ROD && !TOTING(ROD))command->obj = ROD2;
     if (!TOTING(command->obj)) {
         rspeak(spk);
         return GO_CLEAROBJ;
     }
-    if (command->obj >= MINTRS && command->obj <= MAXTRS && AT(TROLL)) {
+    if (object_descriptions[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(TROLL2, PLAC[TROLL]);
-        DROP(TROLL2 + NOBJECTS, FIXD[TROLL]);
+        DROP(TROLL2, object_descriptions[TROLL].plac);
+        DROP(TROLL2 + NOBJECTS, object_descriptions[TROLL].fixd);
         JUGGLE(CHASM);
         rspeak(spk);
         return GO_CLEAROBJ;
@@ -950,7 +955,7 @@ static int wake(token_t verb, token_t obj)
 /* Wake.  Only use is to disturb the dwarves. */
 {
     if (obj != DWARF || !game.closed) {
-        rspeak(ACTSPK[verb]);
+        rspeak(actspk[verb]);
         return GO_CLEAROBJ;
     } else {
         rspeak(PROD_DWARF);
@@ -961,7 +966,7 @@ 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 = ACTSPK[verb];
+    int spk = actspk[verb];
     if ((!TOTING(obj)) && (obj != ROD || !TOTING(ROD2)))spk = ARENT_CARRYING;
     if (obj != ROD ||
         !TOTING(obj) ||
@@ -990,7 +995,7 @@ static int wave(token_t verb, token_t obj)
         }
         if (HERE(BIRD))rspeak(spk);
         game.prop[FISSURE] = 1 - game.prop[FISSURE];
-        pspeak(FISSURE, 2 - game.prop[FISSURE]);
+        pspeak(FISSURE, look, 2 - game.prop[FISSURE]);
         return GO_CLEAROBJ;
     }
 }
@@ -1000,7 +1005,7 @@ int action(FILE *input, struct command_t *command)
  *  unless verb is "say", which snarfs arbitrary second word.
  */
 {
-    token_t spk = ACTSPK[command->verb];
+    token_t spk = actspk[command->verb];
 
     if (command->part == unknown) {
         /*  Analyse an object word.  See if the thing is here, whether