Constant Story "The Fox, The Dragon, and The Stale Loaf of Bread"; Constant Headline "^A Bizarre Fairytale Adventure. Story & Program by David Welbourn.^ Release 1 for IntroComp 2005. For some background info, type ABOUT.^"; Release 1; !===============NOTES=======================! ! - No contractions! (n't, 'll, 're, it's, there's) ! - PLOT POINT: ! When the Bard eats the meal in the castle, he is attacked with fire somehow. ! The player must say DONT EAT ME to prevent the fire from eating him. ! The fire will demand three things as its price for sparing him; ! these three things will have to be obtained by fox, dragon, and bread. ! - FUTURE TODO: How about songs sung instead of score points? ! That is, every time the PC might get points, he sings instead? !===========================================! Constant MANUAL_PRONOUNS; Constant MAX_SCORE = 0; Constant DIALECT_US = 1; Constant SACK_OBJECT rucksack; Global hungry = 1; Replace CTheyreorThats; Include "Parser"; Replace ScoreSub; Object LibraryMessages ! see section 21 of the manual with before [; ! and english.h Miscellany: switch(lm_n) { 11: "[You cannot ~undo~ what hasn't been done!]"; 12: "[Cannot ~undo~ twice in succession. Sorry!]"; 14: "Sorry, that cannot be corrected."; 19: "Since you are a bard, you are cursed with natural good looks. Clear, unblemished skin. Thick wavy black hair. Eyes so deep a brown, one could gaze into them forever. Except for that birthmark on your never-you-mind-where, you would be just about perfect."; 17: "It is pitch dark, and you cannot see a thing."; 22: "You cannot begin with a comma."; 23: "You seem to want to talk to someone, but it is not clear whom."; 24: "You cannot talk to ", (the) lm_o, "."; 27: "The game did not understand that sentence."; 29: "The game did not understand that number."; 30: "You cannot see any such thing."; 32: "You are not holding that!"; 33: "You cannot use multiple objects with that verb."; 35: "It is not obvious what ~", (address) pronoun_word, "~ refers to."; 38: "That verb was not recognized."; 39: "That is not something you need to refer to in the course of this game."; 40: "You cannot see ~", (address) pronoun_word, "~ (", (the) pronoun_obj, ") at the moment."; 41: "The game did not understand the way that finished."; } ListMiscellany: switch(lm_n) { 10: if (lm_o == moneypurse) print " (worn on your left hip"; rtrue; } Answer: if (second == player) "Talking to yourself again?"; Ask, Tell: if (lm_o == player) "Talking to yourself again?"; ! Attack: " That's hardly the gentlemanly thing to do."; ! Climb, Jump, JumpOver, Sleep, Tie, Fill: ! " Why would you want to do that?"; ! Cut, Dig, Burn, Consult: " Why would you want to do that? And how?"; ! Drop: switch(lm_n) { ! 1: if (lm_o has pluralname) print " ", (The) lm_o, " are "; ! else print " ",(The) lm_o, " is "; ! "already here."; ! 2: " You are not holding ", (thatorthose) lm_o, "."; ! } ! No: " Well, of course not."; Pray: "You pray to the Unseen and give silent thanks for the world and all its creatures, especially the edible ones."; Sing: "Your singing is delightful."; ! Smell: if (lm_o == player) " You smell nothing unusual. The deodorant must be working."; ! " You smell nothing unusual."; Sorry: "No need to apologize."; ! Squeeze: switch(lm_n) { ! 1: " That's hardly the gentlemanly thing to do."; ! 2: " You achieve nothing by this."; ! } Strong: "Do real bards say such things?"; Take: if (lm_n == 2) "That does not make any sense."; ! Taste: " Right now, unless it is made of cheese, you do not want to taste it."; ! Touch: switch(lm_n) { ! 1: " ~Reach out and touch someone~ may be fine for telephone ! repairmen, but not for a gentleman like yourself."; ! 2: " You feel nothing unusual."; ! 3: " Okay. You verify that you are still here. Now what?"; ! } ! Wake, WakeOther: " No one is asleep."; ! Yes: " Well, of course."; ]; Include "VerbLib"; ! STYLE NOTES: ! - Remove all contractions. See if anyone notices. !============================================================================= ! Entry point routines !============================================================================= [ Initialise; score = 0; lookmode = 2; ! verbose on location = Mountain_Trail; move rucksack to player; move moneypurse to player; move knife to player; move walking_stick to player; print "^^^~My hike was long, ov@'er this peak.^More than a day, less than a week.^ Come hear the tale I have to speak,^Hey diddle diddle aye-oh.^^ ~A brand new town I soon shall see.^New people, I shall sing for thee.^ A happy bard then I shall be,^Hey diddle diddle aye-oh.^^ ~But first I must find food to eat.^I ate my cheese! I ate my meat!^ An apple core would be a treat,^Hey diddle diddle aye-oh.^^ ~No rabbits found I for my pot.^I looked for roots. I found them not.^ These hunger pains! They must be fought!^Hey diddle diddle aye-oh.^^ ~Why do no birds fly overhead?^Would not roast fowl taste good with bread?^ When was the last time that I fed?^Hey diddle diddle aye-oh.~^^^"; ! It has been a long hike over this mountain pass, but soon, soon you will arrive in a new ! country and back to civilization. New sights, new people, new opportunities.^^ ! And not a moment too soon. Your skill as a huntsman proved inferior to your ! skill as a bard. You would have roasted a rabbit over a fire if you could, ! but you never found any rabbits. Or any other animals. Even the birds avoided ! your path. Strange. It has been a lonely little journey.^^The roots, berries, and mushrooms ! you expected to find do not grow ! this high up in the mountains. And you ate the last of your sausage and cheese ! two days ago.^^You are positively famished.^^^"; ]; [ ChooseObjects obj code; switch (code) { 0: ! code 0 == Parser is excluding obj from ALL; accept parser's decision rfalse; 1: ! code 1 == Parser is including obj in ALL if (action_to_be == ##Take) { if (obj has scenery || obj has static) return 2; ! dont include scenery/statics in TAKE ALL } rfalse; 2: ! Parser is asking for 'appropriateness' hint if (action_to_be == ##Enter) { if (obj == short_boulder) return 1; } return 0; } ]; [ DeathMessage; if (deadflag == 3) print "The intro is over * Your destiny awaits"; ]; !============================================================================= ! Replaced routines !============================================================================= [ CTheyreorThats obj; ! *** No contractions! *** if (obj == player) { print "You are"; return; } if (obj has pluralname) { print "They are"; return; } if (obj has animate) { if (obj has female) { print "She is"; return; } else if (obj hasnt neuter) { print "He is"; return; } } print "That is"; ]; [ ScoreSub; if (deadflag == 0) "There is no score in this game."; ]; !============================================================================= ! Other useful routines !============================================================================= [ emph str; style underline; print (string) str; style roman; ]; [ strong str; style bold; print (string) str; style roman; ]; ! ---------------------------------------------------------------------------- ! CLASSES ! ---------------------------------------------------------------------------- Class OutdoorRoom with u_to "No obvious path goes upward from here. Unless you want to try flying or climbing something.", d_to "No obvious path goes downward from here. Unless you want to try digging into the ground.", has light; Class Prop with before [; Examine: rfalse; default: print_ret "You do not need to worry about ", (the) self, "."; ], has scenery; Class Distant with before [; Examine: rfalse; default: print_ret (CThatOrThose) self, " ", (IsOrAre) self, " too far away."; ], has scenery; !Class MyContainer !with ! short_name [; ! if (self hasnt open) print "closed "; ! else if (child(self) == 0) print "empty "; ! else print "open "; ! rfalse; ! ], ! has container; !----------------------------------------------------------- ! Your initial inventory: ! - rucksack, ! -- tinderbox, lute, bag of spices. ! - moneypurse ! - knife ! - walking stick !----------------------------------------------------------- Object rucksack "rucksack" with name 'sack' 'ruck' 'rucksack', description "It is your rucksack. Simple, but dependable.", before [; Receive: if (noun == walking_stick) "The walking stick is too long to fit inside the rucksack."; Smell: "Carrying the rucksack out in the open for a week has done wonders. You can hardly smell the spilt wine on it at all."; ], has container ~open openable; Object tinderbox "tinderbox" rucksack with name 'tinderbox' 'tinder' 'box' 'old' 'small' 'battered', description "A small battered tinderbox made of tin, containing the necessary tools for lighting a fire. Your father helped you put it together when you were a boy, and it is the oldest thing you own.", before [; Open, Close: "[You do not need to open or close the tinderbox. Just type LIGHT WITH TINDERBOX when you want to start a fire.]"; ]; Object lute "lute" rucksack with name 'pine' 'lute' 'catgut' 'strings' 'instrument', article "your", description "Your lute is perhaps your most prized possession, since it provides you with your livelihood, but you could build another if you had to. Master Dorien showed you how to carve its pear-shaped body out of pine, how to lightly string it with catgut so the instrument does not break under its own tension, and (of course) how to tune the thing fifty times a day. It is very lightweight and somewhat delicate.", before [; Play: "You play a few chords on the lute."; ThrowAt: "Never would you treat a lute so."; Tune: "You spend a few moments to tune the lute."; ]; Object spicebag "bag of spices" rucksack with name 'brown' 'bag' 'of' 'spices' 'spice' 'tiny' 'leather' 'spicebag', description [; print "It is a tiny brown bag of soft leather that contains your motley collection of spices."; if (self has open) " The bag is open and unlaced, revealing some mixed spices."; else " It is laced tightly closed."; ], ! short_name [; ! if (action == ##Inv) { ! if (self has open) print "open "; else print "closed "; ! } ! rfalse; ! ], parse_name [ wd num gotit; ! TODO: if refering to just "spices", prefer the actual spices over the bag when they're in scope. ! Otherwise, it's okay to refer to the bag as just "spices". wd = NextWord(); while (WordInProperty(wd, self, name)) { if (wd == 'bag') gotit = true; num++; wd = NextWord(); } if (self hasnt open) gotit = true; if (~~gotit) return 0; return num; ], before [; LetGo, Empty: "It would be foolish to waste precious spices to no purpose."; Receive: if (noun ~= spices) "Only spices belong in your spice bag."; Search: if (self has open) "Inside the bag are some mixed spices."; else "The bag of spices is closed."; Smell: "You stifle a sneeze after you do so."; ], after [; Open: "You open the bag, revealing mixed spices."; ! Close: "You close the bag of spices."; ], has ~open openable container; Object spices "mixed spices" spicebag with name 'mixed' 'spices' 'spice' 'mixture' 'salt', article "some", description "A mixture of salt, pepper, crushed garlic, and chives - but mostly salt. When you are lucky enough to catch wild game, you like to sprinkle on a little of this onto the meat to make it extra tasty. Just looking at the spices makes your mouth water.", before [; Eat: "You cannot eat spices by themselves! You would only make yourself sick if you did that."; Smell: "The spices smell wonderful!"; Take, Remove: "You cannot pick up the mixed spices with your bare hands. Just sprinkle them on your food directly from the bag."; Taste: "You moisten a finger and dab a little of the mixed spices onto your tongue. Mmm. Salty."; ], has pluralname; Object moneypurse "moneypurse" with name 'moneypurse' 'money' 'purse' 'cloth' 'black', article "your", description "A small cloth moneypurse, dyed black.", ! FUTURE TODO PROBLEM: coins not listed when purse is open. ! invent [; ! if (inventory_stage == 2) ! { print " (which is "; ! if (self has open) print "open"; else print "closed"; ! if (self has open && mycoins notin self) ! { print " but empty"; ! if (self has worn) print ","; ! } ! if (self has worn) print " and worn on your left hip"; ! print ")"; rtrue; ! } ! rfalse; ! ], before [; Receive: if (noun ~= mycoins) "Only coins and gems belong in your moneypurse."; ], after [; Wear: "You gird your moneypurse back onto your left hip."; ], has container ~open openable worn clothing; Object mycoins "coins" moneypurse with name 'coins' 'coin' 'money' 'copper' 'coppers' 'silver' 'pieces' 'piece', description "Hmm. Nine coppers and two silver pieces.", has pluralname; Object knife "knife" with name 'knife' 'short', description [; print "A short servicable knife"; if (self.is_bloodied) print " currently stained with blood"; ". It would not be much good in a fight, but every bit helps."; ], is_bloodied 0, invent [; if (inventory_stage == 2) { if (self has worn) print " (worn on your right hip)"; rtrue; } rfalse; ], before [; Wear: if (self.is_bloodied) { self.is_bloodied = 0; print "Absent-mindedly, you clean the blood from the knife. "; rfalse; } Take, Pull: if (self in beartrap) { if (beartrap in nail) { move knife to player; move nailtwin to beartrap; "You pull the knife out from the trap's jaws, and the trap SNAPs around the head of the rusty iron nail."; } else { move knife to player; "You pull the knife out from the trap's jaws, and the trap SNAPs fully closed."; } } Rub: if (self.is_bloodied) { self.is_bloodied = 0; "You clean the blood from the knife."; } ], after [; Wear: "You gird your knife back onto your right hip."; ], has worn clothing; Object walking_stick "walking stick" with name 'walking' 'stick' 'staff' 'wood' 'wooden', description "It is a sturdy walking stick just over five feet long. You made it yourself by trimming a fallen tree branch that you found soon after you began your trek through the mountains almost a week ago.", before [; Take, Pull: if (self in beartrap) { if (beartrap in nail) { move self to player; move nailtwin to beartrap; "You pull the walking stick out from the trap's jaws, and the trap SNAPs around the head of the rusty iron nail."; } else { move self to player; "You pull the walking stick out from the trap's jaws, and the trap SNAPs fully closed."; } } ]; !----------------------------------------------------------- ! First Part: ! 1) where you start: Mountain Trail ! 2) where you meet the fox: Tall Pines ! 3) between fox and dragon: By the Firepit ! 4) where you meet the dragon: Jumble of Rocks ! 5) between dragon and bread: Mountain Vale ! 6) where you meet the bread: Bend in the Path ! 6b) where bread "flies": Scenic View ! 7) after you meet the bread: Foothills !----------------------------------------------------------- ! ---------------------------------------------------------------------------- OutdoorRoom Mountain_Trail "Mountain Trail" with description [; print "You are on a lonely mountain trail. Trees grow sparsely this high up on the mountain, and even less so back up the trail to the northeast. To the west, the trail heads down past the treeline into a forest."; if (self hasnt general) { give self general; print "^^And not a moment too soon. You are positively famished."; } new_line; ], trees_desc "Pine trees, mostly. Short and thin.", ne_to "You spent most of the last week traversing that mountain pass. You are not going back that way now.", w_to [; if (Tall_Pines hasnt visited) print "You make your way down the mountain. As you pass the treeline, you hear a loud SNAP! followed by a sharp cry of pain.^"; else print "You turn around and go back down the mountain, into the trees.^"; return Tall_Pines; ], d_to [; return self.w_to(); ], u_to [; return self.ne_to(); ], cant_go "It is best not to wander off the trail. You could get lost, or worse, risk a fall.", ; ! ---------------------------------------------------------------------------- OutdoorRoom Tall_Pines "Tall Pines" with description "The mountain trail continues under a canopy of tall shady pine trees. The trail continues down to the southwest, and up to the east.", trees_desc "You are pleased to be amongst trees again, to be enclosed in their most welcome shelter.", sw_to By_the_Firepit, e_to [; print "You climb back up the mountain, past the treeline onto open trail.^"; return Mountain_Trail; ], d_to [; if (child(beartrap) == fox) { if (fox.oathstate == 0) "You cannot ignore the fox. Think of the meal it might make."; if (fox.oathstate == 2) "You must fulfill your promise and free the fox from the steel trap."; } return self.sw_to(); ], u_to [; return self.e_to(); ], cant_go "The trail goes down to the southwest, and back up to the east.", ; Object beartrap "steel trap" Tall_Pines with name 'steel' 'trap', initial [; print "To one side, you see a "; if (child(beartrap) == deadfox) print "dead "; else if (fox has female) print "lady "; print "fox"; if (child(beartrap) == fox) { if (fox has female) print ", her"; else print ", its"; print " hind leg caught fast in a steel trap"; } "."; ], description [; print "The steel trap is like a jaw: two rows of zigzag metal ~teeth~ hinged on one side"; if (self has open) ". The trap is currently open, its heavy spring at high tension. Anything put inside that deadly circle is likely to trigger it."; else { print ", with a heavy spring holding them clamped together"; if (child(self)) { print ".^^Well, almost together. The steel trap is currently clamped around "; if (child(self) == fox or deadfox) print "the hind leg of ", (a) child(self); else print (the) child(self); } if (self in nail) print " and is loosely clamped around ", (the) nail; "."; } ], before [ obj; Open, Pry: if (child(self) == fox) <>; else if (child(self) == deadfox) <>; else { if (self notin location) "Put the trap on the ground first."; ! FUTURE TODO: auto-Take, auto-Drop, and tests } Take: if (self has open) "Picking up an open steel trap would be extremely hazardous to your fingers."; obj = child(self); if (obj == fox or deadfox) <>; else if (obj == nailtwin) return nail.success(); else if (self in nail) { move self to player; "Taken."; } Receive: if (self hasnt open) "But the steel trap is not open."; if (noun == walking_stick or knife) { move noun to self; give self ~open; "You insert ", (the) noun, " into the trap, which dutifully SNAPs shut on it, leaving a gap."; } "You do not want to put that into the steel trap."; Pull: if (self in nail) <>; ], after [ obj; Close: if (walking_stick in player) obj = walking_stick; else if (knife in player) obj = knife; else obj = 0; if (obj) "You insert your ", (name) obj, " into the trap and it dutifully SNAPs shut, leaving a gap. You then carefully pull ", (the) obj, " out, so the trap's jaws can close fully."; else "You find a rock somewhere and throw it at the trap's trigger. SNAP! The jaws close on empty air."; Open, Pry: print "You open the trap."; if (child(self)) { print " ", (The) child(self), " falls out."; move child(self) to location; } new_line; rtrue; ], has openable container transparent; ! Use the female attribute to tell whether we've looked at the fox yet. Object fox "fox" beartrap with name 'lady' 'mother' 'fox' 'reynard' 'vixen', is_examined 0, description [; give self female; if (self.is_examined == 0) StartDaemon(fox); self.is_examined = 1; "This is a full-grown lady fox, with a cloth cap on her head and a steel trap on one leg. Despite her obvious pain, she neither cries nor whimpers, but watches your every move with wide brown eyes."; ], oathstate 0, ! 0 = no offer; 1 = offer made; 2 = offer accepted; -1 = offer denied. number 0, saved 0, daemon [; self.number++; switch (self.number) { 1: "^Your stomach chooses this moment to growl."; 3: "^You have never eaten fox before, but doubtless it is similar to rabbit."; 5: "^You wonder which part of the fox might be the most tasty."; 6: StopDaemon(self); } ], makeoffer [; self.oathstate = 1; print "But the sight of the knife terrifies the captured animal! ~DON'T EAT ME!~ it says weakly."; if (self hasnt female) { give self female; print " Its voice is female."; } print "^^The words, faint as they are, freeze you where you stand. It's not merely that you're never heard a fox speak before. You haven't. But somehow, she has invoked magic here. Like a ritual. Or a promise. Or an oath. ^^~DON'T EAT ME,~ the fox says again, stronger now. Or perhaps the world has gone silent instead, to hear her all the better. ~If you spare me and free me, I will help you later. You will not regret it. ^^~Do you accept my offer?~ >>"; if (YesOrNo()) { self.oathstate = 2; StopDaemon(self); move babydragon to Jumble_of_Rocks; "^A sudden breeze blows by; leaves fly by in its wake. ~Then free me, man,~ says the fox."; } else { self.oathstate = -1; "^The scene darkens briefly as a cloud passes over the face of the sun. ~So be it,~ says the fox, and says no more."; } ], ! caution: life property invokes the steel trap isn't open test. before [; ! Attack: if (parent(knife) == player) <>; else "You will need a knife to kill her properly."; Attack: if (child(beartrap) == fox) { if (fox.oathstate == 0) { print "Intending to make short work of the fox, you take out your knife. "; move knife to player; give knife ~worn; self.makeoffer(); rtrue; } else if (fox.oathstate == 2) "You have promised the fox not to kill it."; else move foxcap to deadfox; foxcap.is_bloodied = 1; knife.is_bloodied = 1; remove self; move deadfox to beartrap; "You quickly slice open the fox's neck; it dies instantly. Blood now stains your knife and hands, but that couldn't be helped."; } else "TODO"; Kiss: "You prefer to kiss only your own species."; Cut: <>; Eat: if (child(beartrap) == fox && fox.oathstate == 0) { print "Before you can eat the fox, you will have to kill it. You take out your knife. "; move knife to player; give knife ~worn; self.makeoffer(); rtrue; } else <>; Free: if (child(beartrap) ~= fox) "The fox has already been freed."; else if (fox.oathstate == 0) "And lose a potential meal?"; else { if (second == 0) { if (walking_stick in player) second = walking_stick; else "You'll need a tool of some kind to pry open the trap."; } if (second == knife) "Close. You cannot use the knife for this without cutting yourself or risking more injury to the fox. You need something more like a knife with another handle at the sharp end."; else if (second == lute) "The lute is too large and too fragile to be handled this way."; else if (second == walking_stick) { move beartrap to player; give beartrap ~open; remove fox; fox.saved = 1; "It's awkward, but using the walking stick as a lever, you successfully pry the steel trap open without causing further damage.^^Freed of the trap, the fox gets gingerly to her feet. ~I thank you, man. I will remember my promise to you, and return when your need for me is greatest. Until then, fare well.~ You watch as she hobbles away into the forest and is lost from view.^^You then take a moment more to SNAP the trap closed and pick it up. Waste not, want not."; } else { print (The) second, " seem"; if (second has pluralname) print "s"; " ill-suited to this task."; } } Take: if (child(beartrap) == fox) { if (fox has animate) "It would be dangerous to pick up a wild animal while it is alive and wounded."; "It is too awkward to carry both fox and trap together. You should separate them first."; } "It would be dangerous to pick up a wild animal while it is alive and wounded."; Push, Pull, Touch: print "The fox bares its teeth. "; if (self has female) "She doesn't want you to touch her."; else "It doesn't want you to touch it."; ], has animate edible transparent; Object foxcap "cloth cap" fox with name 'cloth' 'cap' 'fox^s', is_bloodied 0, description [; print "The fox's cap is made of unbleached linen and crudely embroidered with the word ~MOM~ in russet threads."; if (self.is_bloodied) print " Unfortunately, it's also ruined, splattered by the fox's blood."; new_line; ], short_name [; if (self.is_bloodied) { print "bloodied "; rfalse; } ], before [; Take: if (self in deadfox) { move self to player; "You remove ", (the) self, " from ", (the) deadfox, "."; } Wear: "The cap is somewhat too small for you."; ], has clothing; Object deadfox "dead fox" with name 'dead' 'fox' 'reynard' 'vixen' 'meat' 'carcass' 'body' 'slab', skinned 0, cooked 0, ! initial [; ! print "To one side, you see a dead fox"; ! if (child(beartrap) == self) print ", its hind leg caught fast in a steel trap"; ! "."; ! ], short_name [; if (self.cooked) print "slab of fox meat"; else if (self.skinned) print "fox carcass"; else print "dead fox"; rtrue; ], description [; print "This is ", (a) self, ". "; if (self.cooked) "It's cooked and ready to eat!"; else { print " Before you can eat it, you'll need to "; if (child(beartrap) == self) print "remove the steel trap, "; if (foxcap in deadfox) print "remove the cloth cap, "; if (~~self.skinned) print "skin it, and "; "cook it. (Sprinkling on some spices is optional.)"; } ], before [; Cook: if (self.skinned == 0) "You have yet to skin the animal first."; Cut: if (second == 0 && knife in player) second = knife; if (second ~= knife) "That is not a suitable cutting tool."; if (knife notin player) "Where is your knife?"; if (child(beartrap) == self) "Your knife is not quite good enough to cut the fox's leg off. You will have to remove the trap some other way."; if (self.skinned == 0) { if (foxcap in deadfox) { ; new_line; } self.skinned = 1; move foxpelt to player; knife.is_bloodied = 0; give knife worn; remove foxcap; "You begin the messy work of skinning the fox. First you turn the fox onto its back and make a long vertical incision...^^Let us make a long story shorter. When you are done, you have a carcass of uncooked fox meat and a fox pelt. Incidently, you made a bundle with the fox's cap and the unedible bits and chucked it far off into the forest. You also cleaned off your knife and put it back on your hip."; } else print_ret (The) self, " has already had its pelt removed."; Eat: if (self.cooked == 0) "You have never eaten a fox raw, and you are not about to start now."; Free: if (child(beartrap) ~= self) "The fox has already been freed."; else { if (second == 0) { if (walking_stick in player) second = walking_stick; else "You'll need a tool of some kind to pry open the trap."; } if (second == lute) "The lute is too large and too fragile to be handled this way."; else if (second == walking_stick or knife) { move beartrap to player; give beartrap ~open ~scenery; move deadfox to player; if (second == walking_stick) print "It's awkward, but using "; else print "Using "; print_ret (the) second, " as a lever, you successfully pry the steel trap open. After the fox's leg falls free, you carefully SNAP the trap closed and pick up both it and the fox's body. Waste not, want not."; } else { print (The) second, " seem"; if (second has pluralname) print "s"; " ill-suited to this task."; } } Smell: if (self.cooked) "It smells like mutton."; else if (self.skinned) "It smells like bloody meat. No surprises there."; else <>; Take: if (child(beartrap) == self) "It is too awkward and messy to carry both fox and trap together. You must remove the trap first."; ], after [; Eat: hungry = 0; "You eat the cooked fox meat. Not bad. For fox meat, that is."; ], has edible transparent; Object foxpelt "fox pelt" with name 'fox' 'pelt' 'skin' 'fur', description "It has soft fox fur on one side, and bloody skin on the other. You are not sure what it is worth, but perhaps you can trade it for a nice bottle of wine.", before [; Smell: "Ignoring the blood, the fur smells slightly of pine oil. No musk smell, but it was a lady fox, after all."; Touch: "Soft and luxurious."; ]; ! ---------------------------------------------------------------------------- OutdoorRoom By_the_Firepit "By the Firepit" with description "The trail widens here, passing through a small level clearing. A thick forest of trees surrounds the clearing. From here, you can follow the trail down to the west, or up to the northeast.", w_to Jumble_of_Rocks, ne_to Tall_Pines, d_to [; return self.w_to(); ], u_to [; return self.ne_to(); ], cant_go "The trail goes down to the west, and back up to the northeast."; Object firepit "firepit" By_the_Firepit with name 'old' 'firepit' 'pit' 'circle' 'of' 'white' 'stones', description [; print "The firepit is just a circle of white stones at the side of the trail. "; if (kindling in self) print "It does not look like it has been used for a long time. "; <>; ], initial [; print "To one side of the trail, there is an old firepit"; if (bonfire in self) print " (containing a bonfire)"; ", and a short boulder sits beside it."; ], has container open static; Object kindling "dry twigs and leaves" firepit with name 'dry' 'twigs' 'leaves' 'kindling', description "A loose collection of dry twigs and leaves has conveniently fallen into the firepit. You could not ask for better kindling.", before [; Take: "Why bother? The kindling is perfectly placed, right where is it."; Search: "The dry twigs and leaves have nothing to hide."; Burn: if (tinderbox notin player) "You need your tinderbox to start a fire."; remove self; move bonfire to firepit; "Using your tinderbox, you easily set the twigs and leaves ablaze."; ], has pluralname static; Object bonfire "bonfire" with name 'bonfire' 'fire' 'flame' 'flames', description "A cheery bonfire burns within the pit.", before [; Burn: "The bonfire is already burning."; Extinguish: if (self hasnt general) { give self general; "You belatedly notice that you have no good way of putting out the fire. You suppose you could chisel out enough dirt from the ground and try to smother it that way, but by then it should burn out on its own. So why not leave it? It looks safe enough. It will not be going anywhere. (You hope.)"; } "No. Leave it. It will be fine."; Smell, Taste: "Not getting that close, thank you."; Take, Touch: "Burnt fingers? No, thank you."; ], has static; Object short_boulder "boulder" By_the_Firepit with name 'short' 'boulder' 'rock' 'gray' 'grey', description "It is just an ordinary gray boulder, but it is just the right size to sit on and has been pushed up close to the firepit.", before [; Push, Pull: "The boulder is just fine where it is."; ], after [; Enter: if (verb_word == 'sit') "You rest your Johnny-sit-me-down on the boulder."; ], has enterable supporter scenery; ! ---------------------------------------------------------------------------- OutdoorRoom Jumble_of_Rocks "Jumble of Rocks" with name 'rocks' 'cairn' 'rockslide', description "The mountain trail crosses east to west over uneven and broken ground; a wagon could have real trouble passing through here. Rockslides from the north pose an additional ongoing hazard.", trees_desc "Not too many trees here. There are too many rocks, you suppose. There are more trees further down the mountain, of course, so you still cannot see where this trail ends.", road_desc "The trail is quite a mess here. Lots of broken rock from higher up the mountain.", w_to [; if (babydragon in location) { if (babydragon.oathstate == 0) "You cannot ignore the dragon. Two words: dragon steak."; if (babydragon.oathstate == 2) "You must fulfill your promise and pull the nail from the dragon's paw."; } return Mountain_Vale; ], e_to By_the_Firepit, n_to "There is a name for people who climb treacherous rockslides. ~Dead.~ Do not go that way.", s_to "That way down the mountain is a bit too steep. The safe road down is west.", d_to [; return self.w_to(); ], u_to [; return self.e_to(); ], cant_go "The trail goes down to the west, and back up to the east."; Object babydragon "baby dragon" ! Jumble_of_Rocks with name 'baby' 'dragon' 'green' 'hatchling', initial [; if (nail in self) "Lying on one of the rock piles, a baby dragon is crying pitiously."; "Lying on one of the rock piles, a baby dragon licks its injured foot with its long, sinewy tongue."; ], is_examined 0, saved 0, description [; if (self.is_examined == 0) StartDaemon(babydragon); self.is_examined = 1; print "The baby dragon has green scales with a blue underbelly and is about the size of an adult wolf."; if (nail in self) print " It is lying on its back and whimpering, probably because of the rusty iron nail stuck in its left foot."; new_line; ], oathstate 0, ! 0 = no offer; 1 = offer made; 2 = offer accepted; -1 = offer denied. number 0, daemon [; self.number++; switch (self.number) { 1: "^Dragon steak is supposed to be a delicacy. This must be your lucky day."; 3: "^It is fortunate the dragon is so young. Its scales do not look any worse than fish scales. Your knife should have little trouble at all."; 5: "^Mmm, ", (emph) "baby", " dragon steak. Can you dare imagine how tender its flesh might be?"; 6: StopDaemon(self); } ], makeoffer [; self.oathstate = 1; print "As with the fox, the sight of your knife conveys your terrible intent only too well. ~DON'T EAT ME!~ says the dragon, between sobs."; print "^^Startled, you stop in place. Did this creature of myth and legend, young as it is, truly speak? No, no, that cannot be. Not eat it? Of course you want to eat it. You're hungry! ^^~DON'T EAT ME,~ the baby dragon says again, more forcefully, and there is no mistaking it this time. Your ears seem to roar as the words echo within your head. You hear nothing else. ~If you spare me and pull this nail out of my paw, I will help you later. You will not regret it. ^^~Do you accept my offer?~ >>"; if (YesOrNo()) { self.oathstate = 2; StopDaemon(self); move staleloaf to Bend_in_the_Road; "^Without warning, a dove flies west, singing joyfully, the first bird you have heard in days. ~Then please. Pull out this nail,~ says the baby dragon."; } else { self.oathstate = -1; "^~No? No? You will not?,~ cries the dragon child. It lifts its head and screams in anguish. And if in answer, a shelf of the mountain loses its grip and crashes down, narrowly missing the two of you. Subdued, the dragon whimpers more quietly thereafter."; } ], life [; !TODO Attack: if (nail in babydragon) { if (babydragon.oathstate == 0) { print "Intending to make short work of the dragon, you take out your knife. "; move knife to player; give knife ~worn; self.makeoffer(); rtrue; } else if (babydragon.oathstate == 2) "A promise is a promise. You are oathbound not to kill the creature."; else move nail to deaddragon; knife.is_bloodied = 1; remove self; move deaddragon to location; "You plunge your knife into the dragon's breast; it struggles and keens like a mad thing. One of its claws gashes your forehead. The pain is dreadful, but it spurs you on to stab the beast repeatedly. ^^At last the dragon is dead. There is blood everywhere. You feel no sense of victory in such a kill. Perhaps the dragon's flesh itself will taste better."; } else "TODO"; Ask, Tell: if (nail in self) "The baby dragon just whimpers in pain."; Kiss: if (nail in self) "You cannot kiss it better."; "That is not going to happen."; ! Give, Show: "TODO"; ! ThrownAt: "TODO"; default: if (nail in self) "The baby dragon just whimpers in pain."; ], before [; Burn: "Dragons are said to be fireproof."; Cut: <>; Eat: if (nail in babydragon && babydragon.oathstate == 0) { print "Before you can eat the baby dragon, you will have to kill it. You take out your knife. "; move knife to player; give knife ~worn; self.makeoffer(); rtrue; } else <>; Free: if (nail in self) <>; ], has animate transparent edible; Object deaddragon "dead baby dragon" with name 'dead' 'baby' 'dragon' 'corpse' 'body' 'meat' 'steak' 'carcass', initial "Lying on one of the rock piles is the corpse of a baby dragon.", skinned 0, cooked 0, short_name [; if (self.cooked) print "cooked dragon steak"; else if (self.skinned) print "raw dragon steak"; else print "dead baby dragon"; rtrue; ], description [; print "This is ", (a) self, ". "; if (nail in self) print " It has a rusty iron nail stuck in its left foot."; if (self.cooked) "It's cooked and ready to eat!"; else { print " Before you can eat it, you'll need to "; if (~~self.skinned) print "cut it up, and "; "cook it. (Sprinkling on some spices is optional.)"; } ], before [; Cook: if (self.skinned == 0) "You have yet to cut the beast up first."; Cut: if (second == 0 && knife in player) second = knife; if (second ~= knife) "That is not a suitable cutting tool."; if (knife notin player) "Where is your knife?"; if (self.skinned == 0) { if (nail in deaddragon) { move nail to player; print "Now that the dragon is dead, there is no reason why you cannot just cut into the foot and take the nail. So you do so.^^"; give deaddragon ~container; } self.skinned = 1; knife.is_bloodied = 0; give knife worn; move self to player; "** Time passes. **^^The eternal anatomy of a dragon proves to be quite a strange thing. Many of the internal organs are unfamiliar to you, and you doubt that all of them are safe for a person to eat. Eventually you do find some normal looking muscle tissue, and cut yourself out a nice healthy portion. ^^You clean off your knife, and for a moment think you are done, but no. You are unwilling to leave the corpse by the roadside where it might attract scavengers, so you cover the body with several pieces of nearby rock, making a crude cairn. Boy, this dragon steak better be good!"; } else "You have no desire to cut up the dragon steak any smaller."; Eat: if (self.cooked == 0) "You like your dragon steaks well done."; Smell: if (self.cooked) "Mmmm. A meal fit for a king or wizard."; else if (self.skinned) "It smells rich. Sort of like beef, sort of like duck."; else "It does not smell too good, to be honest. Vinegary."; Take: if (self.skinned == 0) "You do not feel like carrying the entire dragon, small as it is. Cut out some meat and take it back to that firepit you passed."; Receive: "You cannot put anything into ", (the) self, "."; ], after [; Eat: hungry = 0; "You chew the dragon steak thoughtfully. It ", (emph) "is", " a good steak, but something is not quite right. Perhaps it is because you are not a chef. Chefs always have secret ingredients to add to food to make them taste better. Or perhaps it is because you are not in a great dining hall and currently bereft of table, cutlery, goblets of wine, and good company.^^You do not understand it. Dragon steak is supposed to be one of the best meals one can have, and you find yourself disappointed. It feels wrong. But... if the best is wrong, then what is right? Mmm. Damn good steak, though."; ], has edible container transparent; Object nail "rusty iron nail" babydragon with name 'rusty' 'iron' 'nail', description [; if (nail in babydragon) "The nail is embedded pretty deep in the baby dragon's foot. It looks like one of those long nails used to hold a wagon wheel on its axle. Ouch. That must be incredibly painful."; else "It looks like one of those long nails used to hold a wagon wheel on its axle."; ], success [; ! Assume beartrap on the nail, nail in the dragon, nailtwin in the beartrap. move beartrap to player; remove nailtwin; move nail to beartrap; give beartrap ~open; give nail ~supporter; remove babydragon; StopDaemon(babydragon); babydragon.saved = 1; print "With the steel trap firmly gripping the nail between its teeth, you are able to grab onto the trap in turn, and pull the troublesome nail out of the baby dragon's paw. Before your disbelieving eyes, the wound heals in seconds without the iron nail to prevent it.^^The child of dragons, no longer sobbing, gets to its feet. Its large reptilian eyes stare at you, and you back up a step. You suddenly realize you are face-to-face with a deadly monster. It is still only the size of a wolf, true, but that is plenty big enough, and somehow you forgot that wolves can be dangerous too."; "^^~Be at peace,~ says the dragon. ~I have no love of mankind, nor that hated iron. But you alone need not fear me. You have helped me as I asked and our bargain stands. I will remember my promise to you, and return when your need for me is greatest. Until then, fare well.~ You stop breathing when the dragon jumps, but it is only to catch the air in its leathery wings, and then it flies off into the distance.^^The tension in your body relaxes, and you start breathing normally again. You also remember that you are still hungry."; ], before [; Pull, Take: if (self in babydragon) { if (babydragon.oathstate == 0) "Hold on. That nail is probably the only thing keeping the dragon here. If you remove it, your (yum) meal will fly away."; if (child(beartrap) == nailtwin) return self.success(); "Sensing your intent, the dragon holds still as you approach. You grasp the nail with your bare hand and pull, but it is no use. You just cannot get a strong enough grip on it. You will need a tool of some kind."; } if (self in beartrap) { move self to player; "You pull ", (the) self, " out from the trap's jaws, and the trap SNAPs fully closed."; } Receive: if (babydragon.oathstate == 0) "Why fiddle with the nail when you could be eating dinner?"; if (noun ~= beartrap) "Putting that on ", (the) self, " is not likely to help. Something else, maybe?"; if (child(beartrap) == 0) "Good idea. The steel trap should get a better grip on the nail than your fingers. Unfortunately, the trap is closed."; if (child(beartrap) == walking_stick or knife) { move beartrap to nail; "Aha. With ", (the) child(beartrap), " holding the trap slightly open, you are able to put the trap on the nail. That is, the nail is now in the gap between the trap's jaws.^^The dragon watches you curiously as you perform this operation."; } ], has supporter; ! This is the part of the nail inside the beartrap, as opposed to the nail that's inside the dragon. ! We need this since the object model doesn't allow one object to be inside two things at once. Object nailtwin "rusty iron nail" with ! no name please! has concealed scenery; ! ---------------------------------------------------------------------------- OutdoorRoom Mountain_Vale "Mountain Vale" with description "The ground dips down here into a small valley on the mountainside, and a much greater variety of trees compete for the space here. Fortunately, even though the road is covered with leaves, it is still wide enough to see that it goes both southwest and east.", sw_to Bend_in_the_Road, e_to Jumble_of_Rocks, d_to [; return self.sw_to(); ], u_to [; return self.e_to(); ], ; ! ---------------------------------------------------------------------------- OutdoorRoom Bend_in_the_Road "Bend in the Road" with name 'gutter', description "The road bends sharply here around a large boulder, heading up to the northeast and down to the southeast. A lesser travelled footpath goes south.", ne_to Mountain_Vale, se_to [; if (staleloaf.saved == 0) { if (staleloaf.oathstate == 0) "You sigh. You cannot ignore the stale loaf of braad. You are starving."; if (staleloaf.oathstate == 2) "You must fulfill your promise and give the bread to the birds."; print "You cannot wait any longer. "; <>; } return Foothills; ], s_to [; if (Scenic_View has visited) print "Again, you push through the trees to the scenic view.^"; else print "The path is overgrown, forcing you to duck and push branches out of the way. Suddenly, there are no more trees, and you look up and see what they hid.^"; StartDaemon(scenic_birds); return Scenic_View; ], d_to [; return self.se_to(); ], u_to [; return self.ne_to(); ], road_desc "The mountain road is in sad shape here. There are deep ruts in the soil, which would make going around this boulder rather awkward if you weren't on foot. But since you are on foot, you also have the option of travelling down a shady trail southward.", cant_go "Your choices are northeast, southeast, and south.", before [; Listen: "Now that you stop to listen, you do hear birds somewhere to the south."; ]; Prop boulder "boulder" Bend_in_the_Road with name 'boulder', is_examined 0, description [; print "It is as tall as you, five times as wide, and only the Unseen know how heavy."; if (self.is_examined == 0) { self.is_examined = 1; print "^^You sing to yourself: ~The obdurate obelisk. It makes no sound. It moveth not. So go around.~"; } new_line; ]; Object staleloaf "stale loaf of bread" ! Bend_in_the_Road with name 'stale' 'loaf' 'of' 'bread' 'grainma' 'old' 'toast', initial "A stale loaf of bread has fallen into a gutter on the far side of the road.", is_examined 0, description [; if (self.is_examined == 0) { self.is_examined = 1; StartDaemon(self); } print "A reddish-brown loaf of bread, gone hard and stale."; if (self.oathstate == 0) " Apart from being a item of food, it looks totally unremarkable."; else if (self.cooked) " You have toasted it into something a little more edible."; else " You never knew stale loaves of bread could talk, but it has been a strange day."; ], oathstate 0, ! 0 = no offer; 1 = offer made; 2 = offer accepted; -1 = offer denied. cooked 0, saved 0, ! has the loaf been returned to the birds? number 0, daemon [; self.number++; switch (self.number) { 1: "^Bread. Food. Mine, mine, mine."; 3: "^Sure, it may be a ", (emph) "stale", " loaf of bread, but you do not care at this point."; 5: "^Into the mouth and over the gums, look out stomach, here it comes. Let us start eating!"; 6: StopDaemon(self); } ], makeoffer [; self.oathstate = 1; give self female; print "When you pick up the loaf of bread, it suddenly shakes and squeals, ~DON'T EAT ME!~"; print "^^You have ", (emph) "got", " to be kidding me. Baked goods are inanimate objects and they do not talk. You must be delirious from hunger. Yes, of course. The strange events of the day are repeating in your mind and you only think that the bread is talking. Of course the cure to such delusions is to digest some food..."; print "^^~DON'T EAT ME,~ the stale loaf of bread says again, and you cannot help but notice it is ", (emph) "scolding", " you, just like Grandma Zedna did when you tried to steal some cookies. The voice of ~Grainma~ continues, ~I am not food to eat. I am a ", (strong) "bird", ". Uh-huh. Looks like delirium is contagious."; print "^^~I was riding on the back of a wagon when it hit a bump in the road and I fell here. I think my wings are broken; I could not fly away. I need to rejoin my fellow birds who can help me. Please. I can hear some birds just south of here. If you spare me and take to them, I will help you later. You will not regret it.^^~Do you accept my offer?~ >>"; if (YesOrNo()) { self.oathstate = 2; StopDaemon(self); "^You feel you must be out of your mind, but you agree. ~Wonderful,~ says Grainma. ~Take me to them.~ ^^Birdsong trills to the south. It is a fool's errand, but you are losing your taste for food that talks to you. So why not humor the old bread?"; } else { self.oathstate = -1; "^You refuse to agree to do anything so ludricous. A cold breeze from up-mountain chills the air; you shiver in its wake. ^^~Fool! You will be sorry. You wait and see. I hope you choke!~ says the stale loaf of bread, spitefully."; } ], before [; Attack: "Perhaps you want to eat it instead?"; Ask, Tell: if (self.oathstate == 0) "You can only do that to something animate."; "[Alas, talking to the stale loaf of bread isn't implemented yet. Wait for the full game.]"; Cook: if (self.oathstate == 2) "You may not cook it. You promised to take it to the birds instead."; Cut: "That is not necessary."; ! FUTURE TODO Eat: if (self.oathstate == 0) <>; if (self.oathstate == 2) "You may not eat it. You promised to take it to the birds instead."; Kiss: print "A kiss, a nibble. What is the difference when it is bread? "; <>; Take: move self to player; if (self.oathstate == 0) { self.makeoffer(); rtrue; } else "Taken."; Give, ThrowAt: if (second == scenic_birds) return self.saveloaf(); ], after [; Cook: "You toast the stale loaf of bread. It looks and smells better than before. It didn't seem to enjoy the experience, though."; Drop: if (verb_word == 'throw' && location == Scenic_View) return self.saveloaf(); Eat: hungry = 0; "You gnaw the stale loaf of bread by bits and pieces. It is old, dry, and without much flavor. Munch, crunch, chew, swallow. Fortunately it stops screaming by the time a third of it is gone."; ], saveloaf [; remove self; self.saved = 1; StopDaemon(scenic_birds); "You throw the stale loaf of bread over the cliff towards the birds, and for a moment it seems to hover in mid-air. ^^~Bless you! I am free! Free!~ the bread shouts. ~I will remember my promise and return to youuuuuu....~ ^^Oh dear. Look at it plummet. And there goes every bird in the sky after it. My my. Goodness, what a racket those birds are making."; ], has animate edible; ! ---------------------------------------------------------------------------- OutdoorRoom Scenic_View "Scenic View" with description [; ! if (self hasnt visited) print "Oh. Such grandeur. What spectacle is this?^^"; print "You stand at the top of a cliff overlooking a lake far below. The expanse is breathtaking. Look there at that lake so clear and blue: it contains a small wooded island, and on that island is a curious white dome. Or look at that cliff. Tall it is here, and tall it remains as it traverses a great C-shaped arch around the lake. Halfway into that arch is a majestic waterfall, pouring its liquid bounty into the waters below. Then look you further. Also on the cliff, opposite and across the lake, is a village and castle."; if (self hasnt visited) print " Be it a true kingdom or the strange keep of barbarians, you do not know, but it must be an abode of men. Civilization, at last. ^^The scene as a whole sings with vitality and life. Scarcely have you seen a place so pregnant with power, so rich in air, earth, and water."; " Alas, no path from here proceeds. You must needs regain your road to the north."; ], cant_go "The trees block all movement away from the cliff except back north.", tree_desc "The trees block all movement away from the cliff except back north.", road_desc "The path ends here. It is overgrown and little used, but it does go back north to the mountain road.", n_to [; StopDaemon(scenic_birds); print "You push through the trees, back to the road.^"; return Bend_in_the_Road; ], s_to "It would be suicidal to walk off the cliff.", d_to "If you really want to go down the cliff and smash against the rocks below, then jump. But it is not recommended.", before [; Jump: "[Perhaps in the full game, you may be allowed to jump to your death. But not now. Not today.]"; Listen: if (noun == nothing or scenic_birds) { PrintOrRun(scenic_birds,initial); rtrue; } if (noun == scenic_waterfall) "Yes, you can faintly hear the roar of the waterfall from here."; ]; Object scenic_birds "birds" Scenic_View with name 'birds' 'bird' 'gull' 'parrot' 'owl' 'finch' 'sparrow' 'robin' 'goose' 'duck' 'bluejay', is_examined 0, initial [; "You hear the ", (string) random("screeches","hoots","caws","chirping"), " of ", (string) random("several","many"), " birds having a ", (string) random("noisy","loud","raucous"), " ", (string) random("argument","to-do","disagreement"), " below the cliff."; ], description [; print "Most of the birds are not visible, since they are somewhere below you down the cliff. But every so often one or two fly up mere yards out of reach, but within throwing distance, shall we say."; if (self.is_examined == 0) { self.is_examined = 1; print "^^What ", (emph) "is", " peculiar is just how many different types of birds there seem to be down there. What could the attraction be?"; ! Gulls, parrots, owls, finches, sparrows, robins, geese, ducks, bluejays, and more. } new_line; ], daemon [ n; n = random(3); if (n == 1) "^A", (string) random(" gull", " parrot", "n owl", " finch", " sparrow", " robin", " goose", " duck", " bluejay"), " ", (string) random("flies up","appears","zooms in"), " from below and ", (string) random ("squawks at one of its fellows", "travels in a lazy circle above the lake", "seems to attack one of the other birds", "flaps its wings furiously", "screams something in pidgin Pigeonese", "hoots loudly in your direction"), ". ", (string) random ("Then it dives back down again", "Cawing, it then flies out of sight", "Another bird gives you the eagle eye before flying down below", "Several nearby birds all chirp at once, and one plummets toward the lake"), "."; ], life [; Show: "The birds seem to be ignoring you."; ], before [; Ask, Tell, Order: "The birds ignore you. Maybe birds speak a different language."; Attack: print "The birds may be flying relatively close by, but they are still out of reach"; if (walking_stick in player) print " from a swing of your walking stick"; "."; Examine: rfalse; ThrownAt: "Perhaps you could throw ", (the) noun, " at a bird, but to what end? Even if your aim was true, both bird and ", (name) noun, " would fall and be lost, leaving you worse off than before."; default: "Those are too far away."; ], has animate pluralname static; Distant scenic_cliff "cliff" Scenic_View with name 'cliff', description "Of the part of the cliff on which you stand, you can see little but the grass and weeds at your feet. You must be on an outcropping of sorts and the rock wall must curve inwards, for you can see only the lake below and no hint of any beach or whatever the birds are squabbling about.^^Further away, encircling the lake, the cliff is a testament to ages past, recorded in the strata laid bare. Although the layers of rock are in many hues, the dominant color is a pale yellow bronze flecked with gold. Indeed, you think the wall sparkles with the glint of gold, but that may well be a trick of the light.^^Only two more details intrude upon the cliff's face: the waterfall, and a thin vertical line underneath the castle.", before [; Climb: "You cannot. The cliff here bows inward, providing no place to put your feet."; ]; Distant scenic_castle "castle" Scenic_View with name 'castle' 'building' 'village' 'line', description "Directly south of you, on top of the opposite cliff, is a village dominated by a small castle. It is difficult to see many details, but the village buildings have the reddish brown colour of mud or brick. The castle, however, is made of gray stone and has the outline of an upside-down M: a pointed roof with a tower on either side.^^Hm. You do not see any movement, nor flags, nor pennants, but that does not mean much of anything. You also note that a thin black line runs vertically down from the castle, over the cliff face, and into the lake, but you have no idea what it is."; Distant scenic_lake "lake" Scenic_View with name 'lake', description "The lake is deep deep blue and far far below you. You are looking south and can only see the eastern half of it, bounded by the semi-circular cliff. The lake is obviously fed by the great waterfall east of the lake, but it is not clear where the outflow is. There must be another river north or west from here. The island is in the center of the lake, or at least the center of the portion you can see."; Distant scenic_island "island" Scenic_View with name 'white' 'dome' 'island', description "The island is fairly small and about halfway between you and the castle. There are some trees and shrubs on the island, but the dominant feature is a large white dome shaped like a giant's thimble. You can not imagine what the dome is made of or what it is for. It is the color of chalk, but no chalk ever gleamed so brightly."; Distant scenic_waterfall "waterfall" Scenic_View with name 'river' 'water' 'waterfall' 'mist' 'rainbow', description "A huge waterfall is falling from the top of the eastern side of the cliff and into the lake far below. Every now and then, you can see a faint rainbow within its attendent mist: one end appearing in the waterfall itself, and the other end on the dome on the island."; ! ---------------------------------------------------------------------------- OutdoorRoom Foothills "Foothills" with description [; print "You are in the foothills of the local mountain range, where a variety of weeds and ", (name) crocuses, " grow between the trees and tree stumps. The road begins its ascent into the mountains to the northwest. To the southeast, the road continues on a more gentle slope into farmland."; if (self hasnt visited && fox.saved && babydragon.saved && staleloaf.saved) print "^^You cannot help thinking you have racked up a lot of karma today. ", (emph) "Somebody", " owes you big time."; new_line; ], road_desc "The dirt road rises up to the northwest, but levels out to the southeast.", trees_desc "The trees that still standing look like healthy specimens of birch and ash to your untrained eye.", nw_to Bend_in_the_Road, se_to Farmlands, u_to [; return self.nw_to(); ], ; Object stumps "stumps" Foothills with name 'tree' 'stumps' 'stump', description "On another day, it might make you a bit sad to see a forest so despoiled, to see living trees turned into this ruin. But it also means men must be nearby, men who build homes and furniture. Or maybe, even now, they are burning wood from these trees to cook their suppers. Mmm, supper.", has scenery enterable supporter pluralname; Object weeds "weeds" Foothills with name 'weeds', description "The weeds are common, unedible, and unimportant.", has scenery pluralname; Object crocuses "flowers" Foothills with name 'purple' 'flowers' 'crocuses' 'flower' 'crocus', is_examined 0, short_name [; if (self.is_examined) print "crocuses"; else print "purple flowers"; rtrue; ], description [; self.is_examined = 1; "The flowers have large veiny blue-purple petals surrounding a cluster of yellow tree-like formations in the center. They have a strange kind of beauty. You recognize them as crocuses."; ], before [; Take: "[You cannot pick one of these flowers in the IntroComp version of this game. Sorry.]"; Smell: "The ", (name) self, " have no scent. Odd."; ], has scenery pluralname; ! ---------------------------------------------------------------------------- OutdoorRoom Farmlands "Farmlands" with description "This part of the road passes by barren farmland to the east. Although the view is uninteresting in the extreme, at least the land is flat, the road is straight, and the stones are few, for which your feet are truly thankful. To the south, you see a bridge.", road_desc "It is a simple north/south dirt road.", e_to "There is nothing to be gained by entering such an empty field.", nw_to [; <>; ], n_to Foothills, s_to North_of_Bridge, ; Object field "farmer's field" Farmlands with name 'farmer^s' 'field' 'farm' 'farmland' 'land' 'soil', description "Nothing grows on the field, not even grass, nor has it been plowed recently. Perhaps the farmer has let the field go fallow this season, but it looks abandoned to you.", before [; Enter: <>; ], has scenery; Object farmbridge "bridge" Farmlands with name 'bridge' 'river', description "From here, it looks like a normal wooden bridge crossing a normal river.", before [; Examine: rfalse; default: "It's too far away."; ], has scenery; ! ---------------------------------------------------------------------------- OutdoorRoom North_of_Bridge "North of Bridge" with description "You are on the north side of a bridge. Farmlands are north, or go south over the bridge.", road_desc "The plain dirt road is wide enough for a large cart and comes in from the north and ends south at the bridge.", before [; Swim: "No way. The river looks far too dangerous to swim in. And there's no reason to when there is a perfectly good bridge."; ], n_to Farmlands, s_to [; print "You tramp noisily over the bridge.^"; return South_of_Bridge; ]; Object bridge "bridge" with name 'wooden' 'bridge', description "The bridge is fully as wide as the road it serves, but apart from its size, it is not very impressive. It is crudely constructed from many wooden planks laid side-by-side. If it were not for the short railings on either side (also of wood), it would look like nothing more than a gigantic raft.^^You also note with some surprise that the bridge is barely high enough to clear the water. As a result, several of the bridge's planks are wet, filthy, or warped. Still, better to have a bridge like this than no bridge at all.", found_in North_of_Bridge South_of_Bridge, has scenery; Object river "river" with name 'river' 'water', description "The river is both surprisingly wide and fast-moving, flowing from the east to the west. The turbulence makes it difficult to tell how deep the water is. Fortunately, there is a bridge here and you can cross the river easily.", found_in North_of_Bridge South_of_Bridge, before [; Enter: <>; Drink: "You're more hungry than thirsty, but you drink a few handfuls of water anyway. Can't hurt."; Receive: if (noun == walking_stick) "You find a relatively dry and clean piece of the bridge to lie down on and carefully lower the stick into the water, making sure you grip the stick tightly. It touches the river bottom with only a foot remaining the surface. From this, you estimate the river depth at four feet. You then haul the stick out from the water before the current gets a chance to steal it from you."; else "You are in no hurry to lose ", (the) noun, " to the river."; ], has scenery container open; ! ---------------------------------------------------------------------------- OutdoorRoom South_of_Bridge "South of Bridge" with description [; print "The south side of the bridge is somewhat more thrilling than the north side. The road on this side is made of green bricks, and it continues south towards a village."; if (self hasnt visited) print " And surely, where there's a village, there must be food! Huzzah! A good meal at last."; new_line; ], road_desc "The bricks in the road are about six by three inches in size and are painted dark green. Underneath, where the paint has worn away, you can see the reddish clay or terra cotta or whatever bricks are made from. The road itself goes north and south.", n_to [; print "You tramp noisily over the wooden bridge.^"; return North_of_Bridge; ], s_to [; print "The brick road turns west before entering the village proper.^"; print "^As you approach the village, you decide to sing:^ ~Ohhhhh, the fish was long and the fish was wide ^ But you will never ever guess what I found inside...~"; deadflag = 3; rtrue; ! return Village_East; ], sw_to [; <>; ]; ! ---------------------------------------------------------------------------- OutdoorRoom Village_East "East End of Village" with description "You are in an abandoned village. The gates of a castle are west, or you can leave the village to the northeast.", ne_to South_of_Bridge, w_to Castle_Gates, ; ! ---------------------------------------------------------------------------- OutdoorRoom Castle_Gates "Castle Gates" with description "You are outside a large castle. The village is east.", e_to Village_East, ; ! ---------------------------------------------------------------------------- ! Some scenery objects that can be found in several places ! ---------------------------------------------------------------------------- Prop trees "trees" with name 'tree' 'trees', description [; if (location provides trees_desc) print_ret (string) location.trees_desc; "The trees are numerous here."; ], before [; Climb: "None of the trees here are suitable for climbing."; ], found_in Mountain_Trail Tall_Pines By_the_Firepit Jumble_of_Rocks Mountain_Vale Bend_in_the_Road Scenic_View Foothills, has pluralname; Prop clouds "clouds" with name 'cloud' 'clouds' 'sky', description "It is a beautiful day. The clouds are solid patches of white, full and plump.", found_in Mountain_Trail Tall_Pines By_the_Firepit Jumble_of_Rocks Mountain_Vale Bend_in_the_Road Scenic_View Foothills Farmlands North_of_Bridge South_of_Bridge Village_East Castle_Gates, has pluralname; Prop road "road" with name 'road' 'path', description [; if (location provides road_desc) print_ret (string) location.road_desc; "You see nothing interesting about the road itself."; ], found_in Mountain_Trail Tall_Pines By_the_Firepit Jumble_of_Rocks Mountain_Vale Bend_in_the_Road Scenic_View Foothills Farmlands North_of_Bridge South_of_Bridge Village_East Castle_Gates; Prop mountain "mountain" with name 'mountain', is_examined 0, description [; print "Mountains are big. Really really big. You cannot truly appreciate just how tediously big they are until you try to walk over them. Calling it a great big rock may be true, but that does not tell the full truth of it. You have to be there."; if (self.is_examined == 0) { self.is_examined = 1; print "^^This particular great big rock dominates the northern part of the compass. You do not know its name, but it surely must have one. Perhaps more than one. You once heard a story about a mountain with two names. If you climbed it when it had its first name, you simply reached the top. But if you climbed it when it had its other name, its secret name, then you arrived somewhere else. And yet, it was the same mountain both times."; } new_line; ], found_in Mountain_Trail Tall_Pines By_the_Firepit Jumble_of_Rocks Mountain_Vale Bend_in_the_Road; ! ---------------------------------------------------------------------------- [ AboutSub; print (strong) "The Fox, The Dragon, and The Stale Loaf of Bread", " got its initial inspiration from Emily Short's game "; print (strong) "Savoir-Faire", ". Yes, I know. This game is nothing like that one. Let me explain."; print "^^What happened was that Emily and I had a brief little discussion on the ifMud about how objects were coded in her game. Apparently some game-objects represented multiple objects within the game, and I interpreted this to mean that some objects were like extras in a theatre play. So, perhaps in the Living Room, Joe Extra played the role of the fox on the wallpaper, but in the Bedroom, Joe Extra played the role of the dragon carving."; print "^^Well, I was wrong about that. That wasn't how Emily did it at all. But I still liked the idea of the fox, the dragon, and yes, the stale loaf of bread being actors, and then I started thinking of them as NPCs and PCs, and, well, I like fairy tales, and thus was born the idea of this unlikely trio helping some other guy on his quest. That guy being you. You help them out, and then they'd be obligated to help you out. Simple enough."; print "^^Simple, except for one of the trio being a stale loaf of bread. That's really ", (emph) "weird", " y'know? What motivates a loaf of bread? What can it possibly do to help? That's going to be a fun question to answer."; "^^By the way, I must apologize for the complete lack of testing in this game. I foolishly left things until the very last minute, and I know that the game is not as robust or as bulletproof as I'd like. Hopefully, the Spirit of IntroComp will bless this mess, understanding that the beginning of a game is going to lack a little completeness in any case."; ]; [ CookSub; if (noun hasnt edible) "Only edible things can be cooked."; if (location ~= By_the_Firepit) "There is nothing nearby to cook with."; if (location == By_the_Firepit && bonfire notin firepit) "There is no fire in the pit to cook with."; if (AfterRoutines()==1) rtrue; if (noun provides cooked) { if (noun.cooked) print_ret (The) noun, " is already cooked."; noun.cooked = 1; "You cook ", (the) noun, ". It looks and smells wonderful."; } "It would be better to leave ", (the) noun, " uncooked."; ]; [ DontEatMeSub; "[Aren't you the clever one? That puzzle hasn't been implemented yet, and already you know the answer! Shh. Don't tell.]"; ]; [ ExtinguishSub; "You cannot extinguish something that is not burning."; ]; [ FreeSub; print_ret (The) noun, " does not need rescuing."; ]; [ PlaySub; "That is not something you can play."; ]; [ PourSub c; if (noun has container) { if (noun notin player && AttemptToTakeObject(noun)) return; if (second == d_obj) <>; } else { c = parent(noun); if (c has container) { if (c notin player && AttemptToTakeObject(c)) return; if (second == d_obj) <>; } } "[Pouring and sprinkling is not yet properly supported. It will be in the full game.]"; ! "That is not something you can pour."; ]; [ PrySub; if (noun hasnt openable) print_ret (The) noun, " ", (isorare) noun, " not something that can be opened."; if (noun has open) print_ret (The) noun, " ", (isorare) noun, " already open."; "That is not something you can pry."; ]; [ TuneSub; "That is not something you can tune."; ]; ! ---------------------------------------------------------------------------- Include "Grammar"; Extend 'eat' replace * noun -> Eat; Extend 'put' * 'out' noun -> Extinguish * noun 'out' -> Extinguish; Verb meta 'about' * -> About; Verb 'cook' 'toast' * held -> Cook; Verb 'extinguish' 'douse' * noun -> Extinguish; Verb 'free' 'rescue' * noun -> Free * noun 'with' held -> Free; Verb 'gird' * held -> Wear; Verb 'play' 'strum' 'pluck' * held -> Play; Verb 'pour' * 'out' noun -> Empty * noun 'out' -> Empty * noun 'into'/'on'/'onto'/'over' noun -> Pour; Verb 'pry' 'jimmy' 'prise' * noun 'with' held -> Pry * 'open' noun 'with' held -> Pry * noun 'open' 'with' held -> Pry; Verb 'skin' * noun -> Cut * noun 'with' held -> Cut; Verb 'sprinkle' * noun 'onto'/'on'/'over'/'into' noun -> Pour; Verb 'tune' * held -> Tune; Verb 'dont' 'don^t' * 'eat' 'me' -> DontEatMe; !----- ! IDEAS ! ! There are halls in the heavens above that open only to the voice of song. --The Zohar ! (one of the cloud country gates should only open in response to birdsong.)