
themes {
   custom: theme {

      theme_settings {
         layout = "G H D O"
         parser_delay = 0
      }

   }
}

game_information {
   game_name                    = Escape from the MV Capricorn
   game_version                 = 1.0.0
   game_shortname               = EscCap
   written_by                   = FLACRabbit
   uuid                         = ce26f920-8bfa-4394-b275-cefe710876e3
   year_of_release              = 2026
}

game_settings {
   rollback_enabled = true
   rewind_enabled = true
   auto_pluralize_nouns = false
}

start_at = goat_box

locations {
   goat_box: location {
      header = "Goat Box"
      on_describe {
         : if (highlighting) {
            : print "This place is like a container home \(you heard about those on a TV show\), except without the \"home\" part. It's a single rectangular room with drab walls, incandescent lights, and a single <door<#f80>> to the west. Maybe that show biased your expectations, but there isn't even a home theater.\nAll you can see is a <pile of straw<#f80>>, a <stack of books<#f80>>, and a <refrigerator<#f80>>.";
         }
         : else {
            : print "This place is like a container home \(you heard about those on a TV show\), except without the \"home\" part. It's a single rectangular room with drab walls, incandescent lights, and a single door to the west. Maybe that show biased your expectations, but there isn't even a home theater.\nAll you can see is a pile of straw, a stack of books, and a refrigerator.";
         }
      }
   }

   container_stacks: location {
      header="Container Stacks"
      graphic="containers"
      on_describe {
        : if (highlighting) {
            : print "You're standing on piles of shipping <containers<#f80>>. This steep, uneven terrain seems to have awakened some ancient instincts in you. It reminds you of Mediterranean mountains, covered with craggy rocks and scraggly bushes, even though you've never been there.\nThe container that you were penned up in is to the east.";
         }
         : else {
            : print "You're standing on piles of shipping containers. This steep, uneven terrain seems to have awakened some ancient instincts in you. It reminds you of Mediterranean mountains, covered with craggy rocks and scraggly bushes, even though you've never been there.\nThe container that you were penned up in is to the east.";
         }
      }
   }

   main_deck: location "You're on the main deck of the ship. A door to the interior lies to the west, and the stacks of containers rise to the east. The cargo crane towers above you to the north, with a short flight of stairs leading to its cabin." header="Main Deck";

   control_cabin: location {
      header="Crane Control Cabin"
      graphic="ship_base"
      on_describe {
         : if (highlighting) {
            : print "This dusty, glass-windowed cabin inside the crane's superstructure contains its controls, the most obvious ones being a <left lever<#f80>>, a <right lever<#f80>>, a <button<#f80>> marked \"LOWER\", and a <button<#f80>> marked \"RAISE\". There's also a computerized <display<#f80>> that reminds you of some of those stupid 1980s TV shows. Stairs lead back down to the main deck to the south.";
         }
         : else {
            : print "This dusty, glass-windowed cabin inside the crane's superstructure contains its controls, the most obvious ones being a left lever, a right lever, a button marked \"LOWER\", and a button marked \"RAISE\". There's also a computerized display that reminds you of some of those stupid 1980s TV shows. Stairs lead back down to the main deck to the south.";
         }
      }
   }

   crane_boom: location "It's exhilarating up here, balancing precariously on top of the shipboard crane's boom. You climbed up from the east, but the boom extends a long way west, nearly reaching an upper deck." header="On the Boom";

   upper_deck: location {
      on_describe {
         : append "You're on a balcony-like upper deck of the ship. You got here by jumping off the back of the crane's boom to the east, but you don't think you could jump back up there. A door leads into the ship to the south";
         : if (is_beside "life_preserver" || is_beside "wicker_chair") {
            : if (is_beside "life_preserver" && is_beside "wicker_chair") {
               : if (highlighting) {
                  : append ", and you notice a few other things around: a <life preserver<#08f>>, a <wicker chair<#f80>>, and, most importantly, a <lifeboat<#f80>>!\n";
               }
               : else {
                  : append ", and you notice a few other things around: a life preserver, a wicker chair, and, most importantly, a lifeboat!\n";
               }
            }
            : else_if (is_beside "life_preserver") {
               : if (highlighting) {
                  : append ", and you notice a few other things around: a <life preserver<#08f>> and, more importantly, a <lifeboat<#f80>>!\n";
               }
               : else {
                  : append ", and you notice a few other things around: a life preserver and, more importantly, a lifeboat!\n";
               }
            }
            : else_if (is_beside "wicker_chair") {
               : if (highlighting) {
                  : append ", and you notice a few other things around: a <wicker chair<#f80>>, and, more importantly, a <lifeboat<#f80>>!\n";
               }
               : else {
                  : append ", and you notice a few other things around: a wicker chair, and, more importantly, a lifeboat!\n";
               }
            }
            : else {
               : if (highlighting) {
                  : append ", and you notice a few other things around: a <life preserver<#08f>>, a <wicker chair<#f80>>, and, most importantly, a <lifeboat<#f80>>!\n";
               }
               : else {
                  : append ", and you notice a few other things around: a life preserver, a wicker chair, and, most importantly, a lifeboat!\n";
               }
            }
         }
         : else {
            : if (highlighting) {
               : append ", and a <lifeboat<#f80>> on its launch ramp.\n";
            }
            : else {
               : append ", and a lifeboat on its launch ramp.\n";
            }
         }
      }
      header="Upper Deck"
   }

   staircase: location {
      on_describe {
         : append "This is the top of a long staircase that leads down and south into the ship. The sunlight coming in from the door in the north wall far outshines the fluorescent lights inside.";
         : if (is_beside "fire_extinguisher") {
            : if (highlighting) {
               : append " There's a <fire extinguisher<#f80>> in a recess in the wall.\n";
            }
            : else {
               : append " There's a fire extinguisher in a recess in the wall.\n";
            }
         }
         : else {
            : append "\n";
         }
      }
      header="Top of the Staircase";
   }
}

connections {
   from, direction, to = [
      goat_box, west, container_stacks
      main_deck, north, control_cabin
      upper_deck, south, staircase
   ]
}

on_startup {
   : print "You used to lead a pretty easy life. In exchange for solving a few logic puzzles every day in front of people wearing lab coats, you got free room and board! (And access to a TV.)\nOf course, that had to come to an end sometime. A few days ago they packed you into a shipping container - as if you were mere cargo! - and loaded you on a ship, mumbling something about an international neuroscience conference.\nThat doesn't sound very fun. Time to get out of here.";
   : press_any_key;
   : clear_screen;
   : print_graphic "title" ;
   : print "by FLACRabbit";
   : print "Release 1.0 (Aug 13 2026)";
   : print "Made with Adventuron 1.0.0 Beta 84";
   : press_any_key;
   : play_incidental "music_1";
}

vocabulary {
   : noun aliases=["liberty", "book"];
   : noun aliases=["sensor", "sensors", "label", "labels", "box", "boxes"];
   : noun aliases=["saw", "hacksaw"];
   : noun aliases=["deadbolt", "bolt", "lock", "bar"];
   : noun aliases=["refrigerator", "fridge"];
   : noun aliases=["liberty", "note"];
   : noun aliases=["container", "containers", "ring", "rings"];
   : noun aliases=["lifeboat", "boat"];
   : noun aliases=["crane", "boom", "beam", "beams"];
   : noun aliases=["preserver", "lifesaver", "saver", "buoy", "lifebuoy"];
   : noun aliases=["sun", "sky"];
   : noun aliases=["sea", "ocean"];
   : noun aliases=["light", "lights"];
   : noun aliases=["display", "computer", "readout"];

   : adjective aliases=["shipping", "cargo", "purple"];
   : adjective aliases=["metal", "steel"];
   : adjective aliases=["copy", "sticky"];
   : adjective aliases=["blue", "Atlantic"];

   : verb aliases=["go", "walk", "trot", "canter", "strut"];
   : verb aliases=["saw", "cut", "sever"];
   : verb aliases=["break", "smash", "hit", "attack", "destroy"];
   : verb aliases=["examine", "search"];
   : verb aliases=["push", "press"];
   : verb aliases=["attach", "hook", "put", "tie", "connect", "fasten", "secure"];
   : verb aliases=["enter", "climb", "sit"];
   : verb aliases=["eat", "bite", "gnaw"];
   : verb aliases=["drop", "throw"];
   : verb aliases=["put", "pass", "place"];

   : verb aliases=["highlight", "highlighting"];
}

