Refactored discard to concentrate bird-related things in one place
[open-adventure.git] / actions.c
index cb034d16605a98205aec8ce92c9b781a3bb62833..be822c8083493c44c4201c29933620fd9e3eb632 100644 (file)
--- a/actions.c
+++ b/actions.c
@@ -311,40 +311,35 @@ static int vcarry(verb_t verb, obj_t obj)
     }
 
     if (game.fixed[obj] != IS_FREE) {
-        /* Next guard tests whether plant is tiny or stashed */
-        if (obj == PLANT && game.prop[PLANT] <= PLANT_THIRSTY) {
-            rspeak(DEEP_ROOTS);
-            return GO_CLEAROBJ;
-        }
-        if (obj == BEAR && game.prop[BEAR] == SITTING_BEAR) {
-            rspeak(BEAR_CHAINED);
-            return GO_CLEAROBJ;
-        }
-        if (obj == CHAIN && game.prop[BEAR] != UNTAMED_BEAR) {
-            rspeak(STILL_LOCKED);
-            return GO_CLEAROBJ;
-        }
-        if (obj == URN) {
+        switch (obj) {
+        case PLANT:
+            /* Next guard tests whether plant is tiny or stashed */
+            rspeak(game.prop[PLANT] <= PLANT_THIRSTY ? DEEP_ROOTS : YOU_JOKING);
+            break;
+        case BEAR:
+            rspeak( game.prop[BEAR] == SITTING_BEAR ? BEAR_CHAINED : YOU_JOKING);
+            break;
+        case CHAIN:
+            rspeak( game.prop[BEAR] != UNTAMED_BEAR ? STILL_LOCKED : YOU_JOKING);
+            break;
+        case RUG:
+            rspeak(game.prop[RUG] == RUG_HOVER ? RUG_HOVERS : YOU_JOKING);
+            break;
+        case URN:
             rspeak(URN_NOBUDGE);
-            return GO_CLEAROBJ;
-        }
-        if (obj == CAVITY) {
+            break;
+        case CAVITY:
             rspeak(DOUGHNUT_HOLES);
-            return GO_CLEAROBJ;
-        }
-        if (obj == BLOOD) {
+            break;
+        case BLOOD:
             rspeak(FEW_DROPS);
-            return GO_CLEAROBJ;
-        }
-        if (obj == RUG && game.prop[RUG] == RUG_HOVER) {
-            rspeak(RUG_HOVERS);
-            return GO_CLEAROBJ;
-        }
-        if (obj == SIGN) {
+            break;
+        case SIGN:
             rspeak(HAND_PASSTHROUGH);
-            return GO_CLEAROBJ;
+            break;
+        default:
+            rspeak(YOU_JOKING);
         }
-        rspeak(YOU_JOKING);
         return GO_CLEAROBJ;
     }
 
@@ -352,14 +347,14 @@ static int vcarry(verb_t verb, obj_t obj)
         obj == OIL) {
         if (!HERE(BOTTLE) ||
             LIQUID() != obj) {
-            if (TOTING(BOTTLE)) {
-                if (game.prop[BOTTLE] == EMPTY_BOTTLE) {
-                    return (fill(verb, BOTTLE));
-                } else if (game.prop[BOTTLE] != EMPTY_BOTTLE)
-                    rspeak(BOTTLE_FULL);
+            if (!TOTING(BOTTLE)) {
+                rspeak(NO_CONTAINER);
                 return GO_CLEAROBJ;
             }
-            rspeak(NO_CONTAINER);
+            if (game.prop[BOTTLE] == EMPTY_BOTTLE) {
+                return (fill(verb, BOTTLE));
+            } else
+                rspeak(BOTTLE_FULL);
             return GO_CLEAROBJ;
         }
         obj = BOTTLE;
@@ -389,12 +384,16 @@ static int vcarry(verb_t verb, obj_t obj)
     }
     if ((obj == BIRD ||
          obj == CAGE) &&
-        (game.prop[BIRD] == BIRD_CAGED || STASHED(BIRD) == BIRD_CAGED))
+        (game.prop[BIRD] == BIRD_CAGED || STASHED(BIRD) == BIRD_CAGED)) {
         /* expression maps BIRD to CAGE and CAGE to BIRD */
         carry(BIRD + CAGE - obj, game.loc);
+    }
+
     carry(obj, game.loc);
+
     if (obj == BOTTLE && LIQUID() != NO_OBJECT)
         game.place[LIQUID()] = CARRIED;
