! _Hunter, in Darkness_ ! Special source-code edition ! Copyright 1999 Andrew Plotkin ! http://www.eblong.com/zarf/if.html ! This source code is provided for personal, educational use only. ! See README file for details. Object PitLedge "Narrow Ledge" with seen_once false, description [; if (~~self.seen_once) { print "After a moment you retake your balance, and turn. "; self.seen_once = true; } print "This ledge is barely two feet wide at most. You try not to feel like it's angled slightly outward."; if (illum) print " The pit stretches above and below you; but you can see no way to climb from here, either way."; else print " Empty air echoes above and below you."; new_line; rtrue; ], before [; Jump: switch (ledge_rope.phase) { 0: "The rope curves some fifteen feet above you. Jumping is just a bit optimistic."; 1, 2: deadflag = 1; "You back along the ledge, then take a long step and leap...^^ The cut end of the rope brushes your fingers, but you have no chance to grab it. You twist, plummet, and are impaled on sharp stone."; 3: <>; } ]; ObjExit -> ledge_up "pit above" with name 'pit' 'u//' 'up' 'above' 'roof' 'ceiling' 'ascent', description "The pit walls are slick vertical limestone here, although you know they widen somewhere above.", door_to "Ascent is impossible.", before [; Climb: <>; ]; ObjExit -> ledge_down "pit below" with name 'pit' 'd//' 'down' 'below' 'floor' 'descent', description "You can make out the pit floor. It's only two or three body-lengths down; but the stone formations directly below you look vicious.", seen_once false, door_to [; if (illum && (~~self.seen_once)) { self.seen_once = true; "You dangle your legs over the edge again, and turn and hang... and look down. And change your mind. The spires below are like fangs in a stone maw. You scramble back to the ledge to think it over."; } <>; ], before [; Climb: <>; JumpInto: deadflag = 1; "You leap out into space, trying to clear the blade-like stone formations below. They get you anyway."; ]; Class LedgePassage class ObjExit, with name 'side' 'passage' 'dark' 'patch' 'patches' 'pillar' 'pillars', description "The passage is just a dark patch in the side of the pit, off to the side and far above the ledge you stand on. Its outline is ragged with stalactites and flowstone pillars where water has dripped for millennia down the pit walls.", before [; Examine, VagueShoot: rfalse; Enter, CaveGo: rfalse; default: "The side passage is out of reach."; ], door_to "Both side passages are well above you, and a fair distance around the pit wall as well."; Object -> ledge_left_passage "left side passage" class LedgePassage, with name 'left', description [; ledge_rope.seen_once = true; print (string) self.LedgePassage::description; print " A rope is tied securely to one such pillar"; switch (ledge_rope.phase) { 0: print ", and stretches across the pit."; 1, 2: print ", and hangs down the wall to a point above your head."; 3: print ", and hangs down the wall to your left. A curved white claw is tied to the lower end."; } new_line; rtrue; ], before [; JumpOver: if (ledge_rope.phase == 3) <>; ]; Object -> ledge_right_passage "right side passage" class LedgePassage, with name 'right', description [; ledge_rope.seen_once = true; print (string) self.LedgePassage::description; switch (ledge_rope.phase) { 0: print " A rope is wrapped around one such pillar, hooked to itself with a curved white claw. The rope stretches across the pit."; 1: print " A rope is wrapped around one such pillar, hooked to itself with a curved white claw. The rope hangs down the wall to a point above your head."; } new_line; rtrue; ]; Object -> ledge_blades "stone blades" with name 'sharp' 'blades' 'blade' 'stone' 'formation' 'formations' 'fang' 'fangs' 'vicious' 'spire' 'spires', description "Sharp spires rise directly below you -- some chance result of dripping minerals and flowing water. If you try to descend farther, you'll slip and probably fall into them.", before [; Examine, VagueShoot: rfalse; JumpOver: <>; JumpInto, Enter: deadflag = 1; "You dangle your legs over the edge again, and turn and hang... and steel yourself, and drop.^^ The stone blades that impale you probably aren't that large, in truth. You don't care. The sound of fluttering wings draws closer."; default: "The stone blades are well out of reach."; ], when_shot " The bolt rattles among the blades and is lost.", has scenery pluralname; Object -> ledge_rope "rope" with name 'rope' 'gentle' 'arc' 'end' 'ends', seen_once false, touched_once false, phase 0, ! 0: initial. 1: cut, useless. 2: cut and dislodged, ! claw gone. 3: dislodged. describe [; if (illum == 0) rtrue; switch (self.phase) { 0: if (~~self.seen_once) "^A gentle arc hangs across the pit, well above your head."; "^A rope hangs across the pit, a gentle arc well above your head."; 1: "^Two ends of a rope hang down the pit walls, above you and to either side of the ledge."; 2: "^Half a rope hangs down the pit wall to your left."; 3: "^The rope hangs down the pit wall to your left. The claw dangles from its end, at about the level of your waist."; } ], description [; if (~~self.seen_once) { self.seen_once = true; print "It's a rope. "; } switch (self.phase) { 0: print "Someone must have been trying to cross the pit. Yes, you can make out the side passages now -- dark patches in the walls above you. The rope seems to be tied to a pillar by one; the other end is wound around an opposite pillar, hooked precariously by something white and curved."; 1: print "You've split the rope. Half hangs down from the left side passage where it's tied; the other dangles from the curved white claw that hooks it by the right passage. The cut ends are several feet above your head."; 2: print "The remaining half of the rope hangs down from the left side passage, where it's tied. The cut end is several feet above your head."; 3: print "The upper end of the rope is tied to a pillar by the left side passage. The lower end, tied to the claw, dangles free. It hangs at about waist-level, just beyond the left side of the ledge."; } new_line; rtrue; ], before [ ix; switch (action) { ##Examine, ##VagueShoot: rfalse; ##Enter, ##Climb: if (self.phase ~= 3) <>; print "You breathe a moment; only one chance at this.^^ A step and a leap, and you clutch the rope. It's slicker than you expected; chilly and damp. Perhaps a bit of mold, you think abstractedly, as your hands slip, and catch, and slip again --^^", (emph) "Ouch.", " You've fetched up against the knot at the bottom of the rope; and the claw is biting into your hand. Razor-edged on the inside. You hope you never run into one of these alive -- ", (emph) "ow.", " You've slipped again, and now both your hands are clamped around the claw, and your full weight is on them.^"; PlayerTo(RopeHang); rtrue; default: self.seen_once = true; switch (self.phase) { 0: "Even at the center of its arc, the rope is fifteen feet above you."; 1: ix = (random(101) > 50); print "You move to the extreme "; if (ix) print "left"; else print "right"; print " side of the ledge and stretch, but the cut end of the rope is too far up and out. The "; if (ix) print "right"; else print "left"; " end is no better."; 2: "You move to the extreme left side of the ledge and stretch, but the cut end of the rope is too far up and out."; 3: print "The rope hangs a bit too far beyond the ledge"; if (~~self.touched_once) { self.touched_once = true; ". It would be an easy jump, but you can't simply grab it."; } else { "."; } } } ], when_shot [; self.seen_once = true; switch (self.phase) { 0: self.phase = 1; " Well shot -- the bolt catches the rope neatly in the center, whipping it upward before shearing through. The ends dance like mad snakes, then settle."; 1, 2: " Your bolt brushes the dangling rope, which dances gently."; 3: self.phase = 2; remove ledge_claw; " Well shot again; the bolt snags the middle of the rope and shears through. The lower half of the rope, with claw attached, snakes down into the darkness below."; } ], has static; Object -> ledge_claw "claw" with name 'broken' 'claw' 'white' 'curve' 'curved' 'hook' 'grapple' 'thing' 'object', description [; ledge_rope.seen_once = true; if (ledge_rope.phase == 2) "(BUG) Claw should be gone."; print "Long, curved, white -- it's a claw, a broken-off claw of the ", (NameWumpus) 0, " that you seek"; if (ledge_rope.phase == 3) ". It's still tied to the end of the rope, which hangs to your left."; if (ledge_rope.phase == 0) print ". The rope is"; else print ". Half the rope is still"; print " tied to it, and the makeshift grapple is wound precariously around a pillar by the right passage, above you."; new_line; rtrue; ], before [; Examine, VagueShoot: rfalse; default: if (ledge_rope.phase == 0 or 1) "The claw is up by the right side passage, far out of reach."; <<(action) ledge_rope second>>; ], when_shot [; ledge_rope.seen_once = true; switch (ledge_rope.phase) { 0: ledge_rope.phase = 3; " Well shot -- the claw is dislodged, whirls furiously around the pillar, and falls free. The rope swings down past you and hangs to your left, claw still tied to the end."; 1: remove self; ledge_rope.phase = 2; " Well shot -- the claw is dislodged, whirls furiously around the pillar, and falls free. Its half of the rope snakes down into the darkness."; 2: " (BUG) Claw should be gone."; 3: " Your bolt sets the claw spinning wildly at the end of the rope."; } ], has scenery; ! --- Object RopeHang "Hanging From a Rope" with description "You are dangling at the end of the rope, against a sheer stone wall. Directly below you are vicious stone blades, and the claw you hang from is slowly slicing into your palms, and it hurts...", initial [; StartDaemon(self); ], touched_once false, swinging 0, ! nonzero if swinging before [; Look, Inv, Examine, VagueShoot, Drop: rfalse; Enter, Climb, CaveGo, AutoCaveGo: rfalse; Wake, Sleep, Sorry, Strong, Mild, Pray, NotThisGame, Yes, No, Think: rfalse; Listen, Smell: rfalse; Jump: if (self.swinging) <>; "Not like this."; JumpOver: if (noun == ropehang_blades && self.swinging) <>; "Not like this."; JumpInto, VagueSwing: rfalse; Swing: if (noun == player or ropehang_up or ropehang_claw) { if (self.swinging == 0) { self.swinging = 2; "You lurch yourself to the side, kick at the wall, and manage to set yourself swinging. The pain is amazing, but you have a chance at missing the stone blades now."; } else { self.swinging = 3; "You swing your legs back and forth, pumping your motion. Just like a child's swing, really. Except for the claw slicing into your hands and the stone wall scraping painfully at your shoulder."; } } <>; Wait: print (string) random("Time passes.", "Time passes.", "Time passes.", "Time hangs heavy on your hands.", "Just hanging around."); new_line; rtrue; default: if (~~self.touched_once) { self.touched_once = true; "You try to work one hand loose, but the other one screams at the excess weight. You'd probably lose your grip, and then fingers."; } "You don't have a hand free."; ], after [; Drop: move noun to Pit; if (noun == crossbow && wumpus_wounded) remove noun; print_ret "You manage to dislodge ", (the) noun, ", and it drops out of sight."; ], number 0, daemon [ ix; if (player notin self) "^(BUG) RopeHang daemon still active."; self.number++; switch (self.number) { 2: if (wumpus_wounded) { print "^The claw jerks agonizingly against your hands.^^ There is a dark shape, ", (emph) "clinging", " to the pit wall above you. It bats the rope again. You thrash"; if (crossbow in player) { print ", clutching for your crossbow -- it goes skittering away --"; remove crossbow; lost_crossbow = true; } print " and lose your grip --^^"; StopDaemon(RopeHang); wound.spot = hands; if (~~(lamp.broken)) { lamp.broken = true; if (lamp.brightness > 1) lamp.brightness = 1; } light_silent = true; status_override = "Pain"; DrawStatusLine(); KeyPause(); status_override = 0; PlayerTo(Pit); rtrue; } print "^Your fingers slip, and the claw-edge cuts a little deeper.^"; 4: print "^Blood is trickling down your arm.^"; 6: print "^Your hands are slashes of pain, and blood is making your grip uncertain.^"; 8: print "^You slip again, gasp, grit your teeth, and hold.^"; 10: deadflag = 1; print "^The blood-slick claw slips through your grasp"; if (self.swinging) print ", at the worst moment in your swing"; ".^^There is a moment of free fall, and then you are impaled on stone spires."; 3, 5, 7, 9: ! Note this can't happen immediately, which is important. ! We daren't lose the crossbow this way if wumpus_wounded. for (ix = child(player) : ix ~= 0 : ix = sibling(ix)) { if (ix hasnt worn) break; } if (ix) { move ix to Pit; print "^In your struggle to ease your grip, ", (the) ix, " has slipped away from you. It drops away into the pit.^"; } } if (self.swinging) { self.swinging--; if (self.swinging == 0) { print "^You bump to a stop.^"; } else { print "^You swing along the wall, fingers screaming at the extra strain.^"; } } ]; ObjExit -> ropehang_down "pit below" with name 'pit' 'd//' 'down' 'below' 'floor' 'descent', description "The bottom of the pit isn't too far down, but the sharp stone formations are directly below your feet.", door_to [; if (RopeHang.swinging == 0) { deadflag = 1; "There is a moment of free fall, and then you are impaled on stone spires."; } StopDaemon(RopeHang); print "You twist back, forth, back, increasing your swing. Now -- you're rising away from the spires, which look sharper than ever -- you let go of the claw, finally, the pain nearly stops -- and you drop --^^"; wound.spot = hands; if (~~(lamp.broken)) { lamp.broken = true; if (lamp.brightness > 1) lamp.brightness = 1; } light_silent = true; status_override = "Pain"; DrawStatusLine(); KeyPause(); status_override = 0; return Pit; ], before [; JumpInto: <>; Climb: "You are already at the bottom of the rope."; ]; ObjExit -> ropehang_up "rope" with name 'rope' 'u//' 'up' 'ascent', description "It's an old rope. Somewhere above, it's tied to a stone pillar. At your end, it's tied to a razor-like claw, and that's the end that's got your attention.", door_to "You couldn't even hold in place on the rope, and that was before your hands were cut bloody. Climbing is impossible.", before [; Drop: <>; Climb: <>; ]; ObjExit -> ropehang_ledge "ledge" with name 'ledge' 'right', description "The ledge you were standing on is to your right. But it's about level with your chin; you doubt you could climb back onto it.", door_to "You were right. You can't climb back onto the ledge. If you try to spare a hand from the claw, the other will be sliced bone from tendon.", before [; Climb: <>; ]; Object -> ropehang_claw "claw" with name 'broken' 'white' 'curve' 'curved' 'claw' 'thing' 'object', description [; print "Long, curved, white -- it's a claw, a broken-off claw of the ", (NameWumpus) 0, " that you seek"; ". It hangs from the end of the rope, and you hang from it. Your blood slowly drips down its length."; ], before [; Drop: <>; Climb: <>; ], has scenery; Object -> ropehang_blades "stone blades" with name 'sharp' 'blades' 'blade' 'stone' 'formation' 'formations' 'fang' 'fangs' 'vicious' 'spire' 'spires', description "Sharp spires rise directly below you -- some chance result of dripping minerals and flowing water. You really, really hope you don't fall on them.", before [; Examine, VagueShoot: rfalse; default: "The blades are -- fortunately -- still out of reach."; ], has scenery pluralname;