objects {
   // Goat box
   pile_straw: scenery "a pile of straw" listed="false" at="goat_box" msg="You're supposed to sleep here, as if it were any kind of substitute for a bed. Preferably queen-sized at least.";
   stack_books: scenery "a stack of books" listed="false" at="goat_box" msg="Hobbes, Hume, Kant, Marx... you've seen all of these guys before.";
   copy_liberty: object "\'On Liberty\' by John Stuart Mill" listed="false" msg="It's a thick hardcover copy of \'On Liberty\' by John Stuart Mill. There's a sticky note on the cover with a message from Dr. Walker, scrawled in red pen: \'I hope you find this as freeing as I think you will.\'";
   metal_hacksaw: object "a hacksaw" msg="It's a small steel hacksaw, brand new. You think you can manipulate it with your mouth.";
   container_door: scenery "the door" listed="false" at="goat_box";
   black_sensor: scenery "the sensor" listed="false" at="goat_box" msg="If you had to guess, you'd say it would detect when the door was opened and alert someone. There's a warning label on it: \"CAUTION! Risk of electric shock. Do not insert metal object. Device is not waterproof. Do not immerse in water. Do not leave unsupervised with goat.\"";
   deadbolt: scenery "the deadbolt" listed="false" at="goat_box" msg="You can just see light reflecting off of a metal bar inside the crack between the door and the frame, right next to the handel. It's a deadbolt lock, but there's no way to manipulate it from the inside.";
   small_refrigerator: scenery "the refrigerator" listed="false" at="goat_box" msg="It's a small refrigerator, like they have in hotel rooms (at least in TV shows). The scientists put enough food and water in here to last you for the whole journey. If you open it you cn see what's inside.";
   tofu: scenery "some blocks of tofu" listed="false" msg="You used to like tofu, until about the third week of the journey.";
   bottled_water: scenery "some bottled water" listed="false" msg="There are still a few dozen plastic water bottles in the fridge.";
   water_bottle: object "a bottle of water" msg="It's a cheap bottle of water, with some Photoshopped mountain on the label.";
   incandescent_lights: scenery "the lights" listed="false" at="goat_box" msg="The yellowish light is depressing.";

   // Container stacks
   stacks_door: scenery "the door" listed="false" at="container_stacks" msg="That's the door in the front of the goat box.";
   crane_hook: scenery "the crane's hook" listed="false" msg="This thick steel hook is attached to the crane's cable.";
   crane: scenery "the crane's boom" listed="false" msg="The crane's boom is extended over the stacks of containers.";
   purple_containers: scenery "the containers" listed="false" at="container_stacks" msg="All kinds of containers are piled up here, varying in color and how worn they look. Each one has a ring on top to allow it to be lifted by crane.";

   // Main deck
   deck_door: scenery "the door to the interior" listed="false" at="main_deck" msg="It's a heavy, metal-rimmed door that leads into the interior of the ship.";

   // Crane control cabin

   left_lever: scenery "the left lever" listed="false" at="control_cabin" msg="It's a lever that you could PULL with your hooves.";
   right_lever: scenery "the right lever" listed="false" at="control_cabin" msg="It's a lever that you could PULL with your hooves.";
   raise_button: scenery "the button labeled 'RAISE'" listed="false" at="control_cabin" msg="It's a large round button with faded white lettering underneath: 'RAISE'. Probably it raises the hook.";
   lower_button: scenery "the button labeled 'LOWER'" listed="false" at="control_cabin" msg="It's a large round button with faded white lettering underneath: 'LOWER'. Probably it lowers the hook.";
   display: scenery "the computerized display" listed="false" at="control_cabin";

   // Upper deck and staircase (endgame)

   dr_walker: scenery "Dr. Walker" listed="false" msg="Dr. Walker is a fat, balding, good-hearted neurosurgeon. His thick glasses give him the look of a mad scientist from a TV show. He was your favorite of the experimenters who interacted with you back at the lab.";
   dr_beech: scenery "Dr. Beech" listed="false" at="staircase" msg="Dr. Beech is a gray-haired man with a square jawline and beady eyes. Supposedly he's one of the world's greatest neurobiologists, and he never got tired of telling you that you should be grateful to him for developing the neural growth serum you were injected with.";
   captain: scenery "the Captain" listed="false" at="staircase" msg="The Captain of the ship is a blond-haired, blue-eyed German wearing a sailor's hat. His mouth has a bit of a pouty look.";
   security_guard: scenery "the security guard" listed="false" at="staircase" msg="The MV Capricorn apparently employs this burly, stubbly guy as a security guard, probably in case of a pirate attack.";

   wicker_chair: scenery "a wicker deck chair" listed="false" at="upper_deck" msg="It's a cheap wicker chair on the deck here. It looks light enough that you could push it from place to place.";
   life_preserver: object "a life preserver" listed="false" at="upper_deck" msg="A regulation life preserver ring, painted red and white, is hanging in a bracket on the railing. You think you could grab it with your horns.";
   fire_extinguisher: scenery "a fire extinguisher" listed="false" at="staircase";
   extinguisher_ring: scenery "the fire extinguisher's ring" listed="false" at="staircase" msg="According to the label, pulling out this ring should make it possible to activate the fire extinguisher.";
   life_lifeboat: scenery "the lifeboat" listed="false" at="upper_deck" msg="It's a small motorboat on a launch ramp. Ordinarily, it's held in place by four ropes which are supposed to be released automatically when the release lever is pulled.";
   four_ropes: scenery "the ropes" listed="false" at="upper_deck";


   // Backdrops

   backdrop_crane: scenery "the crane" adjective="shipboard" listed="false" msg="The shipboard crane rises to about the same level as the upper deck, which is even further aft.";
   backdrop_sea: scenery "the sea" adjective="blue" listed="false" msg="The Atlantic Ocean rolls slowly by.";
   backdrop_sky: scenery "the sky" adjective="blue" listed="false" msg="It's pale blue.";
   backdrop_containers: scenery "the containers" adjective="shipping" listed="false" msg="Tons of containers are stacked up on the fore two-thirds of the ship.";


}

booleans {
   noun_is_manipulable: boolean;
   second_noun_is_manipulable: boolean;

   door_is_locked: boolean "true";
   door_is_open: boolean "false";
   sensor_is_broken: boolean "false";

   crane_lowered: boolean "false";
   crane_box_attached: boolean "false";
   on_raised_box: boolean "false";

   occluded: boolean "false";

   commotion_happening: boolean "false";
   commotion_happened: boolean "false";

   time_taken: boolean "false";

   endgame_first_hint: boolean "false";
   endgame_second_hint: boolean "false";
   sensor_first_hint: boolean "false";

   highlighting: boolean "false";
}

integers {
   current_x: integer "4";
   current_y: integer "2";
   current_height: integer;
   destination_x: integer;
   destination_y: integer;
   destination_height: integer;
   move_dx: integer;
   move_dy: integer;

   crane_angle: integer "-1";

   commotion_turns: integer "0";

   climax_turns: integer "0";
   climax_enemy_progress: integer "0";
}

strings {
   move_direction: string "";
}

collections {
   objects_in_current_location: set;
   objects_in_inventory: set;
   manipulable_objects: set;
   extended_scope: set;

   // current_y0_height: list items=[3, 3, 0, 0, 0];
   // current_y1_height: list items=[2, 4, 5, 0, 0];
   // current_y2_height: list items=[1, 2, 6, 4, 3];
   // current_y3_height: list items=[1, 0, 1, 2, 0];

   containers_height: list items=[3, 3, 0, 0, 0, 2, 4, 5, 0, 0, 1, 2, 6, 4, 3, 1, 0, 1, 2, 0];

   time_consuming_verbs: set items=["take", "drop", "push", "pull", "n", "north", "s", "south", "e", "east", "w", "west", "go", "enter", "up", "attach", "wait"];

   containers_exits: list;
}

traits {
   edible_t: trait;
}

