!------------------------------------- ! Benjamin Gimpert ! 4/16/98 ! CS C95 Computer Game Design, Forbus ! Homework Two !------------------------------------- ! - The Island Map: ! ! Lb--GB--AR--AS----TB ! | | | ! | OM--LP--/ ! V | ! TL JE ! | ! 1--2--3----4--5 ! / | \ ! 17 | \ ! \ | \ ! 6--7 8 9-10 11-18 ! / | /| / ! / | JC | / ! / | | / ! 12-13-14 15-16 ! ! - All connections represent the typical 8 compass directions, except that ! the entrance to the Twonky Lair is "down" from the Laboratory. ! - Heading east from both the Airstrip and the Lookout Point leads to the ! Tropical Beach Path, but returning westward leads only to the Airstrip. ! - Numbers represent their respective jungle room (JungleXX). ! - Other rooms: ! ! Lb: Laboratory ! TL: Twonky Lair ! GB: Guard Base Post ! AR: Airstrip Road ! AS: Airstrip ! LP: Lookout Point ! OM: Ore Mine ! TB: Tropical Beach Path ! JE: Jungle's Edge ! JC: Jungle Clearing ! Constant DEBUG; Constant Story "Twonky Island"; Constant Headline "^CS C95 Computer Game Design^"; Release 42; Serial "980330"; Constant MAX_CARRIED = 10; ! Let player carry lots of stuff Constant SACK_OBJECT = Backpack; Include "Parser"; Include "Grammar"; Include "VerbLib"; ! Global attributes Attribute Legible; ! From designer's manual Attribute manual_concealed; ! For the medicine man's kludged hiding. [ ReadSub; <>; ]; Extend "read" first * legible -> Read; ! Global variables Constant NUM_RIDDLES 9; Array RIDDLES table "A man is sitting in a cabin looking at the sky, moving very fast. Who is he?" "Give it food and it will live, but give it water and it dies." "What goes around the world and stays in a corner?" "What gets wetter the more it dries?" "The man who invented it, doesn't want it. The man who bought it, doesn't need it. The man who needs it, doesn't know it." "Forward I am heavy, backward I am not. What am I?" "I look at you, you look at me. I raise my right, you raise your left. What am I?" "It has no top or bottom but it can hold flesh, bones and blood all at the same time. What am I?" "Light as a feather, there is nothing in it. Yet, the strongest man can't hold it for much more than a minute?"; Array RIDDLE_ANSWERS table 'pilot' 'fire' 'stamp' 'towel' 'coffin' 'ton' 'mirror' 'ring' 'breath'; Constant BAD_GUY = -1; Constant GOOD_GUY = 1; Constant NEUTRAL = 0; Global Player_Morality = NEUTRAL; Constant MAX_PLAYER_HP = 3; Global Player_HP = MAX_PLAYER_HP; Constant NUM_BLUES = 9; ! Number of blue Twonkies on the island. Constant BLUE_MOVE_SPEED = 1; ! Blues move every X turns - Lower is faster. Constant RED1_TO_PLAID = 1; Constant RED2_TO_PLAID = 2; Constant RED3_TO_PLAID = 3; Constant PLAID_TO_RED1 = 4; Constant PLAID_TO_RED2 = 5; Constant PLAID_TO_RED3 = 6; ! This array is for the medicine man native who lives in the upper trees ! of the jungle, and knows his way around *very* well. Array JUNGLE_ROOMS table Jungle_Edge Jungle1 Jungle2 Jungle3 Jungle4 Jungle5 Jungle6 Jungle7 Jungle8 Jungle9 Jungle10 Jungle11 Jungle12 Jungle13 Jungle14 Jungle15 Jungle16 Jungle17 Jungle18; ! These are monotonous, but allow for the best customizing of the paths the ! blue's take. Array PATH_RED1_TO_PLAID table Beach_Path Airstrip Airstrip_Path Base_Guard_Post Laboratory Twonky_Lair; Array DIRS_RED1_TO_PLAID table "westward" "westward" "westward" "westward" "downward" "upward"; Array PATH_RED2_TO_PLAID table Jungle_Clearing Jungle9 Jungle15 Jungle16 Jungle11 Jungle5 Jungle4 Jungle3 Jungle_Edge Lookout_Point Airstrip Airstrip_Path Base_Guard_Post Laboratory Twonky_Lair; Array DIRS_RED2_TO_PLAID table "northeastward" "southward" "eastward" "northeastward" "northwestward" "westward" "westward" "northward" "northward" "northward" "westward" "westward" "westward" "downward" "upward"; Array PATH_RED3_TO_PLAID table Mine Lookout_Point Airstrip Airstrip_Path Base_Guard_Post Laboratory Twonky_Lair; Array DIRS_RED3_TO_PLAID table "eastward" "northward" "westward" "westward" "westward" "downward" "upward"; Array PATH_PLAID_TO_RED1 table Twonky_Lair Laboratory Base_Guard_Post Airstrip_Path Airstrip Beach_Path; Array DIRS_PLAID_TO_RED1 table "upward" "eastward" "eastward" "eastward" "eastward" "westward"; Array PATH_PLAID_TO_RED2 table Twonky_Lair Laboratory Base_Guard_Post Airstrip_Path Airstrip Lookout_Point Jungle_Edge Jungle3 Jungle4 Jungle5 Jungle11 Jungle16 Jungle15 Jungle9 Jungle_Clearing; Array DIRS_PLAID_TO_RED2 table "upward" "eastward" "eastward" "eastward" "southward" "southward" "southward" "eastward" "eastward" "southeastward" "southwestward" "westward" "northward" "southwestward" "northeastward"; Array PATH_PLAID_TO_RED3 table Twonky_Lair Laboratory Base_Guard_Post Airstrip_Path Airstrip Lookout_Point Mine; Array DIRS_PLAID_TO_RED3 table "upward" "eastward" "eastward" "eastward" "southward" "westward" "eastward"; [ Print_Gibberish i tmp; ! Print out un-translated Twonkese. print "The Twonky says ~"; for (i = 0: i <= random(25) + 5: i++) { tmp = random(10); if (tmp <= 2) { tmp = 32; } else { if (tmp >= 3 && tmp <= 6) { tmp = random(26) + 64; } else { tmp = random(26) + 96; } } print (char) tmp; } print "~.^"; ]; Class Twonky has static animate neuter; Class Blue_Twonky(NUM_BLUES) with name "blue twonky" "twonky" "blue", short_name "", ! Specified dynamically upon creation. before [; Attack: if (Laser_Saw in player && Laser_Saw has general) { print "The Twonky disintegrates from the laser saw's vicious beam!^"; StopDaemon(self); remove self; Player_Morality = BAD_GUY; } else { print "The Twonky quickly scuttles away from you, dodging the attack.^"; if (random(3) == 1) { Player_Morality = BAD_GUY; } } rtrue; ], description [; print "A clumsy little blue box rolling along quietly clucking to itself. A multitude of tiny switches, knobs and antennae are spread across one side of the creature's... body?^"; switch (self.moving_to) { RED1_TO_PLAID: print (string) random( "The Twonky is carrying a small payload of beach sand.^", "The Twonky is smeared with suntan lotion.^"); RED2_TO_PLAID: print (string) random( "The Twonky is dragging a small pile of lumber.^", "The Twonky is carrying a mound of sawdust.^"); RED3_TO_PLAID: print (string) random( "A mining light is mounted on the Twonky.^", "The Twonky is carrying a small stone.^"); PLAID_TO_RED1, PLAID_TO_RED2, PLAID_TO_RED3: print "The Twonky is carrying nothing.^"; } ], moving_to, current_place 1, move_speed BLUE_MOVE_SPEED, entrance_string "A blue Twonky clutters in...^", exit_string "A blue Twonky noisily rolls ", daemon [; if (self.move_speed ~= 0) { self.move_speed--; rfalse; } self.move_speed = BLUE_MOVE_SPEED; switch (self.moving_to) { RED1_TO_PLAID: if (player in PATH_RED1_TO_PLAID-->self.current_place) { print (string) self.exit_string; print (string) DIRS_RED1_TO_PLAID-->self.current_place; print "...^"; } self.current_place++; if (self.current_place <= PATH_RED1_TO_PLAID-->0) { move self to PATH_RED1_TO_PLAID-->self.current_place; if (player in PATH_RED1_TO_PLAID-->self.current_place) { print (string) self.entrance_string; } } else { self.current_place = 1; self.moving_to = random (PLAID_TO_RED1, PLAID_TO_RED2, PLAID_TO_RED3); } RED2_TO_PLAID: if (player in PATH_RED2_TO_PLAID-->self.current_place) { print (string) self.exit_string; print (string) DIRS_RED2_TO_PLAID-->self.current_place; print "...^"; } self.current_place++; if (self.current_place <= PATH_RED2_TO_PLAID-->0) { move self to PATH_RED2_TO_PLAID-->self.current_place; if (player in PATH_RED2_TO_PLAID-->self.current_place) { print (string) self.entrance_string; } } else { self.current_place = 1; self.moving_to = random (PLAID_TO_RED1, PLAID_TO_RED2, PLAID_TO_RED3); } RED3_TO_PLAID: if (player in PATH_RED3_TO_PLAID-->self.current_place) { print (string) self.exit_string; print (string) DIRS_RED3_TO_PLAID-->self.current_place; print "...^"; } self.current_place++; if (self.current_place <= PATH_RED3_TO_PLAID-->0) { move self to PATH_RED3_TO_PLAID-->self.current_place; if (player in PATH_RED3_TO_PLAID-->self.current_place) { print (string) self.entrance_string; } } else { self.current_place = 1; self.moving_to = random (PLAID_TO_RED1, PLAID_TO_RED2, PLAID_TO_RED3); } PLAID_TO_RED1: if (player in PATH_PLAID_TO_RED1-->self.current_place) { print (string) self.exit_string; print (string) DIRS_PLAID_TO_RED1-->self.current_place; print "...^"; } self.current_place++; if (self.current_place <= PATH_PLAID_TO_RED1-->0) { move self to PATH_PLAID_TO_RED1-->self.current_place; if (player in PATH_PLAID_TO_RED1-->self.current_place) { print (string) self.entrance_string; } } else { self.current_place = 1; self.moving_to = RED1_TO_PLAID; } PLAID_TO_RED2: if (player in PATH_PLAID_TO_RED2-->self.current_place) { print (string) self.exit_string; print (string) DIRS_PLAID_TO_RED2-->self.current_place; print "...^"; } self.current_place++; if (self.current_place <= PATH_PLAID_TO_RED2-->0) { move self to PATH_PLAID_TO_RED2-->self.current_place; if (player in PATH_PLAID_TO_RED2-->self.current_place) { print (string) self.entrance_string; } } else { self.current_place = 1; self.moving_to = RED2_TO_PLAID; } PLAID_TO_RED3: if (player in PATH_PLAID_TO_RED3-->self.current_place) { print (string) self.exit_string; print (string) DIRS_PLAID_TO_RED3-->self.current_place; print "...^"; } self.current_place++; if (self.current_place <= PATH_PLAID_TO_RED3-->0) { move self to PATH_PLAID_TO_RED3-->self.current_place; if (player in PATH_PLAID_TO_RED3-->self.current_place) { print (string) self.entrance_string; } } else { self.current_place = 1; self.moving_to = RED3_TO_PLAID; } } rfalse; ], life [; Give: if (noun ofclass Sea_Shell && noun in player) { if (Babel_Fish in player && Babel_Fish has worn) { print "The Twonky says ~Why thank you sir! My kin back on Xarlap will love a souveneir from such a primitive planet! Good day, and I hope to see you again!~.^"; remove noun; switch (Player_Morality) { NEUTRAL: Player_Morality = GOOD_GUY; BAD_GUY: if (random(3) == 1) { Player_Morality = NEUTRAL; } } } else { print "Perhaps the blue Twonky is interested, but you can't seem to understand its stream of squaks and beeps.^"; } rtrue; } else { rfalse; } Answer, Ask, Tell: if (Babel_Fish in player && Babel_Fish has worn) { print "The Twonky says "; switch(Player_Morality) { BAD_GUY: print (string) random ( "~Oh no! Please don't kill me, please?!~^", "~RUN AWAY!!!~^", "~Can't we all just get along?~^", "~No wonder your planet is doomed...!~^", "~Can't you see this is the violence inherent in the system?~^"); GOOD_GUY, NEUTRAL: print (string) random ( "~Hello kind Earthling! Please step step aside...~^", "~Such a lovely day, isn't it?~^", "~ Hi! ...~^",); } rtrue; } else { Print_Gibberish(); rtrue; } ], explosion [; print "You hear a blue Twonky explode... Chalk one up for the good guys!"; StopDaemon(self); remove self; Player_Morality = BAD_GUY; ], class Twonky; Class Red_Twonky with before [; Attack: if (Laser_Saw in player && Laser_Saw has general) { print "The red Twonky screams for a few moments from the laser saw's onslaught, then suddenly explodes in a spray of shrapnel!^"; if (random(4) == 1) { print "A piece of the Twonky's mecha-pancreas cuts into you!^"; Player_HP--; if (Player_HP == 0) { deadflag = 1; print "Arrggh! The cut is just too deep...^"; } } remove self; Player_Morality = BAD_GUY; } else { print "The red Twonky dodges easily, beeping angrily.^"; if (random(2) == 1) { Player_Morality = BAD_GUY; } } rtrue; ], description [; print "A monstrosity of bad 1950's science fiction - This critter resembles a bright red vacuum tube radio with four small appendages, which you can only assume are arms and legs. Surprisingly, the arms and legs are quite agile and the creature bares an alien kind of grace.^"; if (self.stun_time > 0) { print "This red Twonky seems dazed and confused at the moment.^"; } ], stun_time, each_turn [; if (player in parent(self) && Player_Morality == BAD_GUY && self.stun_time == 0 && random(2) == 1) { ! Un-stunned red is in the same room as the bad player, and notices her. print "* The red Twonky fires its PBB (pulse boolean beam) at you! *^"; Player_HP--; if (Player_HP == 0) { deadflag = 1; print "You disappear in a puff of logic!^"; } } if (self.stun_time > 0) { self.stun_time--; } ], explosion [; self.stun_time = 5; Player_Morality = BAD_GUY; ], class Twonky; ! By default all of the places in this game are going to have ! light. Simplest way to do this is by subclassing object Class ExplosiveContainer with explosion [ x; objectloop (x in self && x provides explosion) { x.explosion(); } remove self; ] has container; Class Room with explosion [ x; objectloop (x in self && x provides explosion) { x.explosion(); } ], has light supporter enterable; Class Jungle_Room with name "jungle", description "Amongst the dense undergrowth and humid air, your senses are very dull. The jungle seems alive with its own intentions.^", before [; Sleep: print "You lay down for a quick snooze in the middle of a jungle, and wake up several minutes later missing several crucial appendages.^ ^You are eaten by a Grue."; deadflag = 1; rtrue; ], cant_go [; print (string) random ( "The undergrowth is just too thick to push through in that direction^", "You step in that direction, but a vicious-looking snake slithers across your feet. Rethinking your navigation may be a good idea.^", "A fallen hollow tree blocks your way.^"); ], class Room; ! Default disconnected location for objects to be revealed later. Room Limbo; ! Around the Airstrip is a control shack and three paths ! North of the airstrip is ocean, it would be nice to say ! something clever to the player who tried to go North from ! the airstrip... Room Airstrip "Airstrip" with name "airstrip" "runway", description "A small runway that runs east-west, in good repair. An occasional cockatoo flies overhead, shrieking loudly. The windsock rustles slowly in a gentle breeze.^ To the west is a one-lane paved road, to the east is a footpath. A Quonset hut lies to the south-east, and a path going up a steep hill lies to the south.^", w_to Airstrip_Path, e_to Beach_Path, se_to Control_Shack, s_to Lookout_Point, cant_go "The rocks are too steep to climb.^"; Room Control_Shack "Control Shack" with name "control shack" "shack" "tower", description "A Quonset hut that was used as a control tower for planes landing on the island. It has been shredded, as if by a giant can-opener. All electronics equipment appears to have been removed, but a steel case is mounted on the far wall.^ The airstrip lies to the northwest.^", nw_to airstrip, cant_go "Cutting through the walls of the hut in that direction would take considerably more effort than you can give at the moment.^"; Object -> Steel_Case "steel case" with name "steel case" "case", with_key Steel_Case_Key, has lockable locked openable static, class ExplosiveContainer; Object -> -> Fire_Axe "fire axe" with name "fire axe" "axe" "fire ax" "ax", description "A fireman's axe, normally used in disaster situations to clear away obstacles.^", before [; Swing: if (Red2 in location) { print "You swing the axe at a nearby tree, and the red Twonky watches you very carefully. Perhaps the creature would like to see the axe?^"; give Red2 general; rtrue; } else { rfalse; } ]; Object -> -> Shotgun "shotgun" with name "shotgun" "gun", description "An unloaded double-barrel shotgun, with ~Imp Killa'~ engraved on its side.^"; Object -> -> Survival_Kit "survival kit" with name "survival" "kit", description "A small leather satchel containing items necessary for survival in the wilderness.^" has openable, class ExplosiveContainer; Object -> -> -> "pack of rations" with name "pack of rations" "pack" "rations", description "Dehydrated moloko and spam. Yum!!!^" has edible; Object -> -> -> Mirror "mirror" with name "mirror", description "A small but sturdy hand mirror.^"; Object -> -> -> "broken compass" ! A decidedly un-useful compass - A red herring, as such. with name "broken compass" "compass", description [; print "A cracked military compass, reading ", random(359) + 1, " degrees.^"; ]; Object -> -> -> Chewing_Gum "piece of chewing gum" with name "piece of chewing gum" "piece of gum" "gum", description "A stick of military issue Blackjack (TM) chewing gum.^", has edible; Room Beach_Path "Tropical Beach Path" with name "path" "beach path" "tropical beach path", description "A huge tropical beach stretches out to the edge of view. Warm white sand and countless pieces of driftwood lay basking in the sun, with the endless of the ocean beyond. For whatever reason, no sea shells are in sight. As if they have all been blown away by the tropical winds.^ The airstrip lies to the west.^", before [; Sleep: if (Player_Morality == BAD_GUY && ~~ (Red1 in self)) { print "You lay down for a quick nap in the sun, and feel very reguvinated upon waking.^"; if (Player_HP < MAX_PLAYER_HP) { if (Headphones in player && Headphones has worn) { Player_HP = MAX_PLAYER_HP; } else { Player_HP++; } } } else { print "You don't have time for that now!^"; } rtrue; Swim: print "Wading a few steps into the ocean helps you remember just what season it is further from the equator - Brrr!^"; rtrue; ], w_to Airstrip, cant_go "More boring beach-front scenery stretches in that direction.^"; Red_Twonky -> Red1 "red Twonky #101" with name "red twonky #101" "red twonky" "red" "#101" "101" "twonky", description [; self.Red_Twonky::description(); "This Twonky seems to be enjoying the climate entirely too much, and is laying on its side sunbathing!^"; ], life [; Answer, Ask, Tell: if (Babel_Fish in player && Babel_Fish has worn) { print "The Twonky says "; switch(Player_Morality) { BAD_GUY: print (string) random( "~No one can escape Twonky Empire! Now run along petty human, I'm very busy.~^", "~Begone flesheater!!!~^", "~If there's one thing I can't stand, it's evolved mammals!~^"); GOOD_GUY, NEUTRAL: print (string) random( "~Ahh, the fishing's good here isn't it? Care to go for a swim, or cast a line?~", "~Such a beautiful planet... I'd hate to see it go anywhere.~", "~Hand me that Coppertone (TM) will you?~"); print " The red goes on to babble further incoherencies...^"; } rtrue; } else { Print_Gibberish(); if (Fishing_Pole has concealed && Player_Morality ~= BAD_GUY) { print " Then the red seems to gesture lazily towards a fishing pole laying nearby, half buried in the sand.^"; give Fishing_Pole ~concealed; } rtrue; } ]; Object -> Fishing_Pole "fishing pole" with name "fishing pole" "pole", description "A typical Earthling fishing pole, with a very ~foreign~ fly attached to the line. The fly is a bit of organic-looking circuitry, glowing with a faint blue pulse. You may want to take a moment to fish, by ~swing~ing this pole.^", before [; Swing: if (location ~= Beach_Path) { rfalse; } print "You throw back the line and cast it gently. However, some bizarre hidden component in the pole send the fly soaring several miles out to sea! Reeling in the line takes several minutes (hours?), "; if (random(3) == 1 && Babel_Fish in Limbo) { print "and dangling from the end is a very tiny fish. You take the fish.^"; move Babel_Fish to player; } else { print "and unfortunately it is empty. Try casting the line again perhaps?^"; } rtrue; ], has concealed; Object Babel_Fish "babel fish" Limbo with name "babel fish" "babel" "fish" "translator", description "A tiny orange fish with a glowing dorsal fin. Some uncanny voice in the back of your mind urges you to put this fish in your ear by ~wear~ing it.^", before [; Wear: print "The babel fish squirms into your ear, and yer hearin' sudenlee beecumz zo mutch cleerur...^"; give self worn; rtrue; ], has clothing; Room Lookout_Point "Lookout Point" with name "lookout point" "lookout" "point", initial "Climbing the deceptively large hill takes quite a bit of effort, but you manage.^", description "The crest of this small hill gives you a decent view of the entire island. Various pieces of very broken equipment lie scattared about, probably the remains of the island's command dish.^ To the north you see the airstrip, its control shack and access road. To your east is the scenic beach, to the west is an entrance to a mine, and to the south is a dense jungle.^", n_to Airstrip, w_to Mine, e_to Beach_Path, s_to Jungle_Edge, cant_go "The hill is too steep to descend in that direction.^"; Room Mine "Ore Mine" with name "ore mine" "mine" "shaft", description "On one edge of the hill is a small dark hole, just a few feet high, leading downwards. Judging by the many small pieces of Twonky equipment and piles of rock strewn about, this is apparently the entrance to a makeshift mine.^ The lookout point is atop the hill to the east.^", e_to Lookout_Point, d_to [; print "The mine shaft is too small to enter.^"; rtrue; ], cant_go "The hill is too steep to climb in that direction.^"; Red_Twonky -> Red3 "red Twonky #103" with name "red twonky #103" "red twonky" "red" "#103" "103" "twonky", description [; self.Red_Twonky::description(); "This Twonky is pacing about the entrance to the mine, belching out short commands into the shaft.^"; ], before [; Push: print "You shove the red Twonky with all your might, and after a quick struggle the huge radio goes tumbling into the mine. Seconds later, it lands with a loud crash and various pieces of the Twonky come flying out of the mine shaft ala' shrapnel.^"; Player_Morality = BAD_GUY; remove self; move Transponder to Mine; rtrue; ], life [; Show, Give: if (noun == Blue_Twonky_Parts && Blue_Twonky_Parts in player && Transponder in Limbo && Babel_Fish in player && Babel_Fish has worn) { print "The Twonky replies "; print "~It is a sad day when one of our valuable workers is dissassembled on a mission. Perhaps someone may still find this blue's transponder of use...~^ You take the transponder.^"; move Transponder to player; rtrue; } else { rfalse; } Ask: switch (second) { 'laboratory', 'lab', 'leader', 'transponder', 'keycard', 'key card', 'key', 'card', 'door', 'trapdoor', 'lock', 'unlock': if (Babel_Fish in player && Babel_Fish has worn) { print "The Twonky replies "; print "~I'm not certain of your intent, but perhaps you may find something interesting amongst the rubble.~^"; give Mine_Rubble ~concealed; rtrue; } default: <>; } Answer, Tell: if (Babel_Fish in player && Babel_Fish has worn) { print "The Twonky says "; switch(Player_Morality) { BAD_GUY: print (string) random( "~Do you wish to face the rath of MC Tonedef from below the depths of your petty laboratoy?~", "~Learn well the art of doom, flesheater.~", "~Bugger off!~"); GOOD_GUY, NEUTRAL: print "~Greetings noble human! Please watch your step around the mine. Have you spoken with our great leader beneath your laboratory?~^"; } rtrue; } else { Print_Gibberish(); rtrue; } ]; Object -> Mine_Rubble "pile of mine rubble" with name "pile of mine rubble" "pile" "mine rubble" "rubble", description "A pile of stones, dirt and dust that has been set aside from the mine.^", before [; Search: if (Blue_Twonky_Parts in Limbo) { print "Buried deep in the rubble, you what once a blue Twonky. The mechanical creature was apparently caught beneath a minor disaster within the mine.^ You take blue Twonky parts.^"; move Blue_Twonky_Parts to player; rtrue; } else { rfalse; } ], has static concealed; Object Blue_Twonky_Parts "blue Twonky parts" Limbo with name "blue Twonky parts" "Twonky parts" "parts" "equipment", description "Just slightly more than a handful of various unknown Twonky parts.^"; Object Transponder "transponder" Limbo ! Having general means the keycard is stuck together by chewing gum. with name "transponder" "key card" "keycard" "card", description [; print "A slim key card, with a row of coded blinkenlights.^"; if (self hasnt general) { print "The card has a large crack running its length. To use the card will require fixing this - Maybe by ~squeeze~ing it together.^"; } else { print "The card has a large crack being held together by chewing gum.^"; } rtrue; ], before [; Squeeze: if (Chewing_Gum in player) { print "After popping the chewing in your mouth for a few seconds, you squeeze to card together and ~clamp~ it closed. This just *might* work!^"; ; print "^"; give self general; } else { print "Squeezing the card together works momentarily, but obviously it just breaks apart again after releasing your grip.^"; } rtrue; ]; Object Medicine_Man "medicine man" ! Having general means the medicine man is wearing his headphones. with name "medicine man" "man" "witch" "witchdoctor" "doctor" "native" "trees" "tree" "above" "canopy", ! Big time kludge happenin' here! short_name [; ! The medicine man only appears as a rustle amongst the trees until ! the player actually looks carefully in his direction. if (self has manual_concealed) { print "rustle of movement high in the tree canopy"; rtrue; } else { rfalse; } ], description [; print "A thin, war painted, half-clothed native wearing a few strategically placed animal pelts. He appears surprisingly inquisitive, and judging by his various bizarre adornments, the native could only be a medicine man.^"; if (self has general) { print "The medicine man is bopping to the tune emanating from his set of headphones.^"; } ], daemon [; if (random(10) == 1 && self.which_riddle == 0) { move self to JUNGLE_ROOMS-->random(JUNGLE_ROOMS-->0); give self manual_concealed; } ], which_riddle 0, life [; Ask: switch (second) { 'headphones', 'phones', 'walkman', 'music', 'humming': print "The witch doctor calls down to you: ~Like my special medicine, perhaps the outsider would? Yes? For such, a riddle must you answer... "; self.which_riddle = random(NUM_RIDDLES); print (string) RIDDLES-->(self.which_riddle); print "~^"; rtrue; } Answer: if (self.which_riddle ~= 0) { if (noun == RIDDLE_ANSWERS-->(self.which_riddle)) { print "The medicine man smiles helpfully, slips the blaring headphones away from his head, and drops them onto a pile of soft grass on the ground near you.^"; give Medicine_Man ~general; move Headphones to location; rtrue; } else { print "The native laughs blatantly. ~Hahaha! WRONG!~^"; self.which_riddle = 0; rtrue; } } else { print "The medicine man just stares at you inquisitively.^"; rfalse; } ], before [; Examine: if (self has manual_concealed) { print "Dizzyingly high in the trees is the shape of a painted island native, humming quietly and watching you..."; give Medicine_Man ~manual_concealed; rtrue; } else { rfalse; } ], has static animate male manual_concealed general; Object Headphones "set of headphones" Limbo with name "headphones" "phones" "walkman", description "A very worn set of headphones connected via cable to a slick black cube of plastic and metal. Printed on a weathered sticker is the name brand, ~Sandbenders~.^", each_turn [; if (self has worn && random(3) == 1) { print "Your headphones crank out some phat tribal beats.^"; rtrue; } else { rfalse; } ], has clothing; Jungle_Room Jungle_Edge "Jungle's Edge" with name "jungle~s edge" "edge" "jungle", initial "Stumbling down the hill into the jungle may not be the wisest idea, but exploring the entire island is your duty.^", description [; self.Jungle_Room::description(); "The jungle grows even thicker to the south. The lookout point is to the north.^"; ], n_to Lookout_Point, s_to Jungle3; Jungle_Room Jungle1 "Jungle" with sw_to Jungle17, e_to Jungle2; Jungle_Room Jungle2 "Jungle" with w_to Jungle1, e_to Jungle3; Jungle_Room Jungle3 "Jungle" with n_to Jungle_Edge, s_to Jungle8, w_to Jungle2, e_to Jungle4; Jungle_Room Jungle4 "Jungle" with w_to Jungle3, e_to Jungle5; Jungle_Room Jungle5 "Jungle" with w_to Jungle4, se_to Jungle11; Jungle_Room Jungle6 "Jungle" with nw_to Jungle17, e_to Jungle7; Jungle_Room Jungle7 "Jungle" with w_to Jungle6, sw_to Jungle12, e_to Jungle8; Jungle_Room Jungle8 "Jungle" with n_to Jungle3, w_to Jungle7, s_to Jungle14; Jungle_Room Jungle9 "Jungle" with sw_to Jungle_Clearing, s_to Jungle15, e_to Jungle10; Jungle_Room Jungle10 "Jungle" with w_to Jungle9; Jungle_Room Jungle11 "Jungle" with nw_to Jungle5, e_to Jungle18, sw_to Jungle16; Jungle_Room Jungle12 "Jungle" with ne_to Jungle7, e_to Jungle13; Jungle_Room Jungle13 "Jungle" with w_to Jungle12, e_to Jungle14; Jungle_Room Jungle14 "Jungle" with w_to Jungle13, n_to Jungle8; Jungle_Room Jungle15 "Jungle" with n_to Jungle9, e_to Jungle16; Jungle_Room Jungle16 "Jungle" with w_to Jungle15, ne_to Jungle11; Jungle_Room Jungle17 "Jungle" with se_to Jungle6, ne_to Jungle1; Jungle_Room Jungle18 "Jungle" with w_to Jungle11; Jungle_Room Jungle_Clearing "Jungle Clearing" with description "A discrete clearing within the jungle, where the noises of the wildlife die down and the undergrowth lessens.^", ne_to Jungle9; Red_Twonky -> Red2 "red Twonky #102" ! Having general means this Twonky has been shown how to swing an axe. with name "red twonky #102" "red twonky" "red" "#102" "102" "twonky", description [; self.Red_Twonky::description(); if (Fire_Axe in Limbo) { print "This Twonky is happily cutting down trees with a primitive-looking axe.^"; } else { print "This Twonky is noisily cutting apart trees in a somewhat-feeble attempt at producing lumber. It is using a bright green beam of light, a laser saw, to slice through the trunks. But, the beam is too destructive to be efficient.^"; } rtrue; ], life [; Ask: if (Player_Morality ~= BAD_GUY) { switch (second) { 'axe', 'ax', 'fire axe', 'fire ax', 'laser saw', 'laser', 'saw', 'trees', 'lumber', 'wood': if (Babel_Fish in player && Babel_Fish has worn) { print "The Twonky replies "; print "~Curse this Earthling plantlife! I require a better means of acquiring this 'wood' substance. Perhaps you can show me a better tool?~^"; rtrue; } default: rfalse; } } else { rfalse; } Give: <>; Show: if (noun == Mirror && Mirror in player && ~~ (Fire_Axe in Limbo)) { print "Good idea, rambo! After a moment of careful mental calculation, you aim your mirror in the direction of the red Twonky's laser saw blasts... "; if (random(2) == 1) { print "The beam reflects perfectly off of your mirror, and with a satisfying ~KERZAP~, the red Twonky disintegrates! Interestingly, the Twonky's laser saw falls to ground where the creature was just standing.^"; remove self; Player_Morality = BAD_GUY; move Laser_Saw to Jungle_Clearing; } else { print "And the beam reflects off of your mirror into a nearby tree. Uh oh, now he's pissed! Maybe if you try again for a little better aim...^"; Player_Morality = BAD_GUY; } rtrue; } else { if (noun == Fire_Axe && Fire_Axe in player && self has general) { print "With what seems like a few chirps of recognition, the red Twonky realizes that the axe would be a much better tool for its task. The Twonky walks across the clearing to face you, and silently pulls the fire axe from your grip! At the same time, the Twonky drops the laser saw.^"; if (Babel_Fish in player && Babel_Fish has worn) { print "The Twonky says ~Thank you human! Perhaps your race is more evolved than we had first imagined.~^"; } move Fire_Axe to Limbo; move Laser_Saw to Jungle_Clearing; rtrue; } else { rfalse; } } ]; Object Laser_Saw "laser saw" Limbo ! Having general means the laser saw is switched on. with name "laser saw" "laser" "saw" "beam", description [; print "This vile weapon is nearly beyond description - A smooth cylinder of almost weightless polished grey metal, with a small panel of alien circuitry mounted on one end. You feel fairly confident that this device could easily bore through most materials, just don't expect any kind of accuracy...^"; if (self hasnt general) { print "The laser saw is currently switched off.^"; } else { print "The laser saw is spitting a vicious-looking green beam of light directly away from you.^"; } ], before [; SwitchOn: if (self hasnt general) { if (self in player) { print "*click* ~Ho ho ho, now I have a machine gun too!~^"; give self general; } else { print "You need to pick up the laser saw first.,,^"; } } else { print "The laser saw is already activated!^"; } rtrue; SwitchOff: if (self has general) { if (self in player) { print "*click* You fire down the laser saw.^"; give self ~general; } else { print "You need to pick up the laser saw first.,,^"; } } else { print "The laser saw is already de-activated!^"; } rtrue; ]; Room Airstrip_Path "Airstrip Road" with name "airstrip road" "lab road" "road", description "This is a one-lane gravel road, running east/west. Every few steps a small sea shell or two catches your eye amidst the gravel.^ The base lies to the west, and the airstrip is to the east.^", e_to airstrip, w_to Base_Guard_Post, cant_go "The dense foliage looks very uninviting."; Class Sea_Shell; Sea_Shell -> Shell1 "conch shell" with name "sea shell" "conch shell" "conch" "shell", description "A tiny, slightly-tattered conch shell.^"; Sea_Shell -> Shell2 "snail shell" with name "sea shell" "snail shell" "snail" "shell", description "A tiny, slightly-tattered snail shell.^"; Sea_Shell -> Shell3 "sea shell shard" with name "sea shell" "sea shell shard" "shard" "shell", description "A shard of some sea shell.^"; Sea_Shell -> Shell4 "crab shell" with name "sea shell" "crab shell" "crab" "shell", description "A tiny, slightly-tattered crab shell.^"; Sea_Shell -> Shell5 "sea Shell (TM)" with name "sea shell" "shell", description "A tiny, slightly-tattered Shell (TM).^"; Room Base_Guard_Post "Base Guard Post" with name "guard post" "post", initial "It's clear that a struggle occurred, with weapons of unknown origin.^", description "A small shanty serving as the guard post has been charred and blasted.^ The laboratory lies to the west, and the road to the airstrip runs off to the east.^", w_to Laboratory, e_to Airstrip_Path; Object -> "body of a guard" with name "body" "body of a guard" "guard", description "Although there isn't much left, from the remains it is clear that this was once a sentry.^", before [; Search: if (Steel_Case_Key in Limbo) { move Steel_Case_Key to player; "You find a small key in the tattered flap of the guard's pocket.^"; } else { rfalse; } ], has static; Object Steel_Case_Key "aluminum key" Limbo with name "aluminum key" "key", description "A simple aluminum key, such as what might be used to open a piece of luggage or a safety deposit box.^"; Room Laboratory "Laboratory" with name "Lab" "Laboratory", initial "The door to the laboratory is shredded, and the whole building has a burnt-out look to it. From the layout of the area, it seems clear that supporting this laboratory is the whole purpose of the base.^", description "The interior of the laboratory is one large room, containing various benches with equipment and a bookshelf lining one wall.^ The entryway to the guard post is eastward.^", each_turn [; if (random(3) == 1) { print "You hear hear faint music emanating from below.^"; rtrue; } else { rfalse; } ], e_to Base_Guard_Post, d_to Trapdoor, cant_go "While the walls have had heavy damage, they do not yield when you push against them.^"; Object -> Trapdoor "trapdoor" with name "trapdoor" "door", description "A thick steel trapdoor set into into the sturdy floor of the laboratory. Along its side is a thin black slot.^", when_closed "Your downward descent is blocked by a thick steel trapdoor.^", when_open "The thick steel trapdoor is open, leading downward. Strangely, you hear music coming from below.^", door_to Twonky_Lair, door_dir d_to, with_key Transponder, before [; Unlock: if (second == Transponder && Transponder in Player && Transponder has general) { rfalse; ! Because we want the usual door routines to take over. } else { print "The trapdoor can't be unlocked with that.^"; rtrue; } ], has static door openable lockable locked; Object -> Scientist_Body "scientist's body" with name "body" "scientist's body", description "This corpse was probably a scientist working in the lab. Like the sentry, the body is burned beyond identification.^", has static; Object -> Lab_Bench1 "long laboratory bench" with name "long bench" "bench", description "A long laboratory bench, with various pieces of apparatus on it. Each piece of apparatus has at least one component missing from it.^", has static; Object -> Lab_Bench2 "cluttered laboratory bench" with name "cluttered bench" "bench", description "This lab bench is festooned with small mechanical and electronic parts. It is as if someone spread things out apparatus on it. Each piece of apparatus has at least one component missing from it.^", has supporter static; Object -> -> Scientist_Note "note" with name "note" "message", initial "It looks as if a message was hurridly scrawled on a page torn from a lab notebook.^", description "The page is charred, but the note is still readable.^", before [; Read: "When we saw them at the airstrip, they looked like animated 1950's radios, so we called them ~Twonkies~. They took apart the control hut, as if they were looking for something. The officer of the day fired on them, and they shot him with a red beam. They swarmed up the road. It would have been funny, that combination of square boxy bodies and obscenely lithe limbs, if it hadn't been for the devastation and the horrible, horrible music!!! Fred tried radioing for help, but they already got the airstrip antenna and we seem cut off from the Command Dish. George broke out the guns, and maybe we can a few of these bastards with us. There's nothing like the smell of napalm in the morning...^"; ], has legible; Room Twonky_Lair "Twonky Lair" with name "twonky lair" "lair", description "An underground cavern that strangely resembles are cross between a 1950's nightclub and a production laboratory. Huge mounds of unknown equipment are piled up everywhere, while in the center of the room rests an empty wooden dance floor. Complementing the dance floor is a black grand piano and a strange looking microphone. A multitude of Twonkies scurry about, performing various construction tasks on the equipment while belting out a steady stream of attrocious R&B music.^", u_to Laboratory, cant_go "Slamming head-first into a wall of rock in that direction leaves you with much less opportunity for moment.^"; Object -> Plaid_Twonky "plaid Twonky" ! Having general means the plaid Twonky has been harmlessly blasted with ! a grenade. with name "plaid twonky" "plaid" "twonky" "mc tonedef" "tonedef" "mc", each_turn [; ! Don't check for the Babel Fish, because MC Tonedef sings in English. :) print "The plaid Twonky sings, ~"; print (string) random( "Doo bee doo be do...~^", "See you at the crossroads...~^", "Walkin' along, mindin' my busines...~^", "Fah la la do bee...~^", "Oh oh oh... Do I ever cross yer mind?~^", "Tainted love, ohhh, tainted love...~^" ); rfalse; ], before [; Attack: if (Laser_Saw in player && Laser_Saw has general) { print "You train the laser saw's beam onto the alien. MC Tonedef, the great Twonky leader, sends its attanae flailing madly as the laser saw's beam heats the microphone head to a glowing red. Eventually, all movement ceases and MC Tonedef passes on to whatever domain lies beyond...^"; Player_Morality = BAD_GUY; Bad_Guy_Win(); } else { print "The plaid Twonky suddenly vanishes, only to reappear several feet away. Obviously, your attack has no affect, other then angering even further the entire Twonky population of this island.^"; Player_Morality = BAD_GUY; } rtrue; ], description [; print "An ancient-looking radio show ball microphone glowing in bright ambergreen plaid glory. The creature is held afloat in midair by some advanced technology, while its hundreds of tiny antennae sample the air of its near environment.^"; if (self has general) { print "The microphone is a little blasted from a grenade, but doesn't appear to be hurt to all.^"; } rtrue; ], explosion [; give self general; ], life [; Give: if (Babel_Fish in player && Babel_Fish has worn) { if (noun == Headphones) { print "MC Tonedef replies "; print "~Yeah baby, YEAH! This walkman is just what I'll need to keep the groove happenin'. Just a few quick modifications and I'll have this little gadget transmitting to my all my brothers and sisters. You humans are so money, and you don't even know it! Of course, you needed our help to stop that huge asteroid from smackin' straight down into New Orleans proper, but that funky space boulder won't be a problem anymore with your help. Shaft!~^"; Good_Guy_Win(); } } else { rfalse; } Ask: if (Babel_Fish in player && Babel_Fish has worn) { switch (second) { 'song', 'sing', 'singing', 'voice', 'music', 'band', 'rythym', 'blues', 'R&B', 'r&b': print "The Twonky replies "; print "~My smashing vocals keep the blue Twonkies' away from your planet's groovin' but ever-so-distracting native radio music. But dig this hipcat: I'm losing my voice. In order to finish our work here, the R&B must continue to groove, baby. So bring me somethin' to get jiggy wit', k?~^"; rtrue; default: rfalse; } } else { Print_Gibberish(); rtrue; } ], class Twonky; ! ============================= ! Props used in the story ! ============================= Class Grenade ! Having general means a grenade is set to explode in 5 turns. ! A grenade explodes after five turns have passed. ! It kills the player if they are silly enough to be in the same location, ! and also sets off any other grenades in the same location. with name "grenade", plural "grenades", short_name "grenade", description "Regulation-issue concussion grenade.^", before [; Set: if (self has general) { "Already activated... *gulp*^"; } else { StartTimer(self, 5); give self general; "You set the grenade's timer to explode in five moves.^"; } ], time_left 0, time_out [ tmp; print "KABOOM! The grenade explodes!^"; tmp = self; while (~~ (tmp ofclass Room)) { tmp = parent(tmp); } remove self; tmp.explosion(); if (player in tmp) { deadflag = 1; "The explosion tears you apart! You should have moved further away.^"; }; ], explosion [; remove self; "The explosion sets off another grenade.^"; ]; Object Backpack "backpack" ! The player's backpack contains useful stuff with name "backpack" "pack" "satchel" "knapsack", description "A strong canvas backpack, suitable for carrying lots of equipment.^", article "your", when_closed "Your pack lies on the floor.^", when_open "Your pack lies open on the floor.^", has open openable, class ExplosiveContainer; ! Start player off with six grenades Grenade ->; Grenade ->; Grenade ->; Grenade ->; Grenade ->; Grenade ->; [ Good_Guy_Win; print "^You return to the airstrip to be picked up by your military air transport several hours later. Wondering the entire trip home, you are not quite sure whether it was all a dream. But by the next Tuesday your suspicions are vanquished: A asteroid roughly a quarter the size of Earth's moon smashes into a Virtucon (TM) satelite, on a collision course with the surface of somewhere on the North American shoreline. While millions scream of Armageddeon, you relax in the knowledge of your race's alien allies. Just minutes before impact, an incredible beam of light erupts from Twonky island, ripping into the core of the asteroid. Suddenly the great rock behemoth disintegrates into an immense puff of logic, never before to plague your planet's well being.^"; if (Player_Morality == GOOD_GUY) { print "^Several weeks later, a small package wrapped in light blue wrapping paper arrives on your doorstep. Tearing open the package, you find an undeniably familiar small blue box with a 'multitude of tiny switches, knobs and antennae spread across one side.' Smiling, you set the blue Twonky down on the floor of your apartment, and it rolls away cheerfully. Never again need concern yourself with housework, chess parters, yardwork, radio interference, income tax returns, annoying neighborhood poodles...^"; } print "^Congatulations! With cooperation and understanding, you have saved planet Earth from a horrible demise.^"; deadflag = 2; rtrue; ]; [ Bad_Guy_Win; print "^You return to the open air, exhausted but elated at vanquishing the Twonkies. Activating the homing beacon, you wait for the task force to pick you up.^ ^Several months later, an asteroid impact levels the Midwestern United States. The dust cloud has wiped out plants on a planetary scale, and the survival of mammalian life, including humans, is now in doubt. It seems you did not act quickly enough to foil the Twonkies nefarious scheme...or were they only trying to help?^"; deadflag = 2; rtrue; ]; [ Initialise i j tmp x; for (i = 1: i <= NUM_BLUES: i++) { tmp = Blue_Twonky.create(); j = random(RED1_TO_PLAID, RED2_TO_PLAID, RED3_TO_PLAID, PLAID_TO_RED1, PLAID_TO_RED2, PLAID_TO_RED3); tmp.moving_to = j; tmp.short_name = "blue twonky"; switch (j) { RED1_TO_PLAID, PLAID_TO_RED1: x = random(PATH_RED1_TO_PLAID-->0); move tmp to PATH_RED1_TO_PLAID-->x; RED2_TO_PLAID, PLAID_TO_RED2: x = random(PATH_RED2_TO_PLAID-->0); move tmp to PATH_RED2_TO_PLAID-->x; RED3_TO_PLAID, PLAID_TO_RED3: x = random(PATH_RED3_TO_PLAID-->0); move tmp to PATH_RED3_TO_PLAID-->x; } StartDaemon(tmp); } move Medicine_Man to JUNGLE_ROOMS-->random(JUNGLE_ROOMS-->0); StartDaemon(Medicine_Man); location = Airstrip; move Backpack to player; #Ifdef DEBUG; move Babel_Fish to player; give Babel_Fish worn; move Mirror to player; move Fire_Axe to player; move Transponder to player; give Transponder general; move Headphones to player; move player to Twonky_Lair; #Endif; ! And start the action rolling... print "^^^You barely have time to appreciate the sunrise on the lush tropical island below as the ground rushes up at you. Your knees buckle as you land, and you quickly roll up your parachute to minimize the chance of discovery. Fortunately, the airstrip is deserted. Aside from the occasional bird call and a gentle breeze, you hear nothing.^^^"; ];