! _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. ! --- You Class BodyPart with description "It's been there all your life.", articles "Your" "your" "your", before [; Take, Drop: "Autodismemberment isn't the answer to this one."; Smell: <>; Receive: if (noun has clothing) print_ret "That's not how ", (the) noun, " ", (IsorAre) noun, " meant to be worn."; <>; Touch, Rub, Squeeze, Repair: if (wound.spot == self) <<(action) wound>>; rfalse; ], has scenery; Object myselfobj "(self object)" with short_name "yourself", description [; if (wound.spot) { print "Your ", (name) wound.spot, " ", (IsorAre) wound.spot, " pretty torn up. Also, you're"; } else { print "You're"; } " tired and covered with mud."; ], capacity 100, number 0, orders 0, before [; Turn: <>; Smell: "You smell like a tired, unwashed hunter."; ], react_after [; Inv: if (lost_crossbow) { lost_crossbow = false; print "^...And no crossbow. Right."; if (~~wumpus.seen_once) { print " You lost hold of it in the fall."; } new_line; } ], add_to_scope [; AddToScope(leg); AddToScope(wrist); AddToScope(arm); AddToScope(hands); AddToScope(otherparts); if (wound.spot) AddToScope(wound); ], has concealed animate proper transparent; Object leg "leg" class BodyPart, with name 'leg' 'thigh', description [ ix; if (thighband in player && thighband has worn) { print "Your thighband is strapped in place."; ix = children(thighband); if (ix == 0) print_ret " It is empty."; else if (ix == 1) print_ret " There is one bolt within."; else print_ret " There are ", (EnglishNumber) ix, " bolts within."; } return self.BodyPart::description(); ]; Object wrist "wrist" class BodyPart, with name 'wrist' 'wrists', description [; if (lamp in player && lamp has worn) { print "You are wearing your lamplens.^"; rtrue; } return self.BodyPart::description(); ]; Object arm "arm" class BodyPart, with name 'arm' 'arms', description [; if (wound.spot == self) return wound.description(); return self.BodyPart::description(); ]; Object hands "hands" class BodyPart, with name 'hand' 'hands' 'palm' 'palms', description [; if (wound.spot == self) return wound.description(); return self.BodyPart::description(); ], before [; Wave: <>; ], has pluralname; Object otherparts "body" class BodyPart, with name 'foot' 'feet'; Object wound "bloody wound" class BodyPart, with name 'my' 'your' 'wound' 'wounds' 'blood' 'bloody', parse_name [ wd num isblood; isblood = false; wd = NextWord(); while (WordInProperty(wd, self, name)) { if (isblood && (wd == 'wound' or 'wounds')) return 0; if (wd == 'blood') isblood = true; num++; wd = NextWord(); } return num; ], spot 0, ! set to a body part to activate the wound. phase 1, ! 1: bleeding. 2: bandaged. 3: bleeding again. number 0, ! how much blood has been lost. description [; switch (self.spot) { 0: "(BUG) Not wounded yet."; arm: print "There's a deep slash in your upper arm. It's"; hands: print "Your palms are deeply gashed. They're"; default: print_ret "(BUG) Wounded ", (name) self.spot, "."; } if (self.phase == 2) " bandaged, and doesn't seem to be bleeding any more."; else if (self.phase == 3) " slowly oozing blood."; else " dripping blood at an alarming rate."; ], before [; Touch, Rub, Squeeze: "That hurts. A lot."; Repair: "You're a hunter, not a doctor."; ], daemon [; if (self.spot == 0) return; if (self.phase == 1) { self.number++; if (location hasnt bled_in) { ! you bleed faster outside of pit. give location bled_in; switch (self.number) { 2 to 3: self.number = 3; 5 to 8: self.number = 8; 9 to 12: self.number = 12; 13 to 14: self.number = 14; } } switch (self.number) { 3: print "^Blood continues to trickle down your fingers.^"; 4: print "^You are starting to feel quite chill and distant.^"; 8: print "^You shake your head to disperse the cold mist, and start to rub your eyes. It doesn't help, except to smear blood all over your face.^"; 12: print "^The world is becoming distant. ", (emph) "Shock,", " a voice says somewhere. That makes sense, you think; you can't have lost enough blood yet to affect you directly.^"; 14: player.orders = InShockOrders; print "^You slump down. ", (emph) "Just a little rest,", " a voice lies, but unfortunately you're too tired to argue with it.^"; 17: deadflag = 1; print_ret "^Something is licking your ", (name) wound.spot, ". You close your eyes."; } } else if (self.phase == 2) { if (strips hasnt worn) print "^(BUG) Phase two, but not bandaged.^"; if (self.number < 15) { self.number++; switch (self.number) { 2: if (location == Pit) print "^The bats seem less agitated now.^"; 4: if (location == Pit) print "^You're starting to feel a bit less shaky.^"; 8: if (location == Pit) print "^You're feeling considerably better.^"; } } } else if (self.phase == 3) { } ]; [ InShockOrders; Look, Inv, Examine: rfalse; Wait: "You are."; Sleep: "Soon now."; Think: "That isn't working so well either."; Smell, Listen: if (noun == 0) rfalse; "You don't have the energy to move."; default: "You don't have the energy to move."; ]; ! --- Your kit Class Bolt with name 'bolt' 'arrow' 'quarrel' 'bolts//p', short_name "bolt", plural "bolts", parse_name [; if (parser_action == ##TheSame) { if (parser_one ofclass Bolt && parser_two ofclass Bolt) return -1; return -2; } return -1; ! normal name handling ], description "Short, thick, and heavy enough to go through the beast's hide without slacking. Vicious things.", maze_pos 0; Class CrossbowPart has scenery; Object crossbow "crossbow" with name 'crossbow' 'bow', article "your", description [; print "The crossbow is well-designed enough to be simple. Laminated leaf-laths, fiber string, and a cocking lever that runs the full length of the stock.^^"; <>; ], invent [ loaded; if (inventory_stage == 1) rfalse; loaded = (child(self) ~= 0); if (loaded || self.cocked) { print " ("; if (loaded) { print "loaded"; if (self.cocked) print " and cocked"; else print " with a bolt"; } else { if (self.cocked) print "cocked"; } print ")"; } rtrue; ], before [ loaded; Search: if (ObjIsUnseeable(self)) rtrue; loaded = (child(self) ~= 0); print "The bow is"; if (loaded || self.cocked) { if (loaded) { print " loaded"; if (self.cocked) print " and cocked"; else print " with a bolt"; } else { if (self.cocked) print " empty but cocked"; } } else { print " unloaded"; } print ".^"; rtrue; Receive: if (~~(noun ofclass Bolt)) { print_ret "You can't fire ", (a) noun, " from a crossbow. (Nor can you really imagine what shape the crossbow would be in afterward.)"; } if (child(self)) "The bow is already loaded."; Cock: if (self.cocked) "The bow is already cocked."; self.cocked = true; print "You pull down the lever, winching the string back until"; if (self.seen_once == 2) { print " the kolt-pin locks behind the warden"; } else { print " it locks"; } self.seen_once++; "."; Uncock: if (~~self.cocked) "The bow is already uncocked."; self.cocked = false; "Holding the cocking lever down, you pop the string, and then carefully let the leaf-laths back out."; Reload: if (second == crossbow) "Topologically implausible."; if (~~(second ofclass Bolt)) print_ret "You really can't load ", (a) second, " into a crossbow."; if (child(self)) "The bow is already loaded."; <>; ], after [; LetGo: print "You extract the bolt from the "; if (self.cocked) print "cocked "; "crossbow."; ], cocked false, seen_once 0, maze_pos 0, add_to_scope leafarms bowstring cocklever bowmechanism stock, has container open; Object leafarms "leaf-laths" class CrossbowPart, with name 'leaf' 'lath' 'laths' 'leaf-laths' 'leaflaths' 'laminate' 'laminated', description [; print "The laminate laths of the crossbow are"; if (crossbow.cocked) print " curved far back"; else print " spread, as relaxed as they can get while strung"; "."; ], before [; Take: "Those are part of the crossbow."; Pull, Push: if (~~crossbow.cocked) "You can barely bend them, by bare hand."; else "You can't bend them any further, certainly not by hand."; Cock: <>; Uncock: <>; ], has pluralname; Object bowstring "bowstring" class CrossbowPart, with name 'bowstring' 'string' 'fiber', description [; if (~~crossbow.cocked) "The string is straight and taut."; else "The string is pulled sharply back, and immobile with the crossbow's strain."; ], before [; Take: "That's part of the crossbow."; Pull, Push: if (~~crossbow.cocked) "Even uncocked, the string is hard to pull."; else "The string is inflexible as the edge of a blade."; Cock: <>; Uncock: <>; ]; Object cocklever "cocking lever" class CrossbowPart, with name 'cocking' 'lever', description "The lever runs down the underside of the crossbow's stock, hinged at the front. It neatly covers the winch mechanism inside, but the design gives the bow much more than a straight draw.", before [; Take: "That's part of the crossbow."; Push: if (verb_word == 'move') <>; "This has no effect."; Pull: if (~~crossbow.cocked) <>; else <>; Cock: <>; Uncock: <>; ], seen_once 0; ! see ShootAtSub Object stock "stock" class CrossbowPart, with name 'stock', description "The crossbow stock is heartwood. Polished in places, worn others.", before [; Take: "That's part of the crossbow."; ]; Object bowmechanism "mechanism" class CrossbowPart, with name 'mechanism' 'winch' 'warden' 'kolt-pin' 'koltpin' 'kolt' 'pin', description "You inspected and rebuilt the crossbow before you entered the cave It doesn't need to be done again.", before [; Take: "That's part of the crossbow."; ]; Object thighband "thighband" with name 'thighband' 'band' 'leather' 'strap' 'tube', description [ count; count = children(self); print "It's a long band of heavy leather, with side straps, woven into a foot-long tube. "; if (count > 0) { if (count == 1) print "The bolt inside is "; else print "The ", (EnglishNumber) count, " bolts inside are "; print "secure yet easily slid out, "; print "and the whole "; } else { print "It "; } if (self has worn) print "is "; else print "can be "; print "strapped comfortably to your leg."; if (count == 0) print " The band is empty."; new_line; rtrue; ], invent [ count; count = children(self); if (count == 0) { print "an empty thighband"; } else { print "a thighband with ", (EnglishNumber) count; if (count == 1) print " bolt"; else print " bolts"; } if (self has worn) print " (strapped to your leg)"; rtrue; ], before [; PutOn: if (second == player or leg) <>; rfalse; Tie: if (second == player or leg) <>; "The leather straps are made to wrap around your leg, not to tie knots with."; Untie: if (second == player or leg or 0) <>; rfalse; Receive: if (~~(noun ofclass Bolt)) "The thighband is shaped only to hold your crossbow bolts."; ], after [; LetGo: print "You slide "; if (child(self)) print "a "; else print "the last "; "bolt from your thighband."; Wear: "You fasten the band back on."; Disrobe: "You unstrap the thighband."; ], maze_pos 0, has clothing container open; Object -> bolt1 class Bolt; Object -> bolt2 class Bolt; Object -> bolt3 class Bolt; Object -> bolt4 class Bolt; Object -> bolt5 class Bolt; Object lamp "lamplens" with name 'lamp' 'lens' 'lamplens' 'cord' 'rim', parse_name [ wd num lightok; lightok = (self has on && self.brightness); wd = NextWord(); while (WordInProperty(wd, self, name) || (wd == 'light' && lightok)) { num++; wd = NextWord(); } return num; ], invent [; print "a"; if (self.broken) print " cracked"; if (self has on && self.brightness) { if (self.broken) print " but still"; if (self.brightness >= 2) print " brightly-glowing"; else print " glowing"; } else { if (self.broken) print " and"; print " darkened"; } print " lamplens"; if (self has worn) print " (on your wrist)"; rtrue; ], description [; if (self has on && self.brightness) { if (self.brightness >= 2) print "A clear glareless light pours from the lamp's"; else print "A dimming light gleams from the lamp's"; if (self.broken) print " cracked face."; else print " curved face."; } else { print "The lamp's"; if (self.broken) print " cracked face"; else print " curved face"; print " is dark."; } new_line; rtrue; ], brightness 2, ! light level (if actually on). 0 means it's dead. broken 0, ! 0 is whole, 1 is cracked before [; PutOn: if (second == player or wrist) <>; rfalse; Tie: if (second == player or wrist) <>; "The flexible cord is all of a piece; it can't be tied."; Untie: if (second == player or wrist or 0) <>; rfalse; Touch, Rub: if (self has on && self.brightness) <>; else <>; SwitchOn: if (self.brightness == 0) "Nothing happens."; if (self has on) "The lamp is already on."; give self on; print "You tap the lens's rim, and it"; if (self.brightness == 2) print " shines"; else print " glimmers"; " again."; SwitchOff: !"You're no specialist -- you just use the things -- but you know that the ! mechanisms for firing these lamps are bulky and expensive. Cheaper ! to buy something compact that will sustain the light, and never go ! out."; if (self hasnt on || self.brightness == 0) "The lamp is already off."; give self ~on; "You tap the lens's rim, and it goes dark."; Repair: if (self.broken) { "You're no specialist; you just use the things. You'll be... you hope... buying a new one."; } rfalse; ], after [; Wear: "You fasten the lamp back on."; Disrobe: "You slip the lamplens from your wrist."; ], maze_pos 0, has clothing on; Object strips "cloth strips" with name 'old' 'cloth' 'ragged' 'strip' 'strips' 'bandage' 'bandages', description [; print "Ragged strips of old cloth"; if (self has worn) print ", bound around your ", (name) wound.spot; switch (wound.phase) { 1: print ". The fabric has held up quite well. Nothing has touched it in years, you suppose, but the sometime drip of mineral water"; 2: print ". The fabric is streaked dark with your blood, but it doesn't seem to be getting any worse"; 3: print ". The fabric is streaked dark with your blood"; } "."; ], invent [; if (inventory_stage == 1) rfalse; if (self has worn) print " (tied around your wounded ", (name) wound.spot, ")"; rtrue; ], before [ ix; PutOn, Insert: if (second ofclass BodyPart || second == player) { if (second == wound or player or (wound.spot)) <>; "You can't think of any reason to."; } rfalse; Tie: if (second ofclass BodyPart || second == player) { if (second == wound or player or (wound.spot)) <>; "You can't think of any reason to."; } rfalse; Untie: if ((second == player or 0) || second ofclass BodyPart) <>; rfalse; Wear: if (wound.spot == 0) "You can't think of any reason to."; Disrobe: if (self hasnt worn) rfalse; if (location provides when_unbandage) { ix = location.when_unbandage(); if (ix) rtrue; } wound.phase = 3; give self ~worn; print_ret "You carefully unwrap the cloth from your ", (name) wound.spot, ". The worst of the bleeding has stopped, although there is still a fierce ache and a slow trickle of blood."; Touch, Rub, Squeeze: if (self has worn) <<(action) wound>>; rfalse; ], after [; Wear: if (wound.phase == 3) { wound.phase = 2; print_ret "You bind the strips around your ", (name) wound.spot, " again."; } if (wound.phase ~= 1) "(BUG) Already bandaged!"; if (wound.number >= 14) print "^(BUG) Too badly hurt to be helped.^"; wound.phase = 2; wound.number = 0; print_ret "You quickly bind up your ", (name) wound.spot, " with the cloth. It stanches the bleeding, at least. You only hope that you can get to better care before infection sets in."; ], maze_pos 0, has pluralname clothing;