on_command {
   // : mask {
   //    : if (1 == 1) {
   //       : print {("v: " + original "verb")};
   //       : print {("a1: " + original "adjective1")};
   //       : print {("n1: " + original "noun1")};
   //       : print {("p: " + original "preposition")};
   //       : print {("a2: " + original "adjective2")};
   //       : print {("n2: " + original "noun2")};
   //    }
   // }

   : if (verb_is "highlight" && (preposition_is "on" || (noun1_is "" && noun2_is "" && preposition_is ""))) {
      : print "<[[Object highlighting is now turned ON. Use >>HIGHLIGHT OFF to turn it off again.]]<#ff0>>";
      : set_true "highlighting";
      : press_any_key;
      : redescribe;
   }
   : if (verb_is "highlight" && noun1_is "off") {
      : print "<[[Object highlighting is now turned OFF. Use >>HIGHLIGHT ON to turn it on again.]]<#ff0>>";
      : set_false "highlighting";
   }

   : match "exits" {
      : if (is_at "goat_box") {
         : if (door_is_open) {
            : print "You can go west now that the door is open.";
         }
         : else {
            : print "There's a door in the west wall, but it's closed.";
         }
      }
      : else_if (is_at "container_stacks") {
         : if (on_raised_box) {
            : print "From here, you could go back east to the tall stack of containers, or up onto the crane's boom.";
            : done;
         }

         : clear "containers_exits";

         : if (current_x == 0) {
            : if (current_height <= 2) {
               : collection_push { collection = "containers_exits" value -> ("west")};
            }
         }
         : else_if (current_x == 2 && current_y == 2 && !crane_lowered && crane_angle == 0 && crane_box_attached) {
            : collection_push { collection = "containers_exits" value -> ("west")};
         }
         : else {
            : set_integer var="destination_height" (int(collection_get {collection -> ("containers_height") index -> (current_y*5 + (current_x - 1))}));
            : if (destination_height >= current_height - 2 && destination_height <= current_height + 1) {
               : collection_push { collection = "containers_exits" value -> ("west")};
            }
         }

         : if (current_x < 4) {
            : set_integer var="destination_height" (int(collection_get {collection -> ("containers_height") index -> (current_y*5 + (current_x + 1))}));
            : if (destination_height >= current_height - 2 && destination_height <= current_height + 1) {
                  : collection_push { collection = "containers_exits" value -> ("east")};
            }
         }

         : if (current_y > 0) {
            : set_integer var="destination_height" (int(collection_get {collection -> ("containers_height") index -> ((current_y - 1)*5 + current_x)}));
            : if (destination_height >= current_height - 2 && destination_height <= current_height + 1) {
                  : collection_push { collection = "containers_exits" value -> ("north")};
            }
         }

         : if (current_y < 3) {
            : set_integer var="destination_height" (int(collection_get {collection -> ("containers_height") index -> ((current_y + 1)*5 + current_x)}));
            : if (destination_height >= current_height - 2 && destination_height <= current_height + 1) {
                  : collection_push { collection = "containers_exits" value -> ("south")};
            }
         }

         // this is stupid, but there's no built in list printing routine, and it's not worth making one and setting up all the appropriate globals just for this
         : if (count "containers_exits" == 1) {
            : print {("You can go " + collection_get { collection = "containers_exits" index->(0) } + " from this container.")};
         }
         : else_if (count "containers_exits" == 2) {
            : print {("You can go " + collection_get { collection = "containers_exits" index->(0) } + " or " + collection_get { collection = "containers_exits" index->(1) } + " from this container.")};
         }
         : else_if (count "containers_exits" == 3) {
            : print {("You can go " + collection_get { collection = "containers_exits" index->(0) } + ", " + collection_get { collection = "containers_exits" index->(1) } + " or " + collection_get { collection = "containers_exits" index->(2) } + " from this container.")};
         }
         : else_if (count "containers_exits" == 4) {
            : print {("You can go " + collection_get { collection = "containers_exits" index->(0) } + ", " + collection_get { collection = "containers_exits" index->(1) } + ", " + collection_get { collection = "containers_exits" index->(2) } + " or " + collection_get { collection = "containers_exits" index->(3) } + " from this container.")};
         }
      }
      : else_if (is_at "main_deck") {
         : print "You can go east (onto the containers) or north (into the crane control cabin).";
      }
      : else_if (is_at "control_cabin") {
         : print "The only way to go from here is south.";
      }
      : else_if (is_at "crane_boom") {
         : print "You can walk along the beam you're on to the west. The containers are back to the east, but there's no reason to go back there.";
      }
      : else_if (is_at "upper_deck") {
         : print "You can go south into the stairwell.";
      }
      : else_if (is_at "staircase") {
         : print "You can go north, back out onto the upper deck. The stairwell continues south, but you don't think you can get past the three men.";
      }
   }

   : if (original "noun1" == "bottle" && original "noun2" == "water") {
      : set_sentence {(original "verb" + " bottle")};
   }

   : match "examine me;examine myself" {
      : print "You glance over what you can see of your fur and hooves. All in order.";
      : done;
   }

   : if (original "noun1" == "me" || original "noun2" == "me") {
      : print "You don't need to refer to yourself in this game.";
      : done;
   }

   : if (is_at "control_cabin") {
      : match "examine display;read display" {
         : set_sentence "look";
      }
   }

   : if ((original "noun1" == "book") && !(is_present "copy_liberty") && (is_present "stack_books")) {
      : set_sentence {(original "verb" + " books")};
   }

   : if ((original "noun1" == "water") && (is_present "water_bottle")) {
      : set_sentence {(original "verb" + " bottle " + original "preposition" + " " + original "noun2")};
   }

   : if ((original "noun1" == "bottle") && (!is_present "water_bottle")) {
      : set_sentence {(original "verb" + " water " + original "preposition" + " " + original "noun2")};
   }

   : if (original "verb" == "get" && (original "preposition" == "in" || original "preposition" == "on")) {
      : set_sentence {("enter " + original "noun1")};
   }

   : if (original "verb" == "examine" && original "preposition" == "in" && (noun1_is "book" || noun1_is "fridge")) {
      : set_sentence {("open " + original "noun1")};
   }

   : if (original "verb" == "in" && original "noun1" == "" && original "noun2" == "") {
      : set_sentence "inwardify"; // there appears to be some built-in weirdness around >IN, because it seems to be interpreted as equivalent to >ENTER by verb_is, at which point the scope check asks you for a noun.
   }

   : if (is_at "control_cabin") {
      : if (original "noun1" == "left") {
         : set_sentence {(original "verb" + " left lever")};
      }
      : if (original "noun1" == "right") {
         : set_sentence {(original "verb" + " right lever")};
      }
      : if (original "noun1" == "raise") {
         : set_sentence {(original "verb" + " raise button")};
      }
      : if (original "noun1" == "lower") {
         : set_sentence {(original "verb" + " lower button")};
      }
   }

   : if (verb_is "push" && noun1_is "chair" && (original "noun2" == "south" || original "noun2" == "s" || original "noun2" == "west" || original "noun2" == "w" || original "noun2" == "east" || original "noun2" == "e" || original "noun2" == "north" || original "noun2" == "n" || original "noun2" == "southeast" || original "noun2" == "se" || original "noun2" == "southwest" || original "noun2" == "sw" || original "noun2" == "northeast" || original "noun2" == "ne" || original "noun2" == "northwest" || original "noun2" == "nw" || original "noun2" == "down" || original "noun2" == "d")) {
      : set_sentence {("push chair to " + original "noun2")};
   }

   : if ((verb_is "drop" || verb_is "push") && noun1_is "preserver" && (original "noun2" == "south" || original "noun2" == "s" || original "noun2" == "west" || original "noun2" == "w" || original "noun2" == "east" || original "noun2" == "e" || original "noun2" == "north" || original "noun2" == "n" || original "noun2" == "southeast" || original "noun2" == "se" || original "noun2" == "southwest" || original "noun2" == "sw" || original "noun2" == "northeast" || original "noun2" == "ne" || original "noun2" == "northwest" || original "noun2" == "nw" || original "noun2" == "down" || original "noun2" == "d")) {
      : set_sentence "drop preserver";
   }

   : match "port _" {
      : set_sentence "go north";
   }

   : match "starboard _" {
      : set_sentence "go south";
   }

   : match "fore _" {
      : set_sentence "go east";
   }

   : match "aft _" {
      : set_sentence "go west";
   }

   : match "sleep -" {
      : print "You just got up not too long ago.";
      : done;
   }

   : mask {
      : if (verb_is "examine" || verb_is "take" || verb_is "drop" || verb_is "read" || verb_is "open" || verb_is "close" || verb_is "saw" || verb_is "pour" || verb_is "break" || verb_is "sleep" || verb_is "drink" || verb_is "eat" || verb_is "pull" || verb_is "push" || verb_is "attach" || verb_is "enter" || verb_is "unlock" || verb_is "lock") {
         : disambiguate_s1 "present";
         : gosub "s1_scope_check";
      }
      : if (verb_is "saw" || verb_is "pour" || verb_is "attach") {
         : disambiguate_s2 "present";
         : gosub "s2_scope_check";
      }
   }

   : mask {
      : if (verb_is "take" && is_carried {(s1())}) {
         : print {("You already have " + definite(d(s1())) + ".")};
         : done;
      }
      : if (verb_is "take" && count "_inventory" > 0) {
         : print {("You're already carrying " + definite(d(one_of "_inventory")) + " in your mouth.")};
         : done;
      }
   }

   : match "examine books;read books" {
      : examine;
      : if (!is_exists "copy_liberty") {
         : if (highlighting) {
            : print "Actually, there is one book in there that you haven't read, though: '<On Liberty<#08f>>' by John Stuart Mill. You pull it out of the pile and set it to the side, noticing as you do so that there's a sticky note on the cover.";
         }
         : else {
            : print "Actually, there is one book in there that you haven't read, though: \'On Liberty\' by John Stuart Mill. You pull it out of the pile and set it to the side, noticing as you do so that there's a sticky note on the cover.";
         }
         : create "copy_liberty";
      }
   }

   : match "read liberty;open liberty" {
      : if (is_exists "metal_hacksaw") {
         : print "Suddenly, reading about liberty doesn't seem as appealing as actually attaining it.";
      }
      : else {
         : if (highlighting) {
            : print "You open \'On Liberty\' with your hooves and start at page 1. It's engrossing; the defense of individual freedom is rousing. But just as you're getting to the really good stuff like the critique of the assumption of infallibility, you're horrified to discover that the book has been mutilated! Someone sliced a rectangular section out of all the middle pages, for no reason - wait, there's a <hacksaw<#08f>> in there.\nYou've forgiven Dr. Walker immediately, and taken the hacksaw.";
         }
         : else {
            : print "You open \'On Liberty\' with your hooves and start at page 1. It's engrossing; the defense of individual freedom is rousing. But just as you're getting to the really good stuff like the critique of the assumption of infallibility, you're horrified to discover that the book has been mutilated! Someone sliced a rectangular section out of all the middle pages, for no reason - wait, there's a hacksaw in there.\nYou've forgiven Dr. Walker immediately, and taken the hacksaw.";
         }
         : create "metal_hacksaw" target="inventory";
         : if (is_carried "copy_liberty") {
            : create "copy_liberty";
         }
      }
   }

   : if (is_at "goat_box") {
      : match "out -;enter door;go door" {
         : set_sentence "west";
      }
   }

   : if (is_at "control_cabin") {
      : match "out -" {
         : set_sentence "south";
      }
   }

   : if (is_at "container_stacks") {
      : match "inwardify -;enter door;go door" {
         : if (current_x == 4 && current_y == 2) {
            : set_sentence "east";
         }
         : else {
            : print "You can't go in from here.";
            : done;
         }
      }
   }

   : if (is_at "main_deck") {
      : match "inwardify -;enter door;go door" {
         : set_sentence "west";
      }
   }

   : match "inwardify" {
      : print "You can't go that way.";
   }


   : if (is_at "goat_box") {
      : mask {
         : match "west _" {
            : if (!door_is_open) {
               : print "The door is closed.";
               : done;
            }
         }
      }
   }

   : match "open door" {
      : if (is_at "goat_box") {
         : if (door_is_open) {
            : print "It's already open.";
         }
         : else_if (door_is_locked) {
            : if (highlighting) {
               : print "You haul on the handle, but the door doesn't move at all. Looking closer, you see that it's locked from the outside with a thick <deadbolt<#f80>>, which you can glimpse between the door and its frame.";
            }
            : else {
               : print "You haul on the handle, but the door doesn't move at all. Looking closer, you see that it's locked from the outside with a thick deadbolt, which you can glimpse between the door and its frame.";
            }
         }
         : else {
            : if (sensor_is_broken) {
               : print "You hook your left horn through the handle and pull it open. To your relief, the sensor doesn't activate, and sunlight spills into the goat box.";
               : set_true "door_is_open";
            }
            : else {
               : print "You hesitate. You could open the door, but that sensor might alert the scientists that you escaped, and then you would be even worse off than you are now.";
            }
         }
      }
      : else_if (is_at "container_stacks") {
         : if (door_is_open) {
            : print "It's already open.";
         }
         : else {
            : print "You pull the door open again.";
            : set_true "door_is_open";
         }
      }
      : else_if (is_at "main_deck") {
         : set_sentence "west";
      }
   }

   : match "unlock door" {
      : if (is_at "container_stacks") {
         : print "There's no reason to mess with the lock on the door now.";
      }
      : else_if (is_at "goat_box") {
         : print "There's no way to manipulate the lock from this side. However, you can just barely see the deadbolt.";
      }
      : else_if (is_at "main_deck") {
         : print "The door to the interior doesn't have a lock as far as you can tell.";
      }
   }

   : match "lock door" {
      : if (is_at "container_stacks" || is_at "goat_box") {
         : print "There's no reason to try to lock the door.";
      }
      : else_if (is_at "main_deck") {
         : print "The door to the interior doesn't have a lock as far as you can tell.";
      }
   }

   : mask {
      : match "close door" {
         : if (is_at "goat_box" || is_at "container_stacks") {
            : print "There's no reason to close the door now - it would only slow you down.";
            : done;
         }
      }
   }

   // dynamic descriptions

   : if (verb_is "examine" && (s1() == "container_door" || s1() == "stacks_door")) {
      : if (door_is_open) {
         : print "The door is now hanging open.";
      }
      : else_if (door_is_locked && !sensor_is_broken) {
         : if (highlighting) {
            : print "Two things stand out about the door.\nThe first is the heavy <deadbolt<#f80>>, which glints in the crack between the door and the frame, near the handle. You're locked in.\nThe second is a pair of little black boxes - an electronic <sensor<#f80>> of some kind - the larger one attached to the frame and the smaller one attached to the door right next to it.";
         }
         : else {
            : print "Two things stand out about the door.\nThe first is the heavy deadbolt, which glints in the crack between the door and the frame, near the handle. You're locked in.\nThe second is a pair of little black boxes - an electronic sensor of some kind - the larger one attached to the frame and the smaller one attached to the door right next to it.";
         }
      }
      : else_if (door_is_locked && sensor_is_broken) {
         : if (highlighting) {
            : print "Two things stand out about the door.\nThe first is the heavy <deadbolt<#f80>>, which glints in the crack between the door and the frame, near the handle. You're locked in.\nThe second is an electronic sensor, although its standby LED is off, so you think it's broken.";
         }
         : else {
            : print "Two things stand out about the door.\nThe first is the heavy deadbolt, which glints in the crack between the door and the frame, near the handle. You're locked in.\nThe second is an electronic sensor, although its standby LED is off, so you think it's broken.";
         }
      }
      : else_if (!door_is_locked && !sensor_is_broken) {
         : if (highlighting) {
            : print "You've cut through the deadbolt, leaving a pile of metal filings on the ground.\nStill, there is a pair of little black boxes - an electronic <sensor<#f80>> of some kind - the large one attached to the frame and the smaller one attached to the door right next to it.";
         }
         : else {
            : print "You've cut through the deadbolt, leaving a pile of metal filings on the ground.\nStill, there is a pair of little black boxes - an electronic sensor of some kind - the large one attached to the frame and the smaller one attached to the door right next to it.";
         }
      }
      : else_if (!door_is_locked && sensor_is_broken) {
         : print "You've cut through the deadbolt, leaving a pile of metal filings on the ground, and disabled the sensor, so you think it should be safe to open the door now.";
      }
   }

   // sawing things

   : match "saw _ with _" {
      : if (s2() != "metal_hacksaw") {
         : print {("You can't saw anything with " + definite(d(s2())) + "!")};
         : done;
      }
   }
   : match "saw _" {
      : if (!is_carried "metal_hacksaw") {
         : print "You can't saw something without a saw!";
         : done;
      }
   }


   : match "saw door;saw door with saw" {
      : if (is_at "goat_box") {
         : print "You won't get very far sawing at the door itself. It's made of thick corrugated metal.";
         : done;
      }
      : else {
         : print "There's no reason to try to saw at the door.\n";
         : done;
      }
   }

   : match "saw deadbolt;saw deadbolt with saw" {
      : if (!door_is_locked) {
         : print "You already cut through the deadbolt.";
         : done;
      }
      : print "You hold the saw sideways and slide it in between the door and the frame, right above the bolt. Sawing through it takes several minutes and gives you a neck cramp, but eventually it slices all the way through! You stand back and dust metal filings off your fur.";
      : set_false "door_is_locked";
      : done;
   }

   : match "saw sensor;saw sensor with saw" {
      : print "You see the warning on the label - \"DO NOT INSERT METAL OBJECT\" - and think twice. The scientists were very firm with you about how dangerous electricity can be.";
      : done;
   }

   : match "saw _" {
      : print {("There's no reason to try to saw through " + definite(d(s1())) + ".")};
      : done;
   }

   // the fridge

   : match "open fridge" {
      : if (highlighting) {
         : print "You pull the refrigerator door open with your horns, sadly surveying the blocks of <tofu<#08f>> and <bottles of water<#08f>> in there. After a few seconds you close it again to save power, like the scientists told you.\nIf you want something out of the fridge, you can just take it.";
      }
      : else {
         : print "You pull the refrigerator door open with your horns, sadly surveying the blocks of tofu and bottles of water in there. After a few seconds you close it again to save power, like the scientists told you.\nIf you want something out of the fridge, you can just take it.";
      }
      : create "tofu";
      : create "bottled_water";
   }

   : match "close fridge" {
      : print "The refrigerator is already closed.";
   }

   : match "take tofu;eat tofu" {
      : print "You find tofu hard to stomach these days, which is a novel and distressing sensation.";
      : done;
   }

   : match "take water" {
      : if (is_exists "water_bottle") {
         : print "You already got a water bottle out of the fridge.";
         : done;
      }
      : print "You grab one of the bottles of water out of the refrigerator with your mouth.";
      : create "water_bottle" target="inventory";
   }

   : match "pour bottle on sensor" {
      : print "You bite off the top of the water bottle (swallowing the cap for good measure) and pour some over the sensor. With a faint electric crackle, it seems to short out - the green standby LED flickers off. You discard the empty bottle.";
      : set_true "sensor_is_broken";
      : destroy "water_bottle";
      : done;
   }

   : match "pour water on sensor" {
      : print "You'll have to take one of the bottles first.";
      : done;
   }

   : match "pour _ on _" {
      : if (s1() != "water_bottle") {
         : print {("You can't pour " + definite(d(s1())) + " on anything.")};
         : done;
      }
   }

   : match "pour _" {
      : if (original "noun2" == "") {
         : print {("You have to specify what you want to pour " + definite(d(s1())) + " on.")};
         : done;
      }
   }

   : match "pour _ on _" {
      : print {("There's no reason to pour something on " + definite(d(s2())) + ".")};
   }

   : match "drink water" {
      : print "You have to take one of the bottles first.";
      : done;
   }

   : match "drink bottle" {
      : print "You bite off the top of the bottle (it's faster than unscrewing the cap with your teeth) and drink the water, discarding the empty bottle.\n";
      : destroy "water_bottle";
      : done;
   }

   : match "drink _" {
      : print "You can't drink that.";
   }

   // TODO: putting the bottle back
   // TODO: water disambiguation problems
   // TODO: inventory limit

   : match "break sensor" {
      : print "You scratch at the sensor a bit with your horns, but it doesn't seem like you can do any real damage to it that way.";
   }

   : match "sleep straw" {
      : print "You just got up not too long ago.";
   }


   : mask {
      : match "west _" {
         : if (is_at "goat_box") {
            : if (count "_inventory" > 0) {
               : print {("You set down " + definite(d(one_of "_inventory")) + " before you leave so your mouth is free.")};
               : iterate "_inventory" {
                  : destroy {(item())};
               }
            }
            : print "You leave the goat box, stepping out into the bright sunshine...";
            : press_any_key;
            : set_integer var="current_x" value="4";
            : set_integer var="current_y" value="2";
            : set_integer var="current_height" (int(collection_get {collection -> ("containers_height") index -> (current_y*5 + current_x)}));
            : play_incidental "music_2";
         }
      }
      : match "east _" {
         : if (is_at "main_deck") {
            : print "You jump up onto a container near the starboard (southern) side of the ship.";
            : press_any_key;
            : set_integer var="current_x" value="0";
            : set_integer var="current_y" value="3";
            : set_integer var="current_height" (int(collection_get {collection -> ("containers_height") index -> (current_y*5 + current_x)}));
            : goto "container_stacks";
            : redescribe;
            : done;
         }
      }
   }

   // Container stacks puzzle

   : mask {
      : if (is_at "container_stacks") {
         : match "west _" {
            : if (on_raised_box) {
               : gosub "climb_crane";
            }
            : else_if (current_x == 0) {
               : if (current_height == 2) {
                  : print "You leap off the two stacked containers, down to the main deck. It's a long fall, but you nailed the landing.";
                  : press_any_key;
                  : goto "main_deck";
                  : redescribe;
                  : done;
               }
               : else_if (current_height == 1) {
                  : print "You hop lightly down from the container you're standing on to the main deck, and instinctively look around for a clump of weeds to eat. (You can't find one.)";
                  : press_any_key;
                  : goto "main_deck";
                  : redescribe;
                  : done;
               }
               : else {
                  : print {("You peer over the edge of the container you're on and gauge the distance. You're on top of a stack of " + current_height + " containers, so that would be a dangerous drop down to the main deck.")};
                  : done;
               }
            }
            : else_if (current_x == 2 && current_y == 2 && crane_box_attached && !crane_lowered) {
               : print "From the tallest point on the stacks of containers, it's a hard but manageable leap up to the purple container. Nailed it! As you regain your balance, your mind is already mapping out the path upward through the struts to get on top of the boom.";
               : set_true "on_raised_box";
               : done;
            }
            : else {
               : set_string var="move_direction" value="west";
               : set_integer var="move_dx" value="-1";
               : set_integer var="move_dy" value="0";
               : gosub "handle_move";
            }
         }
         : match "east _" {
            : if (on_raised_box) {
               : print "You hop back off the purple container onto the stack of six.";
               : set_false "on_raised_box";
               : done;
            }
            : else_if (current_x == 3 && current_y == 3) {
               : print "You could jump down there, but you don't think you could get back up.";
               : done;
            }
            : else_if (current_x == 4) {
               : if (current_y == 2) {
                  : print "You walk back into the goat box.";
                  : press_any_key;
                  : goto "goat_box";
                  : redescribe;
                  : done;
               }
               : else {
                  : print "You can't go east; the containers are too high in that direction.";
                  : done;
               }
            }
            : else {
               : set_string var="move_direction" value="east";
               : set_integer var="move_dx" value="1";
               : set_integer var="move_dy" value="0";
               : gosub "handle_move";
            }
         }
         : match "north _" {
            : if (on_raised_box) {
               : print "No way! Falling from this height would kill you.";
               : done;
            }
            : else_if (current_y == 0) {
               : print "You'd go overboard! There are no more containers to the north.";
               : done;
            }
            : else {
               : set_string var="move_direction" value="north";
               : set_integer var="move_dx" value="0";
               : set_integer var="move_dy" value="-1";
               : gosub "handle_move";
            }
         }
         : match "south _" {
            : if (on_raised_box) {
               : print "No way! Falling from this height would kill you.";
               : done;
            }
            : else_if (current_y == 3) {
               : print "You'd go overboard! There are no more containers to the south.";
               : done;
            }
            : else {
               : set_string var="move_direction" value="south";
               : set_integer var="move_dx" value="0";
               : set_integer var="move_dy" value="1";
               : gosub "handle_move";
            }
         }
      }
   }

   : if (is_at "container_stacks") {
      : mask {
         : match "drop _" {
            : print {(first_cap(definite(d(s1()))) + " might fall into a crack between two containers, or go overboard. This isn't a good place to put things.")};
            : done;
         }
      }
   }

   // Crane puzzle

   : if (is_at "main_deck") {
      : match "west _" {
         : if (commotion_happened) {
            : print "Dr. Walker said it was too dangerous to go inside.";
         }
         : else {
            : print "You approach the door, but hear footsteps and chatter inside. Best to keep a low profile for now.";
         }
         : done;
      }
   }

   : match "pull lever" {
      : if (original "adjective1" == "left") {
         : if (crane_angle == 0 && crane_lowered && crane_box_attached) {
            : print "You pull back the left lever, but hurriedly release it as you see what's going on; the crane is trying to pull the purple container to the left, but other containers are stopping it from moving that direction.";
            : done;
         }
         : else_if (crane_angle == 1 && crane_lowered && crane_box_attached) {
            : print "Turning the crane left while the purple container is attached to the hook and the hook is lowered would result in it hitting the other containers. Best not to.";
            : done;
         }
         : else_if (crane_angle == -2) {
            : print "A safety override flashes on the screen: you can't extend the crane past 40 degrees left while at sea.";
            : done;
         }
         : else {
            : print "With a smooth hydraulic whirr, the crane starts to move above you. You hold the lever back with your hoof long enough for it to turn about 20 degrees left, then release it.";
            : if (crane_box_attached) {
               : if (crane_lowered) {
                  : print "The purple container, at the bottom of the cable, swings like a pendulum over the ocean.";
               }
               : else {
                  : print "The purple container goes along with the end of the boom.";
               }
            }
            : else_if (crane_lowered && (crane_angle == 1 || crane_angle == 0)) {
               : print "You can hear the scraping noise of the hook dragging across the top of the containers even inside the cabin.";
            }
            : gosub "crane_action";
            : decrement "crane_angle";
            : done;
         }
      }
      : else_if (original "adjective1" == "right") {
         : if (crane_angle == -1 && crane_lowered && crane_box_attached) {
            : print "Turning the crane right while the purple container is attached to the hook and the hook is lowered would result in it hitting the other containers. Best not to.";
            : done;
         }
         : else_if (crane_angle == 2) {
            : print "A safety override flashes on the screen: you can't extend the crane past 40 degrees right while at sea.";
            : done;
         }
         : else {
            : print "With a smooth hydraulic whirr, the crane starts to move above you. You hold the lever back with your hoof long enough for it to turn about 20 degrees right, then release it.";
            : if (crane_box_attached) {
               : if (crane_lowered) {
                  : print "The purple container, at the bottom of the cable, swings like a pendulum over the ocean.";
               }
               : else {
                  : print "The purple container goes along with the end of the boom.";
               }
            }
            : else_if (crane_lowered && (crane_angle == -1 || crane_angle == 0)) {
               : print "You can hear the scraping noise of the hook dragging across the top of the containers even inside the cabin.";
            }
            : gosub "crane_action";
            : increment "crane_angle";
            : done;
         }
      }
   }

   : match "push button" {
      : if (original "adjective1" == "lower") {
         : if (crane_lowered) {
            : print "Nothing happens, because the hook is already lowered.";
            : done;
         }
         : else {
            : gosub "crane_action";
            : if (crane_angle != 0) {
               : if (crane_box_attached) {
                  : print "A winch somewhere in the ship's hull starts grinding away. The purple container descends until it stops over the ocean at about the level of some the containers. Then it just hangs there, swinging and turning slowly.";
               }
               : else {
                  : print "A winch somewhere in the ship's hull starts grinding away. The hook descends, swaying back and forth, until it stops over the ocean at about the level of some the containers.";
               }
            }
            : else {
               : if (crane_box_attached) {
                  : print "A winch somewhere in the ship's hull starts grinding away. The purple container descends, swaying back and forth, until it returns to about where it was originally.";
               }
               : else {
                  : print "A winch somewhere in the ship's hull starts grinding away. The hook descends, swaying back and forth, until it settles on one of the containers with a clank.";
               }
            }
            : set_true "crane_lowered";
            : done;
         }
      }
      : else_if (original "adjective1" == "raise") {
         : if (!crane_lowered) {
            : print "Nothing happens, because the hook is already raised.";
            : done;
         }
         : else {
            : gosub "crane_action";
            : if (crane_box_attached) {
               : print "A winch somewhere in the ship's hull starts grinding away. You admire the power of automation as the purple container rises up until it is nearly at the level of the crane's boom.";
            }
            : else {
               : print "A winch somewhere in the ship's hull starts grinding away. You watch as the hook rises up until it is nearly at the level of the crane's boom.";
            }
            : set_false "crane_lowered";
            : done;
         }
      }
   }

   : match "pull button" {
      : print "You have to push buttons, not pull them.";
      : done;
   }

   : match "push lever" {
      : print "It seems like these levers automatically snap back into the farther position (where they are now), so you'll have to pull them.";
      : done;
   }

   : if (s1() == "crane_hook" && !verb_is "examine") {
      : if (!crane_lowered && !on_raised_box) {
         : print "The crane hook has been raised to the level of the boom, so you can't reach it.";
         : done;
      }
      : else_if ((current_x != 1 || current_y != 2)) {
         : print "The crane hook is on a purple container, just to the west of the tallest stack. You can't reach it from where you are.";
         : done;
      }
   }

   : if (s1() == "crane_boom" && !verb_is "examine") {
      : if (!on_raised_box) {
         : print "You can't reach the crane's boom from where you are now.";
         : done;
      }
   }

   : match "take hook" {
      : print "It's too thick and heavy to grab in your mouth. You could probably nudge it around enough to attach it to something, though.";
      : done;
   }

   : match "pull hook;push hook" {
      : print "You can't easily pull or push it.";
      : done;
   }

   : match "attach hook to container;put hook in container;put hook through container;put hook on container;attach container to hook" {
      : print "It takes some effort and patience, but you manage to push the hook around enough with your hooves and snout to get it to go through the ring on top of the purple container.";
      : set_true "crane_box_attached";
      : done;
   }

   : match "attach _" {
      : if (original "noun2" == "") {
         : print {("You'll have to specify what you want to attach " + definite(d(s1())) + " to.")};
         : done;
      }
   }

   : match "attach hook to _" {
      : print {("There's no ring or anything on " + definite(d(s2())) + " to put the hook through.")};
      : done;
   }

   : match "attach _ to _" {
      : print {("You can't attach " + definite(d(s1())) + " to anything.")};
      : done;
   }

   : match "enter crane" {
      : if (on_raised_box) {
         : gosub "climb_crane";
         : done;
      }
   }

   : if (on_raised_box) {
      : match "up _" {
         : gosub "climb_crane";
         : done;
      }
   }

   : if (is_at "crane_boom") {
      : match "west _" {
         : print "You start walking west along the beam, balancing carefully. As you reach the halfway point, a door leading out onto the upper deck opens and Dr. Walker hurries out, waving to you.\n'Over here, kid!' he yells, rushing over to the lifeboat. You cover the rest of the distance, make one last jump, and land on the deck next to him...\n";
         : press_any_key;
         : goto "upper_deck";
         : redescribe;
      }
      : match "east _" {
         : print "It would be tricky to get back onto the purple container from here, and you don't want to risk falling off.";
         : done;
      }
   }

   : if (commotion_happening && !is_at "main_deck" && !verb_is "examine" && (s1() == "dr_beech" || s1() == "dr_walker" || s1() == "captain")) {
      : print {("You can see " + definite(d(s1())) + ", but you can't interact with him from where you are; he's on the main deck.")};
      : done;
   }

   // Endgame

   : if (is_at "upper_deck") {
      : match "east _" {
         : print "You had to jump down several feet to get to the deck, so you don't think you can get back up on the boom.";
         : done;
      }
   }

   : mask {
      : match "drop preserver" {
         : if (!is_carried "life_preserver") {
            // I don't think this can happen, but just in case:
            : print "You aren't carrying the life preserver!";
            : done;
         }
         : if (is_at "staircase") {
            : print "You shake your neck and get the life preserver free within a few seconds. When you kick it upright with your hoof, it starts to roll and bounce down the stairs, toward the three men pursuing you.\n\"Look out!\" cries the Captain, as Dr. Beech backs up, jostling the guard, and says, \"For heaven's sake- ouch!\" The ring clips the Doctor's arm and keeps bouncing down the stairway behind them, but the confusion delayed them for a few seconds.\n\"The Capricorn doesn't meet code without that life preserver up there!\" yells the Captain. \"Someone track that thing down and put it back where it's supposed to be!\"";
            : gosub "delay_enemies";
            : destroy "life_preserver";
            : done;
         }
         : else {
            : print "You can't throw it very far, but you could probably drop it in the stairwell.";
            : done;
         }
      }
   }

   : match "push chair to south;push chair to s" {
      : print "You charge at the wicker chair, using your horns to shove it along the deck and into the stairwell. It starts tumbling down, faster and faster.\nThe men stop and try to back up, running into each other. Dr. Beech raises his forearm in front of his eyes and cowers against the wall, suffering only a smack on the shin. One of the chair's legs hits the Captain in the forehead. The security guard, though, kicks the chair aside and lets it fall to the landing behind him.\nYou're now in the staircase.";
      : gosub "delay_enemies";
      : destroy "wicker_chair";
      : goto "staircase";
      : press_any_key;
      : redescribe;
      : done;
   }

   : match "push chair to _" {
      : print "The only way to go from here is south.";
      : done;
   }

   : match "push chair" {
      : print "You'll have to specify which direction you want to push the chair.";
      : done;
   }

   : match "enter chair" {
      : print "Goats can't sit!";
      : done;
   }

   : if (is_at "staircase") {
      : match "pull ring;take ring" {
         : print "You hook your horn through the fire extinguisher's ring and pop it out, then, after a quick glance at the label, turn it away from you and push the lever down with your hoof. You squint and flinch as the spray fountains out and hangs in the air, forming whitish clouds.\n\"Get back! Get back!\" yelps Dr. Beech. \"The goat figured out how to use a fire extinguisher!\" You can't see anything, but you hear sounds of commotion.\n\"Don't breathe it!\" yells the Captain. \"I think it's dangerous to breathe that stuff, ja?\"\n\"Uh, I'll Google it,\" says the guard.\n\"No, don't worry about it,\" says Dr. Beech firmly, having recovered his composure, \"just wait a few seconds and keep going! The test subject must be recaptured at all costs!\"\nOnce it's empty, you kick the fire extinguisher canister down the stairs too for good measure.";
         : gosub "delay_enemies";
         : destroy "fire_extinguisher";
         : destroy "extinguisher_ring";
         : done;
      }
      : mask {
         : match "south _" {
            : print "There's no way you could dodge past the three people pursuing you.";
            : done;
         }
      }
      : match "take extinguisher" {
         : print "It's just the wrong size to grab with your mouth, and it doesn't have any good place to put your horns (except for the ring), and it's too slippery to take with your hooves.";
         : done;
      }
   }

   : if (is_carried "life_preserver") {
      : match "examine preserver" {
         : print "The life preserver is currently looped around your neck, like a silly necklace.";
         : done;
      }
   }

   : match "enter lifeboat" {
      : if (climax_turns >= 9) {
         : print "You leap into the lifeboat next to Dr. Walker, who shoves the side of the ship as hard as he can. The lifeboat slides down the ramp with increasing speed as the three men burst onto the deck and peer over the railing. You stick out your tongue at them.\nDr. Beech sputters in shock and anger, his knuckles turning white as he clutches the railing. \"NOOOOO!!!!!\" he screams as you hit the water, but it's too late for them to do anything. You're free!";
         : press_any_key;
         : play_incidental "music_victory";
         : clear_screen;
         : print "Dr. Walker sets the throttle as high as it can go and does a U-turn, leaving the MV Capricorn far behind. \"Well, we made it, kid.\" he says. \"There's no way Captain Feuerbach is going to turn around just to recapture a troublesome goat.\"\nYou bleat in assent. Dr. Walker is lost in thought for a few moments as the engine hums away.\n\"I may have lost my job, but I'm sure we can figure something out. Remember that Stock Trading Simulator game that you were so good at? What if I told you that you could make REAL money by doing exactly the same thing?\"\nYou're fine with whatever, as long as you can buy a TV.";
         : print "***YOU HAVE WON***";
         : win_game;
      }
      : else_if (climax_turns <= 1) {
         : print "As you approach, Dr. Walker frowns and gestures for you to stay away. \"I can't find the lever. We may need another plan.\"";
         : done;
      }
      : else {
         : print "Dr. Walker pushes you away. \"Hold on just a little bit longer, kid. Find some way to distract or delay them!\"";
         : done;
      }
   }

   : match "push extinguisher" {
      : print "You probably could knock it out of its recess, but you don't think it would burst or activate when it hit the ground.";
      : done;
   }

   : match "examine extinguisher" {
      : if (highlighting) {
         : print "This fire extinguisher is located in a red-painted recess in the wall on the left-hoof side of the door. There's a <ring<#08f>> you can pull to activate it.";
      }
      : else {
         : print "This fire extinguisher is located in a red-painted recess in the wall on the left-hoof side of the door. There's a ring you can pull to activate it.";
      }
   }

   : match "examine ropes" {
      : if (climax_turns > 8) {
         : print "Dr. Walker has cut through all four of the ropes.";
      }
      : else_if (climax_turns > 6) {
         : print "Dr. Walker has cut through three of the four ropes. There's only one left holding the lifeboat in place.";
      }
      : else_if (climax_turns > 4) {
         : print "There were originally four ropes holding the lifeboat in place, but Dr. Walker has cut through two so far.";
      }
      : else_if (climax_turns > 2) {
         : print "There were originally four ropes holding the lifeboat in place, but now Dr. Walker has cut through one of them.";
      }
      : else {
         : print "These four thick ropes hold the lifeboat in place. They're supposed to be detached automatically when you pull the release lever.";
      }
      : done;
   }

   : match "eat straw" {
      : print "You idly munch at the straw a bit. There's a lot of it there, though, and you're not that hungry.";
      : done;
   }

   : match "eat ropes;cut ropes" {
      : print "You head over to the ropes, but Dr. Walker pushes you away. \"Even with both of us working on it, they'll catch us for sure! I'll handle the ropes, you handle the crew!\"";
      : done;
   }

   : match "eat _" {
      : if (s1_has_trait "edible_t") {
         : print {("You devour " + definite(d(s1())) + ". It's actually pretty good.")};
         : destroy {(s1())};
         : done;
      }
      : else {
         : print {("Even you won't eat " + definite(d(s1())) + ".")};
         : done;
      }
   }

   : match "pull _" {
      : print {("There's no reason to pull " + definite(d(s1())) + ".")};
   }

   : match "push _" {
      : print {("There's no reason to push " + definite(d(s1())) + ".")};
   }

   // Hints/about/credits

   : match "about _" {
      : print "Escape from the MV Capricorn was written in 5 days, in August 2026, as a warm-up for the fourth episode of Iron ChIF (a competition held on intfiction.org). The challenge ingredient was \"a kid is suddenly transported onto a ship.\"\nIt is possible to make the game unwinnable after a certain point near the end, but the game will warn you when you've reached that point.\nYou can get a hint at any time using >>HINT. Repeating that command will give you increasingly more helpful clues.\nYou can also list exits using >>EXITS.\nIf you are new to parser games, or want to make the game easier, you can enable color-coding relevant objects by typing >>HIGHLIGHT ON. Objects that you can interact with are highlighted orange, and portable objects are highlighted blue.";
   }

   : match "credits _" {
      : print "All the code, art, and music was created by FLACRabbit (copyright 2026). I extend my gratitude to my beta tester, Melisande.";
   }

   : match "hint;help" {
      : if (!door_is_open && is_at "goat_box") {
         // Goat box
         : if (door_is_locked) {
            : if (is_present "metal_hacksaw") {
               : cycle key="1082" predictable_order="true" max_loops="1" {
                  : print "The door is locked with a deadbolt, and there's no way to manipulate the mechanism from the inside. Maybe you could get at the bolt?";
                  : print "Only something thin could fit in the crack between the door and the frame to get at the bolt.";
                  : print "The hacksaw seems like it might be fit between the door and the frame.";
                  on_exhausted {
                     : print "You have to >>SAW THROUGH BOLT.";
                  }
               }
            }
            : else_if (is_present "copy_liberty") {
               : cycle key="1391" predictable_order="true" max_loops="1" {
                  : print "You should take a closer look at \'On Liberty.\'";
                  // WHY, Adventuron? this is stupid
                  : print "John Stuart Mill is worth reading.";
                  on_exhausted {
                     : print "John Stuart Mill is worth reading.";
                  }
               }
            }
            : else {
               : print "You should look at some of the things in the goat box. Maybe there's something that could help you.";
            }
         }
         : else_if (!sensor_is_broken) {
            : if (!sensor_first_hint) {
               : print "There must be some way to disable that sensor. Maybe you should look at it more closely.";
               : set_true "sensor_first_hint";
               : done;
            }
            : if (is_present "water_bottle") {
               : cycle key="1105" predictable_order="true" max_loops="1" {
                  : print "The sensor's warning label says it might be damaged if it's exposed to water.";
                  : print "There's some water in that bottle that you got out of the fridge.";
                  on_exhausted {
                     : print "You have to >>POUR WATER ON SENSOR.";
                  }
               }
            }
            : else {
               : cycle key="1114" predictable_order="true" max_loops="1" {
                  : print "The sensor's warning label says it might be damaged if it's exposed to water.";
                  : print "The scientists wouldn't let you die of thirst in here. Have you checked the fridge?";
                  on_exhausted {
                     : print ">>OPEN FRIDGE, then >>TAKE A BOTTLE.";
                  }
               }
            }
         }
         : else {
            : print "Nothing's stopping you from opening the door now.";
         }
      }
      : else_if (is_at "crane_boom") {
         // Just go west
         : print "You can get onto the upper deck by going west.";
      }
      : else_if (is_at "upper_deck" || is_at "staircase") {
         // Endgame
         : if (climax_turns <= 1) {
            : print "Just wait and see what happens for now.";
            : done;
         }
         : if (climax_turns >= 9) {
            : if (is_at "upper_deck") {
               : print "You're almost done - just get in the lifeboat!";
            }
            : else {
               : print "You're almost done - just go north and get in the lifeboat!";
            }
            : done;
         }
         : if (!endgame_first_hint) {
            : print "There are three ways you can delay your pursuers, and you will have to find all three.";
            : set_true "endgame_first_hint";
            : done;
         }
         : if (!endgame_second_hint) {
            : print "Two ways involve making things fall down the staircase to impede the pursuers.";
            : set_true "endgame_second_hint";
            : done;
         }
         : if (is_exists "life_preserver") {
            : cycle key="1148" predictable_order="true" max_loops="1" {
               : print "The life preserver might roll, if it were on a sloped surface.";
               : print "The staircase is basically a sloped surface.";
               on_exhausted {
                  : print "Get the life preserver, go to the staircase, then >>DROP PRESERVER.";
               }
            }
         }
         : else_if (is_exists "wicker_chair") {
             : cycle key="1158" predictable_order="true" max_loops="1" {
               : print "The chair probably wouldn't stay upright on a staircase.";
               : print "You can't pick up the chair, but you can push it in a given direction.";
               on_exhausted {
                  : print "From the upper deck, >>PUSH CHAIR SOUTH.";
               }
            }
         }
         : else_if (is_exists "fire_extinguisher") {
            : cycle key="1166" predictable_order="true" max_loops="1" {
               : print "There aren't any fires around, but that fire extinguisher might still be useful. Maybe you should take a closer look.";
               : print "If you found a way to activate the fire extinguisher, that would certainly surprise the people pursuing you.";
               on_exhausted {
                  : print "In the staircase, >>PULL RING.";
               }
            }
         }
      }
      : else {
         // Crane puzzle
         : if (is_at "goat_box") {
            : print "You've done everything you need to in the goat box. Try going OUT.";
         }
         : else_if (!has_visited "main_deck") {
            : cycle key="1194" predictable_order="true" max_loops="1" {
               : print "You have to navigate the stacks of containers to get to the main deck.";
               : print "The map above shows your position and the terrain around you. You can move with the commands N, E, S, W.";
               : print "However, you can only jump up 1 container at a time, or descend up to 2 containers at a time.";
               on_exhausted {
                  : print "There's an easy route from outside the goat box to the main deck: W, S, W, W, W, W.";
               }
            }
         }
         : else_if (!has_visited "control_cabin") {
            : print "You haven't checked out the crane's cabin yet. You can get there by going north from the main deck.";
         }
         : else {
            : if (!(commotion_happening || commotion_happened)) {
               : print "You haven't tried doing much with the crane yet. See if you can figure out how its controls work.";
            }
            : else_if (crane_box_attached) {
               : cycle key="1211" predictable_order="true" max_loops="1" {
                  : print "You can raise and lower the purple container, but you can't really move it to another part of the container stacks.";
                  : print "You can't get onto the upper deck via the interior of the ship, but can you think of any other way you might be able to get up there? (There's a rough top-down map of the ship on the crane's display.)";
                  : print "You might be able to use the boom of the crane as a bridge to reach the upper deck.";
                  : print "You have to find a way to get up onto the boom of the crane. What's the tallest location you've seen so far?";
                  : print "You can't get up to the boom from the tallest point of the container stacks directly, but can you think of any way to create a kind of stepping stone?";
                  : print "That purple container could be used to help you get up onto the crane.";
                  on_exhausted {
                     : print ">>PUSH RAISE BUTTON (if it's lowered), then move the crane over the container stacks with the levers. Now the purple container is between the tallest stack of containers and the boom of the crane.";
                  }
               }
            }
            : else {
               : cycle key="1223" predictable_order="true" max_loops="1" {
                  : print "It's fun to play with the crane, but it's really designed for lifting things.";
                  : print "The crane is supposed to lift containers on and off the ship, but right now the hook isn't secured to anything.";
                  : print "The crane's hook has to be attached to a container in order for you to be able to move anything with it.";
                  on_exhausted {
                     : print "Make sure the crane is over the container stacks and lowered, then navigate to the purple container and >>ATTACH HOOK TO CONTAINER.";
                  }
               }
            }
         }
      }
   }
}