+
     if (GSTONE(obj) && game.prop[obj] != STATE_FOUND) {
         game.prop[obj] = STATE_FOUND;
         game.prop[CAVITY] = CAVITY_EMPTY;
@@ -460,21 +459,16 @@ static int discard(verb_t verb, obj_t obj)
  *  bird (might attack snake or dragon) and cage (might contain bird) and vase.
  *  Drop coins at vending machine for extra batteries. */
 {
-    if (TOTING(ROD2) && obj == ROD && !TOTING(ROD))
+    if (obj == ROD && !TOTING(ROD) && TOTING(ROD2)) {
         obj = ROD2;
+    }
+
     if (!TOTING(obj)) {
         speak(actions[verb].message);
         return GO_CLEAROBJ;
     }
-    if (obj == BIRD && HERE(SNAKE)) {
-        rspeak(BIRD_ATTACKS);
-        if (game.closed)
-            return GO_DWARFWAKE;
-        DESTROY(SNAKE);
-        /* Set game.prop for use by travel options */
-        game.prop[SNAKE] = SNAKE_CHASED;
 
-    } else if ((GSTONE(obj) && AT(CAVITY) && game.prop[CAVITY] != CAVITY_FULL)) {
+    if (GSTONE(obj) && AT(CAVITY) && game.prop[CAVITY] != CAVITY_FULL) {
         rspeak(GEM_FITS);
         game.prop[obj] = STATE_IN_CAVITY;
         game.prop[CAVITY] = CAVITY_FULL;
@@ -494,45 +488,75 @@ static int discard(verb_t verb, obj_t obj)
                 move(RUG + NOBJECTS, k);
             }
         }
-    } else if (obj == COINS && HERE(VEND)) {
+        drop(obj, game.loc);
+        return GO_CLEAROBJ;
+    }
+
+    if (obj == COINS && HERE(VEND)) {
         DESTROY(COINS);
         drop(BATTERY, game.loc);
         pspeak(BATTERY, look, FRESH_BATTERIES, true);
         return GO_CLEAROBJ;
-    } else if (obj == BIRD && AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) {
-        rspeak(BIRD_BURNT);
-        DESTROY(BIRD);
-        return GO_CLEAROBJ;
-    } else if (obj == BEAR && AT(TROLL)) {
+    }
+
+    if (LIQUID() == obj)
+        obj = BOTTLE;
+    if (obj == BOTTLE && LIQUID() != NO_OBJECT) {
+        game.place[LIQUID()] = LOC_NOWHERE;
+    }
+
+    if (obj == BEAR && AT(TROLL)) {
         state_change(TROLL, TROLL_GONE);
         move(TROLL, LOC_NOWHERE);
         move(TROLL + NOBJECTS, IS_FREE);
         move(TROLL2, objects[TROLL].plac);
         move(TROLL2 + NOBJECTS, objects[TROLL].fixd);
         juggle(CHASM);
-    } else if (obj != VASE ||
-               game.loc == objects[PILLOW].plac) {
-        rspeak(OK_MAN);
-    } else {
-        state_change(VASE, AT(PILLOW)
-                     ? VASE_WHOLE
-                     : VASE_DROPPED);
-        if (game.prop[VASE] != VASE_WHOLE)
-            game.fixed[VASE] = IS_FIXED;
+        drop(obj, game.loc);
+        return GO_CLEAROBJ;
     }
-    int k = LIQUID();
-    if (k == obj)
-        obj = BOTTLE;
-    if (obj == BOTTLE && k != NO_OBJECT)
-        game.place[k] = LOC_NOWHERE;
-    if (obj == CAGE && game.prop[BIRD] == BIRD_CAGED)
+
+    if (obj == VASE) {
+        if (game.loc != objects[PILLOW].plac) {
+            state_change(VASE, AT(PILLOW)
+                         ? VASE_WHOLE
+                         : VASE_DROPPED);
+            if (game.prop[VASE] != VASE_WHOLE)
+                game.fixed[VASE] = IS_FIXED;
+            drop(obj, game.loc);
+            return GO_CLEAROBJ;
+        }
+    }
+
+    if (obj == CAGE && game.prop[BIRD] == BIRD_CAGED) {
         drop(BIRD, game.loc);
-    drop(obj, game.loc);
-    if (obj != BIRD)
+    }
+
+    if (obj == BIRD) {
+        if (AT(DRAGON) && game.prop[DRAGON] == DRAGON_BARS) {
+            rspeak(BIRD_BURNT);
+            DESTROY(BIRD);
+            return GO_CLEAROBJ;
+        }
+        if (HERE(SNAKE)) {
+            rspeak(BIRD_ATTACKS);
+            if (game.closed)
+                return GO_DWARFWAKE;
+            DESTROY(SNAKE);
+            /* Set game.prop for use by travel options */
+            game.prop[SNAKE] = SNAKE_CHASED;
+        } else
+            rspeak(OK_MAN);
+
+        game.prop[BIRD] = BIRD_UNCAGED;
+        if (FOREST(game.loc))
+            game.prop[BIRD] = BIRD_FOREST_UNCAGED;
+        drop(obj, game.loc);
         return GO_CLEAROBJ;
-    game.prop[BIRD] = BIRD_UNCAGED;
-    if (FOREST(game.loc))
-        game.prop[BIRD] = BIRD_FOREST_UNCAGED;
+    }
+
+    rspeak(OK_MAN);
+    drop(obj, game.loc);
     return GO_CLEAROBJ;
 }