Constant Story "SEARCH FOR THE SORCERER'S STONE"; Constant Headline "^An Interactive Fiction Game^by Aimee Walls^"; Constant DEBUG; Constant BONE_STATE = 0; Constant SLEEP_STATE = 1; Constant GUARD_STATE = 2; Constant ANNOY_STATE = 0; Constant EAT_STATE = 1; Include "parser"; Include "verblib"; Include "grammar"; ! Begin Game Inititalization with a luring phrase [ Initialise; print "Would you like to restore a game? >"; if (YesOrNo()) ; location = Throne_Room; StartDaemon(terrier_head); StartDaemon(retriever_head); print "^^^^^It's a dreary day outside, but a large door leads the way to find the sorcerer's stone. All you need to do is get through it somehow...^^"; ]; [ Inside x y; do { x = parent(x); } until (x == 0 or y); if (x == 0) rfalse; ]; ! In case player tries to examine themself in mirror, print message [ ReflectSub; if (second ~= magic_mirror) "What a strange idea!"; print "The magic mirror "; if (noun == player) print "you"; else print (name) noun; print " looks just like the real "; if (noun == player) print "you"; else print (name) noun; " only all reversed, left for right."; ]; !Extend user action 'Reflect' Extend "look" * "at" noun "in" noun -> Reflect; Extend "examine" * noun "in" noun -> Reflect; !-------------------------------------------------------------------------------------------------------------- ! Throne Room Objects !-------------------------------------------------------------------------------------------------------------- !Throne room leads to door by way of north Object Throne_Room "Throne room" with name "throne", description "The low hiss of stinging rain pounding outside makes an eery melody with the steady pound of your beating heart. Inside, you observe a vast, regal room of sandstone, with large, cathedrial ceilings. The room is filled with objects of noble importance: a purple velvet throne among others. Your feelings of smallness and vulnerability are compounded with the sights of an oversized animal bed, chew bone, and a woven floor rug. A large wooden door beckons you, but is guarded by a ferocious, two headed dog, part yellow labrador, part cairn terrier.", n_to WoodDoor has light; !The door is initially shut, locked, and guarded by two-headed dog unless dog is not in GUARD_STATE !If player gets past door, shut down two headed dog and Start the Troll into laboratory !Door leads to laboratory Object -> WoodDoor "wood door" with description "It's a large, foreboding wooden door with a heavy iron latch.", name "door" "massive" "big" "wood", when_closed "Passage North is barred by a massive wood door.", when_open "The door be open...proceed at your risk....", door_to laboratory, door_dir n_to, with_key gold_key, before [ i; Unlock: if (terrier_head.state == GUARD_STATE) i = terrier_head; else if (retriever_head.state == GUARD_STATE) i = retriever_head; if (i ~= 0) "You are about to start unlocking the door when you notice that ", (the) i, " is right in the way. It's a good thing you stopped, or you would have been eaten in one bite!"; Enter: StopDaemon(retriever_head); StopDaemon(terrier_head); StartDaemon(wish_nick); ], has static door openable lockable locked; !Descriptive objects throne and window are here for added effect Object throne "throne" Throne_Room has light with name "purple" "royal" "throne", description "It is a regal purple velvet and stone edifice.", before[; Climb,Enter: move player to throne; "You sit stiffly in the large, uncomfortable throne.";]; Object window "window" Throne_Room has scenery with name "window" "pane", description "Outside the window it's raining heavily, the sky black as night.", before [; Open: "You wouldn't want to get wet, would you? Better leave the window shut."; Search: <>; ]; !Bone is used to distract part of a dog head away from the door object bone "bone" Throne_Room with name "toy" "chew" "chew-toy" "chew toy" "bone", describe [; if (terrier_head.state == BONE_STATE || retriever_head.state == BONE_STATE) rtrue; ], with description "A disgusting, slimy piece of raw hide, whittled to next to nothing. . .", before [; drop: "I have a bone of contention to make with you...."; ], after [; Take: if (terrier_head.state == BONE_STATE) terrier_head.state = GUARD_STATE; if (retriever_head.state == BONE_STATE) retriever_head.state = GUARD_STATE; ], has light; !Flask is used to distract dog away from door object flask "flask" Throne_Room has scenery with name "flask" "chemical" "vial", with description "An elegant flask of Nyquil, a sleeping aid. It is emerald green in color, probably misplaced from the laboratory", before [; drop: "The flask thumps on the ground. . ."; ], has light; !Gold key, hidden under the animal bed, is used to unlock the door object gold_key "gold key" Throne_Room has scenery with name "gold" "key" "gold key", with description "A beautifully carved solid gold key made by an ancient farmer from Madagascar", before [; drop: "I wouldn't do that: everyone needs a way to unlock their potential......"; ], has light; !Animal bed hides the key, but other possible user actions are accounted for (take, push, pull) Object animal_bed "animal bed" Throne_Room has concealed static supporter enterable ! general if you've found the flute under it with name "dog bed" "animal-bed" "bed" "dog-bed" "soft bed" "animal bed", description "An oversized animal bed, made for a giant beast of some sort. It could nearly fit you, but the stench from it kills any thoughts of lying down on it.", before [; Take: "The bed is much too large and heavy for you to carry."; Push,Pull: "But a bed isn't meant to be moved!"; LookUnder: if (player in self) "You try to lift up a corner of the bed, but fail because you are standing on it."; if (self hasnt general) { give self general; move flask to player; "You lift up a corner of the bed and, peering underneath, discover a small glass flask"; } ]; !Rug conceals the flask but other actions (lift while standing on) are accounted for Object rug "rug" Throne_Room has concealed static supporter enterable ! general if you've found the key under it with name "throne rug" "throne-rug" "rug" "royal-rug" "royal rug" "beautiful" "soft", description "It's a royal rug, woven with gold thread and purple velvet.", before [; Take: "The rug is much too large and heavy for you to carry."; Push,Pull: "But a rug is meant to lie around!"; LookUnder: if (player in self) "You try to lift up a corner of the rug, but fail. After a while, you realise that this is because you are standing on it."; if (self hasnt general) { give self general; move gold_key to player; "You lift up a corner of the rug and, peering underneath, discover the gold key."; } ]; !--------------------------------------------------------------------------------------------------------- !Laboratory objects !--------------------------------------------------------------------------------------------------------- Object laboratory "Laboratory" with description "A messy, cluttered room full of glass beakers and flasks holding all sorts of dangerous concoctions. Peculiar details such as a thick carpet made of moss, a table of ivy covered stone, and a chair coated in seaweed only make sense to you when you realize that this laboratory is inhabited by a troll! Before you lies a mirror, framed in platinum. Five bottles sit on the table in order from left to right: Mini Flask, Tiny Bottle, Medium Flask, Giant Bottle, Large Flask", has light; !chair is a scenic object for added effect, but you may sit in it Object seaweed_chair "chair" laboratory has light with name "seaweed" "seaweed chair" "slimy" "sea-weed" "sea-weed chair" "chair", description "It is an overstuffed, squatty little piece of furniture.", before[; Climb,Enter: move player to seaweed_chair; "You sit stiffly in the slimy, squishy chair.";]; !Table is another added effect that holds the five bottles Object table "table" laboratory has light with name "ivy table" "table" "ivy" "ivy stone table" "stone" "stone table" with description "It is a granite colored, solid table covered in twisted ivy."; !Magic mirror holds the end of the game if the player has the correct bottle with him !If he does, player will see the future and win the game !Otherwise it's just a descriptive object Object magic_mirror "magic mirror" laboratory has static concealed with name "mirror" "magic" "magic-mirror" "magic mirror", description [; if (giant_wine notin player && dwarf_wine notin player) "Framed in platinum, the oval mirror evokes a sense of mystery in all it reflects."; if (giant_wine in player || dwarf_wine in player) "You begin to sense something more with this magic mirror."; ], before [; Pull,Push: "The platinum frame is much to heavy for you to move."; ThrownAt: "You don't want seven years' bad luck, do you?"; Touch: if(dwarf_wine in player || giant_wine in player) { ! Let's get the sorcerer's stone deadflag = 2; "Equipped with your psychic powers, the mirror begins to reflect the future. You see yourself finding the sorcerer's stone, learning that it has been with you all along! With this powerful realization you feel the sorcerer's stone drop into your pocket as if it had been with you for eternity."; } "You touch the mirror but nothing unexpected occurs."; ]; !Carpet conceals the mushroom which is used to distract the pesky troll, other actions accounted for object carpet "carpet" laboratory has concealed static supporter enterable ! general if you've found the mushroom under it with name "mossrug" "moss-rug" "carpet" "green", description "It's a matted, thick carpet of green moss.", before [; Take: "The carpet is much too large and heavy for you to carry."; Push,Pull: "But a moss carpet cannot be dragged!"; LookUnder: if (player in self) "You try to lift up a corner of the carpet, but fail. After a while, you realise that this is because you are standing on it. How curious the world is!"; if (self hasnt general) { give self general; move mushroom to player; "You lift up a corner of the moss carpet and, peering underneath, discover a large shittake mushroom."; } ]; !Mushroom has a distracting effect on trolls object mushroom "mushroom" laboratory has scenery with name "shittake" "mushroom" "shittake mushroom", describe [; if (wish_nick.state == EAT_STATE) rtrue; ], with description "A pungent, rather large fungus, probably from Asia", before [; drop: "Although it is unpleasant, your junk is another creature's treasure......."; ], after [; Take: if (wish_nick.state == EAT_STATE) wish_nick.state = ANNOY_STATE; ], has light; !Scroll is a helpful tool in selecting the correct bottle !Scroll may be read only after troll is distracted !Scroll gives clues to the bottles to take object scroll "scroll" laboratory with name "paper" "letter" "scroll", with description "An ancient piece of parchment, thin enough to see through, but inscribed as follows:", before [i; Examine: if (wish_nick.state == ANNOY_STATE) i = wish_nick; if (i ~= 0) "You are about to read the scroll when you are nearly knocked over by the troll whizzing past you. What a pest!"; ], after [; Examine:"Two of us bottles will help you. Three of us will kill you. Choose one of the five bottles, or we will keep you here forevermore. To help you in your choice, we give you these clues four. First, however slyly the poison tries to hide, you will always find some to the left of nettle wine's side; Second, different are those that stand at either end, but if you would move onward, neither is your friend; Third, as you see clearly, all are different size, neither dwarf nor giant holds death in their insides; Fourth, the second left and the second right, are twins when you taste them, though different at first sight."; ], has light; !------------------------------------------------------------------------------------- !Five bottles are defined, three of which kill the player, two of which help the player !------------------------------------------------------------------------------------- Object mini_flask "Mini Flask" laboratory with name "mini flask" "mini", with description "A bottle larger than tiny bottle but smaller than medium flask, peach in color", before [; Drink, Take: deadflag = 1; "You gulp down the bottle, and, realizing its poison, collapse on the floor."; ], has concealed; Object dwarf_wine "Tiny Bottle" laboratory with name "tiny bottle" "tiny", with description "The tiniest bottle, deep currant in color", before [; Drink: "You must take the bottle before you drink it!"; ], after [; Take: "You take the bottle and gulp down the wine, and although sour, magically floods your entire body. Suddenly you have the wisdom of the world and can see into the future"; ], has concealed; Object medium_flask "Medium Flask" laboratory with name "medium flask" "medium", with description "A bottle larger than tiny bottle and mini flask but smaller than large flask, aqua in color", before [; Drink, Take: deadflag = 1; "You gulp down the bottle, and, realizing its poison, collapse on the floor."; ], has concealed; Object giant_wine "Giant Bottle" laboratory with name "giant bottle" "giant", with description "The largest bottle, pale yellow in color", before [; Drink: "You must take the bottle before you drink it!"; ], after [; Take: "You take the bottle and gulp down the wine, and although too sweet, magically floods your entire body. Suddenly you have the wisdom of the world and can see into the future"; ], has concealed; Object large_flask "Large Flask" laboratory with name "large flask" "large", with description "A bottle larger than medium flask but smaller than giant bottle, copper in color", before [; Drink, Take: deadflag = 1; "You gulp down the bottle, and, realizing its poison, collapse on the floor."; ], has concealed; !--------------------------------------------------------------------------------------------------------------------- !Class objects : Puppy and Troll !--------------------------------------------------------------------------------------------------------------------- !Puppy is an animate object that will have randomized actions and various states based on certain conditions Class Puppy has animate ! general if it's been described this turn with parse_name [ w ok n; do { ok = 0; w = NextWord(); if (w == 'puppies' or 'dogs') { ok = 1; n++; parser_action=##PluralFound; } if (w == 'puppy' or 'pup' or 'dog' || w == ((self.&name)-->0)) { ok = 1; n++; } } until (ok == 0); return n; ], !Three states, Guard, Sleep, and Bone, are defined !Guard: guarding the door without distraction !Bone: distracted with a bone in the throne room !Sleep: distracted with sleep from the throne room state GUARD_STATE, describe [ i; switch (self.state) { SLEEP_STATE: "^A ", (name) self, " is sleeping."; BONE_STATE: "^A ", (name) self, " is playing with a raw hide bone."; GUARD_STATE: if (self has general) rtrue; if ((self.other_puppy).state == 3) { i = self.other_puppy; give i general; "^A two-headed dog, one retriever and one terrier, is guarding the wood door."; } "^A ", (name) self, " is growling by the wooden door."; default: rtrue; } ], description [; "What a fierce, but rather dumb beast ", (the) self, " is."; ], !We take care of possible user/puppy interactions that are not useful to game outcome !We also define how the puppy will move from state to state with object interferences life [; Ask,Answer,Order: print_ret (The) self, " cocks its head from side to side, not amused and losing its already diminishing patience with you."; Kiss: "You give ", (the) self, " a little kiss on its nose, and it barks loudly, foaming rabidly at the mouth."; Attack: "You would never do such a stupid thing to such a large, seething animal!"; Show: print_ret (The) self, " bats a paw at ", (the) noun, "."; Give,ThrowAt: !If object isn't useful, do nothing, otherwise, print message and switch states if (noun ~= bone && noun ~= flask) { if (action == ##ThrowAt) { move noun to Throne_Room; print "You toss ", (the) noun, " onto the floor, but ", (the) self; } else print (The) self; " just examines ", (the) noun, " with a dumb, idiotic expression."; } print "You toss ", (the) noun, " onto the floor and ", (the) self; if (self in player) print " squirms out of your grasp and"; move noun to Throne_Room; move self to Throne_Room; print " scampers sloppingly after it"; if (noun == bone) { give bone general; self.state = BONE_STATE; print ", quickly turning the nasty bone into an even slimier mess"; } else { give flask general; self.state = SLEEP_STATE; print ", drinking the NyQuil and falling into a deep slumber"; } "."; ], before [; Take: "Believe me, you don't want to hold such a smelly, frightening animal"; ], !Now we define a random function and give some actions that a puppy might take during !each of the created states bone, guard, and sleep daemon [ i; give self ~general; self.this_puppies_turn = 1 - self.this_puppies_turn; if (self.this_puppies_turn == false || random(3) == 2) rtrue; new_line; print (The) self; switch (self.state) { BONE_STATE: give bone general; switch (random(5)) { 1: " bats at the bone with its paw."; 2: " stops playing and sits up, stupidly looking around him."; 3: " knocks the bone across the floor and chases after it."; 4: " stops to scratch itself."; 5: " bites the bone and shakes it to make sure that it's dead."; } SLEEP_STATE: switch (random(5)) { 1: " scratches his hind leg uncontrollably."; 2: " snores loudly."; 3: " gets up, circles and flops again in a big heap."; 4: " moves all fours and howls lightly."; 5: " opens one eye then yawns and nods off again."; } GUARD_STATE: if ((self.other_puppy).state == GUARD_STATE && random(2) == 1) { i = random(5); switch (i) { 1: print " chases after "; 2: print " jumps on top of "; 3: print " washes "; 4: print " runs around the dog bed and "; 5: print " paws at "; } print (the) self.other_puppy; switch (i) { 1,3: "."; 2: " and they roll around on the floor."; 4: " chases after it."; 5: " with its paw."; } } switch (random(5)) { 1: " scampers after a shadow."; 2: " rolls around on the floor."; 3: " sits up and washes its tail."; 4: " scratches its head on the floor."; 5: " chases its tail."; } } ]; !Finally, we define to objects of class Puppy and give them names Puppy terrier_head "terrier head" Throne_Room with name "terrier", this_puppies_turn false, other_puppy retriever_head; Puppy retriever_head "retriever head" Throne_Room with name "retriever", this_puppies_turn true, other_puppy terrier_head; !------------------------------------------------------------------------------------------------------------------ !Class Troll is defined !------------------------------------------------------------------------------------------------------------------ Class Troll has animate ! general if it's been described this turn with parse_name [ w ok n; do { ok = 0; w = NextWord(); if (w == 'trolls') { ok = 1; n++; parser_action=##PluralFound; } if (w == 'troll' || w == ((self.&name)-->0)) { ok = 1; n++; } } until (ok == 0); return n; ], !Similar to puppy, we define two states, annoy, and eat state ANNOY_STATE, describe [ ; switch (self.state) { EAT_STATE: "^A ", (name) self, " is munching on the mushroom."; ANNOY_STATE: if (self has general) rtrue; "^A ", (name) self, " is running around the laboratory, casting spells wherever he can."; default: rtrue; } ], description [; "Quite a peculiar, warty little ogre ", (the) self, " is."; ], !Now we handle user/troll interactions !And we define how the troll switches state based on object life [; Ask,Answer,Order: print_ret (The) self, " speaks English like you speak Oompa-Loompa!"; Kiss: "You give ", (the) self, " a little kiss on its nose, and it flies to the ceiling, happily scattering magic dust."; Attack: "You would never do such a thing to such a harmless, if ugly, creature!"; Show: print_ret (The) self, " casts a spell on ", (the) noun, "."; Give,ThrowAt: if (noun ~= mushroom) { if (action == ##ThrowAt) { move noun to laboratory; print "You toss ", (the) noun, " onto the floor, but ", (the) self; } else print (The) self; " kicks ", (the) noun, " with a bored, nonsensical expression."; } print "You toss ", (the) noun, " onto the floor and ", (the) self; if (self in player) print " squirms out of your grasp and"; move noun to laboratory; move self to laboratory; print " flitters excitingly after it"; if (noun == mushroom) { give mushroom general; self.state = EAT_STATE; print ", munching on it quite cheerfully"; } "."; ], before [; Take: "He's too slippery to hold in your hand!"; ], !We give the troll a set of randomized actions based on his current state daemon [ ; give self ~general; self.this_trolls_turn = 1 - self.this_trolls_turn; if (self.this_trolls_turn == false || random(3) == 2) rtrue; new_line; print (The) self; switch (self.state) { EAT_STATE: give mushroom general; switch (random(5)) { 1: " fold over the cap and digs in."; 2: " stops eating and sits up, looking around him."; 3: " knocks the mushroom across the floor and chases after it."; 4: " stops to cast some spells."; 5: " bites the mushroom and munched happily."; } ANNOY_STATE: switch (random(5)) { 1: " scampers after his wand."; 2: " rolls around on the floor."; 3: " sits up and casts some spells."; 4: " scratches its head with his wand."; 5: " chases its wand."; } } ]; !Finally we define a object of class troll and give him a name Troll wish_nick "Wish Nick Troll" laboratory with name "wish" "nick" "wish nick", this_trolls_turn true;