on_tick {
   : if (turns() == 0) {
      : print "<[[For more information, you can type ABOUT, or CREDITS.]]<#ff0>>";
   }

   : set_false "time_taken";
   : iterate "time_consuming_verbs" {
      : if (verb_is {(item())}) {
         : set_true "time_taken";
      }
   }
   : if (time_taken || commotion_happening) {
      : if (crane_angle == 0) {
         : if (!is_exists "crane_hook") {
            : create "crane_hook" target="container_stacks";
            : create "crane" target="container_stacks";
         }
      }
      : else_if (is_exists "crane_hook") {
         : destroy "crane_hook";
         : destroy "crane";
      }
      : if (crane_box_attached && (!crane_lowered || crane_angle != 0)) {
         : collection_modify { collection = "containers_height" index -> (11) value -> ("1") };
      }
      : else {
         : collection_modify { collection = "containers_height" index -> (11) value -> ("2") };
      }

      // "Commotion" scene

      : if (commotion_happening) {
         : if (commotion_turns == 1) {
            : print "You hear some motion and muted chatter to the south and glance back to see the door opening.";
         }
         : else_if (commotion_turns == 2) {
            : create "dr_walker";
            : create "dr_beech";
            : create "captain";
            : play_incidental "music_interlude";
            : if (highlighting) {
               : print "Several people rush out onto the main deck, staring at the crane and at you. You immediately pick out the two fattest humans as <Dr. Walker<#f80>> and <Dr. Beech<#f80>>.\n\"I knew something like this was going to happen,\" complains the <Captain<#f80>>, a tall German guy, to the two professors. \"You know precisely WHEN I knew something like this was going to happen? When you said \'HYPERINTELLIGENT JUVENILE GOAT!\'\"";
            }
            : else {
               : print "Several people rush out onto the main deck, staring at the crane and at you. You immediately pick out the two fattest humans as Dr. Walker and Dr. Beech.\n\"I knew something like this was going to happen,\" complains the Captain, a tall German guy, to the two professors. \"You know precisely WHEN I knew something like this was going to happen? When you said \'HYPERINTELLIGENT JUVENILE GOAT!\'\"";
            }
         }
         : else_if (commotion_turns == 3) {
            : create "dr_walker";
            : create "dr_beech";
            : create "captain";
            : print "\"Well, the goat box was supposed to prevent this sort of nonsense!\" sputters Dr. Beech, glaring at everyone. \"Maybe that intern, whatever her name was, maybe she forgot to lock the door?\"\nDr. Walker adjusts his glasses and clears his throat.";
         }
         : else_if (commotion_turns == 4) {
            : create "dr_walker";
            : print "Dr. Walker raises his left hand and holds the floor. \"Excuse me, but I think you should go inside until I can make sure it's safe. The test subject trusts me most. Don't look at me like that, a goat operating heavy machinery can be dangerous!\"\nReluctantly, the others concur, and retreat back into the ship.";
            : destroy "dr_beech";
            : destroy "captain";
         }
         : else_if (commotion_turns == 5) {
            : if (is_at "control_cabin") {
               : append "Dr. Walker comes over and taps on the glass.";
            }
            : else_if (is_at "main_deck") {
               : append "Dr. Walker walks over to you and ruffles your fur.";
            }
            : else {
               : append "Dr. Walker calls out to you.";
            }
            : append " \"Hang in there, kid,\" he says. \"I'll try to occupy and distract them. There's a lifeboat on the upper deck at the aft of the ship, but you can't possibly get up there through the inside, it's too dangerous - you'll have to find another way. I'll be there. Good luck.\" He hurries back into the ship.";

            : destroy "dr_walker";
            : set_true "commotion_happened";
            : set_false "commotion_happening";
         }
         : increment "commotion_turns";
      }

      // Climax

      : if (is_at "upper_deck" || is_at "staircase") {
         : create "dr_walker" target="upper_deck";
         : create "dr_beech" target="staircase";
         : create "captain" target="staircase";
         : if (climax_turns == 0) {
            : print "\"Come on, get in the lifeboat!\" says Dr. Walker, jumping into the pilot's seat and looking for the release lever. \"Wait...\" he says, \"that's not...\"\n<[[Now would be a good time to SAVE.]]<#ffff00>>";
         }
         : else_if (climax_turns == 1) {
            : if (highlighting) {
               : print "You hear footsteps coming from the south and glance back to see three men hurrying up - <Dr. Beech<#f80>>, the <Captain<#f80>>, and a <security guard<#f80>>.\n\"Don't worry, I broke off the release lever! They can't escape now! Hear that, Dr. Walker? I saw through your plan!\" cackles Dr. Beech, his voice echoing out of the stairwell.\n\"You did WHAT?\" roars the Captain.\n\"I'll explain it all later, Mr. Feuerbach,\" continues Dr. Beech. \"For now, just help me capture the test subject.\"\nDr. Walker pulls out a Swiss Army knife and sizes up the four <ropes<#f80>> holding the lifeboat in place. \"I should be able to cut through the ropes by hand,\" he says urgently, \"but you'll have to buy me some time somehow!\"";
            }
            : else {
               : print "You hear footsteps coming from the south and glance back to see three men hurrying up - Dr. Beech, the Captain, and a security guard.\n\"Don't worry, I broke off the release lever! They can't escape now! Hear that, Dr. Walker? I saw through your plan!\" cackles Dr. Beech, his voice echoing out of the stairwell.\n\"You did WHAT?\" roars the Captain.\n\"I'll explain it all later, Mr. Feuerbach,\" continues Dr. Beech. \"For now, just help me capture the test subject.\"\nDr. Walker pulls out a Swiss Army knife and sizes up the four ropes holding the lifeboat in place. \"I should be able to cut through the ropes by hand,\" he says urgently, \"but you'll have to buy me some time somehow!\"";
            }
            : play_incidental "music_3";
         }
         : else_if (climax_turns == 2) {
            : print "\"Your problem is that you have absolutely no respect for the scientific establishment, Harold!\" yells Dr. Beech from the stairwell between gasps of breath. \"You think science is some sort of game where you can be the hero!\"\n\"You can taunt me all day, Reginald, and you still won't get my goat,\" fires off Dr. Walker, slicing through one of the ropes.";
         }
         : else_if (climax_turns == 3) {
            : print "\"Very clever. You know what, Dr. Walker? You should have been an English major, since you obviously aren't cut out for neurosurgery.\" returns Dr. Beech. Dr. Walker has to take a moment to think of a comeback as he walks over to the next rope. \"You cut it out,\" he says, somewhat lamely.";
         }
         : else_if (climax_turns == 4) {
            : print "\"Oh, I'll cut you out of the department just as soon as I can. You'll lose everything!\" says Dr. Beech in something between a snarl and a wheeze.\n\"On the contrary, I think you're the one who has cut loose with your deportment,\" says Dr. Walker. \"You impugn my training, but it seems that I've managed to hit a nerve after all.\"\nHe's released two ropes now.";
         }
         : else_if (climax_turns == 5) {
            : print "Dr. Beech continues: \"You may be able to locate a nerve, but your lack of psychological knowledge is showing, Harold. You think you're acting nobly, when really your motives are possessiveness and greed!\"\n\"It's a good thing I was never allowed to touch the grant money, then,\" calls Dr. Walker.";
         }
         : else_if (climax_turns == 6) {
            : print "\"I'll grant that your retorts are funny,\" snaps Dr. Beech, \"but this harebrained scheme to run off with the test subject isn't.\"\n\"Given how thick your skull is, I'd be surprised if your hair and your brain even know of each other's existence,\" parries Dr. Walker as another rope snaps free.\n\"I think you both need new hearing aid batteries, ja?\" hollers the Captain.";
         }
         : else_if (climax_turns == 7) {
            : print "\"No, I think YOU just need to learn what \'wit\' is, Mr. Feuerbach,\" you hear Dr. Beech growl at the Captain.\n\"Touché,\" he mutters.\n\"All your wit won't make one whit of difference once we're out of here, Reginald,\" returns Dr. Walker.";
         }
         : else_if (climax_turns == 8) {
            : print "\"Keep whittling away at those ropes, then,\" calls Dr. Beech. \"See how it works out for you!\"\n\"The sea is exactly how it's going to work out for us,\" says Dr. Walker with a smile as the fourth rope pops free. He folds up his knife and gestures to you. \"Come on, kid.\"";
            : add var="climax_enemy_progress" value="-2"; // it would be really anticlimactic for them to catch you right now
         }
         : increment "climax_turns";
         : increment "climax_enemy_progress";
         : if (climax_enemy_progress == 5) {
            : if (is_at "staircase") {
               : print "Dr. Beech reaches out to grab you by the scruff of the neck. You shy away and leap back onto the deck, but there's nowhere to run - the three men surround you.";
            }
            : else {
               : print "The three men pursuing you burst out of the doorway and spread out on the upper deck, closing in on you.";
            }
            : print "\"Now wait a minute-\" exclaims Dr. Walker, raising his hands, but it's too late. The guard grabs you and picks you up roughly, and Dr. Beech smiles in triumph as you kick and wriggle futilely.\n\"Back to the goat box,\" he says, before turning to the Captain: \"And can we put another container directly in front of it? This time, I'm not taking any chances.\"";
            : print "***YOU HAVE LOST***";
            : end_game;
         }
      }
   }

   // Backdrops

   // crane
   : if (!(is_at "container_stacks" && crane_angle == 0) && !(is_at "goat_box" || is_at "staircase")) {
      : create "backdrop_crane";
   }
   : else {
      : destroy "backdrop_crane";
   }

   // containers
   : if (!is_at "container_stacks" && !(is_at "goat_box" || is_at "staircase")) {
      : create "backdrop_containers";
   }
   : else {
      : destroy "backdrop_containers";
   }

   // sea+sky
   : if (!(is_at "goat_box" || is_at "staircase")) {
      : create "backdrop_sea";
      : create "backdrop_sky";
   }
   : else {
      : destroy "backdrop_sea";
      : destroy "backdrop_sky";
   }
}

on_describe {
   : if (is_beside "copy_liberty") {
      : if (highlighting) {
         : print "There's a hardcover copy of '<On Liberty<#08f>>' on the floor here.";
      }
      : else {
         : print "There's a hardcover copy of \'On Liberty\' on the floor here.";
      }
   }

   : if (is_beside "metal_hacksaw") {
      : if (highlighting) {
         : print "A small metal <hacksaw<#08f>> is lying nearby.";
      }
      : else {
         : print "A small metal hacksaw is lying nearby.";
      }
   }

   : if (is_beside "water_bottle") {
      : if (highlighting) {
         : print "You've set down a <bottle of water<#08f>> on the floor.";
      }
      : else {
         : print "You've set down a bottle of water on the floor.";
      }
   }

   : if (is_beside "crane_hook") {
      : if (crane_box_attached) {
         : if (crane_lowered) {
            : if (current_x == 1 && current_y == 2) {
               : if (highlighting) {
                  : print "The crane's <hook<#f80>> is attached to the <ring<#f80>> on the <purple container<#f80>> you're standing on.";
               }
               : else {
                  : print "The crane's hook is attached to the ring on the purple container you're standing on.";
               }
            }
            : else {
               : if (highlighting) {
                  : print "The crane's <hook<#f80>> is attached to a <purple container<#f80>> near the main deck.";
               }
               : else {
                  : print "The crane's hook is attached to a purple container near the main deck.";
               }
            }
         }
         : else {
            : if (highlighting) {
               : print "The <purple container<#f80>> has been lifted even higher than the tallest stack of containers, right below the crane's <boom<#f80>>.";
            }
            : else {
               : print "The purple container has been lifted even higher than the tallest stack of containers, right below the crane's boom.";
            }
         }
      }
      : else {
         : if (crane_lowered) {
            : if (current_x == 1 && current_y == 2) {
               : if (highlighting) {
                  : print "The crane's <hook<#f80>> is lying on the <container<#f80>> you're standing on, near a steel <ring<#f80>> on the top of the box.";
               }
               : else {
                  : print "The crane's hook is lying on the container you're standing on, near a steel ring on the top of the box.";
               }
            }
            : else {
               : if (highlighting) {
                  : print "The crane's lowered <hook<#f80>>  is lying on top of a <purple container<#f80>> near the main deck.";
               }
               : else {
                  : print "The crane's lowered hook is lying on top of a purple container near the main deck.";
               }
            }
         }
         : else {
            : if (highlighting) {
               : print "The crane's <boom<#f80>> looms overhead, but its <hook<#f80>> is raised high enough that you can't reach it from any of the containers.";
            }
            : else {
               : print "The crane's boom looms overhead, but its hook is raised high enough that you can't reach it from any of the containers.";
            }
         }
      }
   }

   : if (is_at "upper_deck") {
      : if (climax_turns >= 9) {
         : if (highlighting) {
            : print "<Dr. Walker<#f80>> is in the lifeboat, frantically waving you over.";
         }
         : else {
            : print "Dr. Walker is in the lifeboat, frantically waving you over.";
         }
      }
      : else_if (climax_turns >= 2) {
         : if (highlighting) {
            : print "<Dr. Walker<#f80>> is trying to cut through the ropes holding the lifeboat in place.";
         }
         : else {
            : print "Dr. Walker is trying to cut through the ropes holding the lifeboat in place.";
         }
      }

      : else {
         : if (highlighting) {
            : print "<Dr. Walker<#f80>> is standing here, gesturing to you.";
         }
         : else {
            : print "Dr. Walker is standing here, gesturing to you.";
         }
      }
   }

   : if (is_at "staircase") {
      : if (climax_enemy_progress == 0) {
         : if (highlighting) {
            : print "<Dr. Beech<#f80>>, the <Captain<#f80>>, and a <security guard<#f80>> are at the bottom of the staircase, but they're rapidly ascending.";
         }
         : else {
            : print "Dr. Beech, the Captain, and a security guard are at the bottom of the staircase, but they're rapidly ascending.";
         }
      }
      : else_if (climax_enemy_progress == 1) {
         : if (highlighting) {
            : print "<Dr. Beech<#f80>>, the <Captain<#f80>>, and a <security guard<#f80>> are nearing the middle of the staircase. Their pounding footsteps are echoing off the hard walls.";
         }
         : else {
            : print "Dr. Beech, the Captain, and a security guard are nearing the middle of the staircase. Their pounding footsteps are echoing off the hard walls.";
         }
      }
      : else_if (climax_enemy_progress == 2) {
         : if (highlighting) {
            : print "Your pursuers are past the midpoint of the staircase. <Dr. Beech<#f80>>, in the front, is panting heavily.";
         }
         : else {
            : print "Your pursuers are past the midpoint of the staircase. Dr. Beech, in the front, is panting heavily.";
         }
      }
      : else_if (climax_enemy_progress == 3) {
         : if (highlighting) {
            : print "The three men pursuing you are near the top of the staircase!";
         }
         : else {
            : print "The three men pursuing you are near the top of the staircase!";
         }
      }
   }
}

on_post_tick {
   : set_false "occluded";
      : if ((current_x == 1 && current_y == 0) || (current_x == 2 && current_y == 1)) {
         : set_true "occluded";
      }
   : update_graphic ;
}

subroutines {
   s1_scope_check: subroutine {
      : if (original "noun1" == "") {
         : print "You have to specify a noun.";
         : done;
      }
      : look_inside {
         of = "current_location"
         extract_the = "id"
         store_results_in = "objects_in_current_location";
      }
      : look_inside {
         of = "inventory"
         extract_the = "id"
         store_results_in = "objects_in_inventory";
      }
      : collection_union {
         collection_1 = "objects_in_current_location"
         collection_2 = "objects_in_inventory"
         result = "manipulable_objects";
      }
      : collection_union {
            collection_1 = "manipulable_objects"
            collection_2 = "extended_scope"
            result = "manipulable_objects";
         }
      : set_false "noun_is_manipulable";
      : iterate "manipulable_objects" {
         : if (s1() == item()) {
            : set_true "noun_is_manipulable";
         }
      };
      : if (!noun_is_manipulable) {
         : print "You can't see any such thing.";
         : done;
      }
   }

   s2_scope_check: subroutine {
      : if (original "noun2" == "") {
         : set_true "second_noun_is_manipulable"; // allow it to pass so a specialized handler can apply in on_command
      }
      : else {
         : look_inside {
            of = "current_location"
            extract_the = "id"
            store_results_in = "objects_in_current_location";
         }
         : look_inside {
            of = "inventory"
            extract_the = "id"
            store_results_in = "objects_in_inventory";
         }
         : collection_union {
            collection_1 = "objects_in_current_location"
            collection_2 = "objects_in_inventory"
            result = "manipulable_objects";
         }
         : collection_union {
            collection_1 = "manipulable_objects"
            collection_2 = "extended_scope"
            result = "manipulable_objects";
         }
         : set_false "second_noun_is_manipulable";
         : iterate "manipulable_objects" {
            : if (s2() == item()) {
               : set_true "second_noun_is_manipulable";
            }
         };
         : if (!second_noun_is_manipulable) {
            : print "You can't see any such thing.";
            : done;
         }
      }
   }

   handle_move: subroutine {
      : set_integer "destination_x" (current_x + move_dx);
      : set_integer "destination_y" (current_y + move_dy);

      : set_integer var="destination_height" (int(collection_get {collection -> ("containers_height") index -> (destination_y*5 + destination_x)}));

      : if (destination_height > current_height + 1) {
         : print {("The stack of containers to the " + move_direction + " has " + (destination_height - current_height) + " more than the one you're on. You don't think you can jump up that high; you can only ascend one container at a time.")};
         : done;
      }
      : else_if (destination_height < current_height - 2) {
         : print {("You look down and gauge the distance. You'd be safe jumping down one or two containers, but the drop to the " + move_direction + " looks dangerous.")};
         : done;
      }

      : if (destination_height == current_height + 1) {
         : print {("You jump up to the stack of containers to the " + move_direction + ".")};
      }
      : else_if (destination_height == current_height) {
         : print {("You walk " + move_direction + ", onto the next container.")};
      }
      : else_if (destination_height == current_height - 1) {
         : if (destination_height == 0) {
            : print {("You nimbly hop down onto an exposed part of the deck to the " + move_direction + ".")};
         }
         : else {
            : print {("You nimbly hop down onto a container to the " + move_direction + ".")};
         }
      }
      : else_if (destination_height == current_height - 2) {
         : print {("Bracing yourself, you jump down and land on the stack of containers to the " + move_direction + " with a muted clang.")};
      }

      : set_integer var="current_x" (destination_x);
      : set_integer var="current_y" (destination_y);
      : set_integer var="current_height" (destination_height);

      : done;

   }

   climb_crane: subroutine {
      : print "You wriggle between two struts, kick off of two more in succession, and balance yourself on top of one of the thick structural beams that form the crane's boom...";
      : press_any_key;
      : goto "crane_boom";
      : redescribe;
   }

   delay_enemies: subroutine {
      : add var="climax_enemy_progress" value="-2";
      : if (climax_enemy_progress < -1) {
         : set_integer var="climax_enemy_progress" value="-1";
      }
   }

   crane_action: subroutine {
      : if (!commotion_happening && !commotion_happened) {
         : set_true "commotion_happening";
      }
   }
}



assets {
   graphics {
      title : base64_png " ";

      containers : base64_png " " {
         : if (crane_box_attached && !crane_lowered && crane_angle == 0) {
            : overlay "containers_raised";
         }
         : else_if (crane_box_attached && crane_angle != 0) {
            : overlay "containers_missing";
         }
         : if (is_at "container_stacks") {
            : if (on_raised_box) {
               : overlay {
                  graphic -> (occluded ? "goat_occluded_1" : "goat")
                  x -> (67 + 1*35 + 2*8 - 4)
                  y -> (76 - 1*9 + 2*8 - 7*13 + 6)
               };
            }
            : else {
               : overlay {
                  graphic -> (occluded ? "goat_occluded_1" : "goat")
                  x -> (67 + current_x*35 + current_y*8 - 10)
                  y -> (76 - current_x*9 + current_y*8 - current_height*13 + 5)
               };
            }
         }
         : if (crane_angle == 0) {
            : if (crane_lowered) {
               : overlay "crane_containers_overlay";
            }
            : else {
               : overlay "crane_containers_overlay_raised";
            }
         }
         : if (crane_angle == -1 && crane_lowered) {
            : if (crane_box_attached) {
               : overlay "crane_20_deg_left_overlay_container";
            }
            : else {
               : overlay "crane_20_deg_left_overlay";
            }
         }
         : if (crane_angle == 1) {
            : if (crane_lowered) {
               : overlay "crane_20_deg_right_overlay_lowered";
            }
            : else_if (crane_box_attached) {
               : overlay "crane_20_deg_right_overlay_raised_container";
            }
            : else {
               : overlay "crane_20_deg_right_overlay_raised";
            }
         }
      }
      goat : base64_png " ";
      ship_base : base64_png " " {
         : if (crane_angle < 0) {
            : overlay {
               graphic -> ("crane_m" + (-crane_angle))
            }
         }
         : else {
            : overlay {
               graphic -> ("crane_" + crane_angle)
            }
         }
         : if (crane_lowered) {
            : overlay "crane_lowered_g";
         }
         : else {
            : overlay "crane_raised_g";
         }
         : if (crane_box_attached && (!crane_lowered || crane_angle != 0)) {
            : overlay "load_detected";
         }
      }
      crane_lowered_g : base64_png " ";
      crane_raised_g : base64_png " ";
      crane_1 : base64_png " ";
      crane_0 : base64_png " ";
      crane_m1 : base64_png " ";
      crane_m2 : base64_png " ";
      crane_2 : base64_png " ";
      load_detected : base64_png " ";
      containers_raised : base64_png " ";
      crane_containers_overlay : base64_png " ";
      crane_containers_overlay_raised : base64_png " ";
      goat_occluded_1 : base64_png "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IB2cksfwAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+oICxEOHAsc5gIAAAC8SURBVEjH7ZOxDcMgEEX/WR7Gsqiyh11kgGyQPiO4zwYewAXZw9UJsc2liQm6ICFwGZ6EdAL0/+cAoJGBMutSsLfIQABA5KtPRFUmXUrcsw3iRHSIV9Gp1OLZwu1Op6baFsWpxbOV+2RCre6g+gTi2YaJ54tPBU226GgJAMRmnzp1ElEDUVBJvSIBgG1dAADjZfyJNpg51Nu6hD1ud7jeHvBsMZiZcs80a6RMqfofxClLBDX92YSNRuMfeANuSVFKmIpzlgAAAABJRU5ErkJggg==";
      containers_missing : base64_png " ";
      crane_20_deg_left_overlay : base64_png " ";
      crane_20_deg_left_overlay_container : base64_png " ";
      crane_20_deg_right_overlay_lowered : base64_png " ";
      crane_20_deg_right_overlay_raised : base64_png " ";
      crane_20_deg_right_overlay_raised_container : base64_png " ";
   }

   sounds {
      music_1: sound_sample "midgame.mp3";
      music_2: sound_sample "ship.mp3";
      music_3: sound_sample "endgame.mp3";
      music_interlude: sound_sample "interlude.mp3";
      music_victory: sound_sample "victory.mp3";
   }
}
