! "The Underoos That Ate New York!" ! Copyright (c) 1994 ! By Gerry Kevin Wilson ! This is a translation of my TADS game to Inform, so that I can learn the ! Inform programming language. I had to change one or two things because ! of the way the Inform parser works, but it is largely identical to the ! TADS version. It's probably buggier than the TADS version, thanks to my ! inexperience with Inform, but what the hey. Enjoy, and I hope this source ! code helps somebody else learn Inform (or compare it to the TADS source ! and learn TADS if you already know Inform.) Switches v5; Constant Story "The Underoos That Ate New York!"; Constant Headline "^An Interactive Quickie by G. Kevin Wilson^ (c) 1994. All Rights Reserved.^Email: gkw@@64pobox.com^ Type 'xyzzy' for help and information.^"; Constant max_score 5; Constant max_carried 18; Constant TASKS_PROVIDED; Constant NUMBER_TASKS 6; Array task_scores -> 1 1 1 1 1 1; Global monster; Global silence; Global secret; Include "Parser"; Attribute clatters; Object LibraryMessages with before [; Miscellany: if (lm_n==10 && silence) { print "Thank you. "; silence = false; Achieved(5); rtrue; } ], ; Include "Verblib"; Object bedroom "Your Bedroom" with description "Home sweet home for a '60s throwback bachelor like yourself. Assorted, but unimportant decorations litter the walls and ceiling. To the west is a door that, as you fuzzily recall, leads into your walk-in closet. To the east is a hallway, that, as you even more fuzzily recall, leads to the kitchen. ", e_to [; if (underoos has concealed) { "You don't like the chill wind blowing in off the kitchen tiles. Maybe you could at least have a look round for your underoos first?"; } else { return kitchen; } ], w_to closetdoor, has light ; Object -> shazam "bed" with name "your" "bed" "my", description "This is your bed.", article "your", before [; LookUnder: if (parent(player)==self) { "You lean over the edge and try to peer under the bed, but the blood rushes to your head and your eyes refuse to focus."; } else if (self hasnt general) { print "You find your Ruby Poo underoos."; give underoos ~concealed; give self general; rtrue; } "You don't find anything else."; ], has enterable supporter static ; Object -> underoos "Ruby Poo underoos" with name "my" "your" "ruby" "poo" "underoos" "roos" "under" "lucky" "wear" "underwear", description "Ah. Your good old Ruby Poo underoos. The luckiest of lucky underwear. You've worn them every time you've ever gotten lucky. But then, maybe that has something to do with never changing them. Naaah. ", before [; Take: print "As you pick your underwear up, something utterly unbelievable happens. The underwear begins struggling in your grasp! Finally, it bites you on the hand, causing you to drop it. It huddles in the corner, growling. This must have been caused by that meteorite that crashed near you. That, or it has something to do with never changing your underwear. "; move liveundies to bedroom; remove self; rtrue; ], has concealed ; Object -> closetdoor "closet door" with description "It's just a closet door. ", name "door" "closet", door_to [; if (location==bedroom) return closet; return bedroom; ], door_dir [; if (location==bedroom) return w_to; return e_to; ], found_in bedroom closet, before [; Open: give closet light; Close: give closet ~light; ], has static door openable scenery ; Object -> decorations "decorations" with name "decorations", description "Assorted, but unimportant. ", has scenery ; Object kitchen "Your Kitchen" with description "Kitchen (ki' chun) n. - A room in which food is prepared. This particular ki' chun has a toaster, a fridge, a hallway leading west, a dark passageway leading down into the cellar, and a hallway leading north to the entryway of your home. ", before [; Drop: if (noun has clatters) { if (parent(sock)==toaster) { print "When you drop ", (the) noun, " it clatters on the floor, waking up the socks! They leap from the toaster, latching on to you with their terrible elastic mouths. Gradually, the venom in their bite overcomes you, and you pass out..."; deadflag = 1; rtrue; } else { print (The) noun, " clatters noisily on the kitchen floor tiles. "; move noun to kitchen; rtrue; } } ], w_to bedroom, n_to entryway, d_to [; if (self hasnt general && shoes hasnt worn) { print "As you recall, there's an awful lot of broken glass, rusting staples, and the like down there. It would probably be good to make sure you're wearing shoes before you go down these stairs. But, if you want to chance it anyways, then on your head lies the blame. "; give self general; rtrue; } else if (deadundies hasnt worn) { "You want to walk down into that freezing cellar without even the barest of protection? No way, go put some underwear on. "; } else return cellar; ], has light ; Object -> broom "broom" with name "broom", initial "There is a broom leaning against the counter. ", description "Your broom. There is a rubbermade sticker on the end of it, near the bristles. ", has clatters transparent ; Object -> -> sticker "rubbermade sticker" with name "sticker" "rubbermade", description "It reads 'Rubbermade.'", before [; Take: if (parent(self)==broom) { "It's stuck to the broom."; } else { print "Respectfully, you pick up the sticker, then, on a sudden impulse, you tie it around your head, like a bandana. Your broom will not go unavenged!"; move bandana to player; StartDaemon(bandana); remove self; rtrue; } ], ; Object -> toaster "toaster" with name "toaster", description [; print "The toaster has a lever on its side. The lever is currently "; if (lever has general) print "down. A warm glow comes from the toaster. "; else print "up. "; if (parent(sock)==self) print "There is a sock in each slot. They are asleep. Apparently they have built a nest in your toaster. "; if (parent(deadsock)==self) print "There is a well toasted sock in each slot. So much for the toaster warming party. Heheheh. "; rtrue; ], before [; Take: "Why bother? "; ], has transparent ; Object -> -> lever "lever" with name "lever", before [; Push: self.toast(); rtrue; Pull: self.toast(); rtrue; ], toast [; if (self has general) "It has already been pushed! "; if (parent(sock)==toaster) { print "Gently, so as not to wake the fearsome socks, you push down the lever. "; give self general; StartTimer(self, 2); } else { print "You push down the lever. "; give self general; StartTimer(self, 2); } ], time_left 1, time_out [; give self ~general; if (parent(sock)==toaster) { if (parent(player)==kitchen) print "The socks are overcome by heat stroke and die. The lever pops up with a cheery snap, hurling the socks onto the floor. "; else print "You hear a cheery snap off in the kitchen. Toast anyone?"; remove sock; move deadsock to kitchen; Achieved(4); } else { if (parent(player)==kitchen) print "The lever pops up with a cheery snap. "; else print "You hear a cheery snap off in the kitchen. Toast anyone?"; } ], ; Object -> -> sock "pair of lurking socks" with name "sock" "socks" "lurking" "pair" "of", description "Your socks have mutated into something fearsome that likes to lurk in dark places and eat unwitting adventurers such as yourself. The sock's natural habitat is apparently the toaster. I wouldn't wake those socks up if I were you.... ", before [; Examine: ; default: self.kill(); rtrue; ], kill [; print "The socks leap from the toaster in a flash, fastening themselves onto your body with their terrible elastic mouths. You struggle mightily in their grip, but to no avail. Gradually, the venom from their bite drags you down into oblivion. "; deadflag = 1; ], ; Object -> fridge "refrigerator" with name "fridge" "refrigerator" "baking" "soda", description "The fridge is the newest in bachelor fridges, made entirely of baking soda. After awhile in there with the door shut, anything smells better.", before [; Close: if (parent(liveshoes)==self) StartDaemon(self); Take: "You consider the fridge as visions of hernias dance before your eyes. No thanks. "; Open: if (parent(liveshoes)==self) { print "The shoes hop out of the fridge. "; move liveshoes to kitchen; StopDaemon(self); self.counter = 0; give self open; rtrue; } ], counter 0, daemon [; self.counter++; switch(self.counter) { 1: "A frantic pounding comes from within the fridge."; 2: "The pounding grows weaker."; 3: print "The pounding stops. "; move shoes to fridge; Achieved(2); remove liveshoes; } ], has container openable static ; Object -> -> glowstick "glowstick" with name "glowstick" "stick" "glow", description "You put this in the fridge after the little light burned out. It's guaranteed for another six centuries or so. Probably toxic as can be, too.", before [; Eat: print "Lacking anything remotely resembling common sense, you down the glowstick in one gulp. A tingling, crawling sensation flutters across your skin as the room begins to shrink. Looking down at your hands, you see them twist into hideous claws as fur sprouts from your body. Bursting through the roof of your house, you find that you now stand fifty feet tall, a hairy monstrosity vaguely resembling a werewolf. You feel a tickling feeling in your throat and cough. Flame shoots out of your mouth, destroying a nearby home in the process. People point and shout as a terrible anger takes hold of you, and you begin to crush and burn the city to the ground.^ Abruptly, you notice a tiny figure looking up at you in horror, and your mind registers the name 'Cindy.' You reach down and pick her up screaming. An idea trickles through your chemically deranged brain, and you head for the convenience store where you bought the first glowstick.^ Eight weeks later, after having destroyed twelve major cities, thirty-two suburbs, and New Jersey, the two of you build a nest out of scrap metal left over from the army vehicles you've destroyed and settle down to raise a family. The rest of the world, having tried every weapon known to man and giving you no more than slight indigestion from the atomic bombs, realizes that fifty-foot-tall, egg-laying, fire-breathing werewolves are just something they're going to have to learn to live with."; deadflag = 2; monster = true; rtrue; ], has clatters light edible ; Object -> -> lysol "can of lyesmall" with name "can" "lyesmall", description "Lyesmall. Hmm. Guaranteed to clear up any odor. Just 'spray can at ' to use. There's also a warning label that says not to use the stuff near open fires. Good thing there aren't any open fires in this game. ", has clatters ; Object cellar "Your Cellar" with description "Illuminated by the green glow of your glowstick, the cellar is indeed a fearsome place. The floor is littered with various sharp rusty objects. ", before [; if (silence) "Ssh! Show some respect for the dead! "; ], after [; if (shoes hasnt worn) { print "^As you walk out onto the floor, you step on a sharp, rusty nail. You try to scream, but your jaw has already frozen up, and you quickly succumb to tetanus. "; deadflag = 1; } else if (self hasnt general) { print "^The shoes protect your feet from the various sharp, rusty items.^"; Achieved(0); give self general; StartDaemon(moth); StartTimer(self, 1); } ], time_left 1, time_out [; print "^You hear a faint knock at the front door, followed by the sounds of it opening, and a scream!^ ~Hang on, Cindy! I'm coming!~ you shout.^"; move suit to entryway; move cindy to entryway; ], u_to kitchen ; Object -> rustys "assortment of sharp, rusty items" with name "sharp" "rusty" "assortment" "of" "items", description [; print "These items look to be a breeding ground for tetanus. You always meant to sweep up down here, but now *sniff* it's too late."; if (self hasnt general) { give self general; silence=true; "^^A moment of silence for your dearly departed broom, please. "; } ], has scenery ; Object -> jar "jar" with name "jar" "clear" "plastic" has clatters container transparent openable ; Object -> moth "moth" with name "moth", description "The moth flutters around your glowstick, seeming to like it quite a bit. ", initial "A moth flutters around. ", before [; Take: "You can't seem to catch it. "; ], daemon [; if (parent(self)==parent(suit)) { print "^The moth, seeing the delicious looking shirt and pants, makes a beeline for the living clothes. The clothes make a break for the door, but the moth is upon them before they can get away. It darts inside the shirt. The clothes go wild and start beating at themselves, but the moth is apparently eating whatever makes them move, for they slow down and crumple to the ground. A rather fat moth flies out, and weaves its way outside, with a final dip in its flight as though to say, ~Thanks for dinner, buddy!~ You resolve to throw away all your mothballs.^ ~W-What was that?~ stammers Cindy.^ ~I'll tell you on the way to dinner. Right now, let me finish getting dressed. It's been a long day.~"; move shirt to entryway; move pants to entryway; StopDaemon(moth); remove suit; remove moth; } else if (parent(glowstick)==jar && parent(self)==parent(player) && jar has open && ~~ parent(self)==jar) { print "^The moth flutters into the jar.^"; if (self hasnt general) { give self general; } Achieved(3); move self to jar; } else if (parent(self)==jar) { if (jar has open) { print "^The moth flutters back out of the jar.^"; if (parent(jar)==player) move self to parent(player); else move self to parent(jar); } else "^The moth flutters around in the jar.^"; } ], life [; Answer: "Moths can't talk. "; Ask: "Moths can't talk. "; Tell, Show, Give: "The moth seems suitably impressed. "; Attack: "You miss. "; Kiss: "No thanks. You have no desire to kiss a moth. "; ThrowAt: move noun to location; <>; ], has animate ; Object entryway "Your Entryway" with description "This is your plain old entryway. There are a thousand places for clothing to hide. The only thing to do is let the clothing make the first move. The front door leads north. The kitchen lies south. ", s_to kitchen, n_to [; if (~~ (shirt has worn && pants has worn) ) { print "You're not dressed yet"; if (parent(suit)==parent(cindy)) print " (and Cindy's still a prisoner.)"; else print "."; } else self.win(); ], win [; print "You and Cindy walk out to the car, and drive to a nice little Italian bistro. You explain the whole sordid affair to her over garlic bread and wine, while waiting for your meal. You pause periodically to allow her to gasp in fear as you tackle the nine-foot killer Underoos, the ravenous mutant shoes, the horrible socks, and after embellishing only somewhat, you arrive at the point where you rescued her. She leans forward, gazing into your eyes.^ ~My hero.~ she murmurs, and kisses you gently on the lips.^ Abruptly, a wolf whistle, followed by a crude ~Hot Momma!~ pipes from between your legs.^ ~That better be my underoos.~ you think to yourself, heading for the bathroom...."; deadflag = 2; rtrue; ], has light ; Object closet "Your Closet" with description "Ah, the cathedral of clothes. Only, you wonder why it's empty? The exit lies back to the east. ", e_to closetdoor ; Object -> liveshoes "shoes" with name "shoes" "stinky" "your" "my", description "Living shoes. Welp. That's something you don't see every day. Worse yet, they stink something fierce.", article "your", initial "Your shoes are here, hopping about and smelling terribly.", flee [; switch(parent(self)) { closet: print "The shoes bolt out into your bedroom. "; move self to bedroom; bedroom: print "The shoes hop into the kitchen. "; move self to kitchen; kitchen: if (fridge has open) { print "The shoes flee into the fridge. "; move self to fridge; } else { "The shoes hop around in circles. "; } fridge: "The shoes huddle back into the rear of the fridge. "; } ], before [; Take: "They hop playfully out of reach. "; Attack: "But they're so cute! They just stink is all. "; ], life [; Answer: "The shoes don't respond. "; Ask: "One of the shoes says something surprisingly like ~Momma!~ Awww, it thinks you're its mommy. Isn't that cute? "; Tell, Show, Give: "The shoes seem suitably impressed. "; Kiss: "No thanks. They might slip you some tongue."; ], has animate ; Object deadundies "Ruby Poo underoos" with name "underoos" "underwear" "roos" "wear" "ruby" "poo" "under" "lucky", description "Your relationship with your underoos may never be the same, but at least you can wear them again. ", article "your", has clothing ; Object liveundies "Ruby Poo underoos" with name "underoos" "underwear" "roos" "wear" "ruby" "poo" "under" "lucky", article "your", description "They look like your underoos, but in a surprise move, right out of 'Night of the Comet', they seem to have come to life. (Well, maybe not a surprise move. After all, the title of the game WAS 'The Underoos That Ate New York', and they can hardly do that without coming to life, can they?) ", before [; Take: "They snarl menacingly, and you decide not to risk your hand in the attempt. "; Attack: if (parent(broom)==player) { print "You tentatively poke the broom towards the underoos. The broom is almost jerked out of your hands, and you hurriedly pull it back. The bristly end has been bitten clean off. You look accusingly at your underoos, but they only belch up a Rubbermade sticker. "; move staff to player; move sticker to bedroom; remove broom; rtrue; } else if (parent(staff)==player) { print "Angered at the wanton destruction of your broom, you assume a karate movie stance. ~En garde, you elastic nightmare!~ you yell, and wade in with a flurry of blows, thrusts, and parries that leave the underoos dazed and confused. Finally, you begin spinning the broom handle over your head, and change its momentum into a tremendous blow that hurls the underoos across the room to lie still by your bed. "; move deadundies to bedroom; Achieved(1); remove self; rtrue; } else "You have nothing appropriate to attack with. "; ], life [; Answer: "The underoos don't respond. "; Ask: "The underoos just growl at you. "; Tell, Show, Give: "The underoos just growl at you. "; Kiss: "No thanks. You might lose your tongue doing that."; ], has animate ; Object staff "broom handle" with name "broom" "handle" "staff", description "The remains of your once proud broom. Tears fill your eyes as you remember all those hours spent sweeping pizza crumbs off the kitchen ceiling.", has clatters ; Object bandana "rubbermade bandana" with name "bandana" "sticker" "rubbermade", description "The bandana says, ~Rubbermade.~ Watch out world! ", daemon [; if (self has worn && random(100)<11) { print "^Wheoweo! Wanh WANH Wanh!"; if (self hasnt general) { print " [A little 'Good, Bad, and Ugly mood music for you.] "; give self general; } "^"; } ], has clothing worn ; Object deadsock "pair of socks" with name "pair" "of" "socks" "sock", description "Ordinary old socks, now that you've vanquished them. ", has clothing ; Object shoes "pair of shoes" with name "pair" "of" "shoes" "shoe", description "Poor things. They must've suffocated in the fridge. Oh well, they're wearable once more, at any rate!", before [; Wear: if (deadsock hasnt worn) "Those chilly shoes on your bare feet? Are you sick? Where are your socks?"; ], has clatters clothing ; Object suit "shirt and pants" with name "shirt" "pants" "clothing", description "Your shirt and pants are here, holding Cindy hostage with a knife. ", initial "Your shirt and pants are here, holding Cindy hostage with a knife. ", life [; Answer: "The suit doesn't respond. "; Ask: "The suit doesn't say much. "; Attack: "As you move near, the shirt presses the knife against Cindy's neck. You back off. "; Tell, Show, Give: "The suit ignores you. "; ], has animate transparent ; Object -> knife "knife" with name "butcher" "knife", description "Nice and sharp. Damn, when did clothes figure out the difference between a butter knife and a butcher knife?", has clatters ; Object shirt "shirt" with name "shirt" "my" "your", article "your", description "Your shirt, recently disarmed. ", has clothing ; Object pants "pants" with name "pants" "my" "your", article "your", description "Your pants, recently disarmed. ", has clothing ; Object cindy "Cindy" with name "cindy" "girlfriend" "friend" "girl" "my", description [; print "This is Cindy, your girlfriend. "; if (parent(suit)==parent(self)) "She is currently being held captive by your shirt and pants. "; rtrue; ], initial [; if (~~ parent(self)==parent(suit)) "Cindy is here, looking grateful. "; else rtrue; ], counter 0, before [; Kiss: if (parent(suit)==parent(self)) { "Much as you long to press your lips against her full red counterparts, getting that close right now might incite the shirt to kill her. "; } else { self.counter++; switch(self.counter) { 1: "You press your lips against hers. She seems happy to see you. "; 2: "You kiss her again, more firmly this time. She responds in kind. ~Mmm. My hero.~ she murmurs in your ear. "; 3: print "Inflamed with desire, you crush her against yourself, and the two of you raise the temperature in the room with your passion. Gasping, she pulls out of the kiss and looks you in the eye. ~We don't really HAVE to go out tonight, do we?~^ Picking her up and carrying her towards the bedroom is all the answer she needs. A pity that all your efforts getting dressed are going to be wasted though. "; secret=true; deadflag = 2; } } ], life [; Answer: "She seems distracted. "; Ask: "Cindy has never been much for words. "; Tell, Show, Give: "She seems distracted. "; Attack: "No way, she's your girlfriend! "; ], has animate proper ; [ Initialise; location = shazam; lookmode=2; thedark.description = "It's pitch black. You are likely to be eaten by a sock. "; "^^Yesterday, as you were walking through Central Park, a meteorite crashed nearby, bathing you in cosmic radiation. It only made the twelth page of the paper, under Dear Abby. Of course, if anyone could have foreseen the awful effects of that accident, it surely would have been a front page story. But there was no way for you, or anyone else, to predict that the result of that accident would be....^"; ]; [ DarkToDark; print "Oh no! You walked into the slavering fangs of a lurking sock. "; deadflag = 1; ]; [ InScope person i; if (person==player && location==thedark) objectloop (i near player) if (i==closetdoor) PlaceInScope(i); rfalse; ]; [ SprayAtSub; if (noun==lysol) { if ((parent(player)==closet) && (closetdoor hasnt open)) { "Probably not a good idea. These aerosols can be lethal in small, enclosed areas. "; } else if (parent(player)==kitchen && parent(sock)==toaster) { print "The socks are awakened by the hissing of the aerosol can. They leap from the toaster in a flash, fastening themselves onto your body with their terrible elastic mouths. You struggle mightily in their grip, but to no avail. Gradually, the venom from their bite drags you down into oblivion. "; deadflag = 1; } else if (second==liveshoes) { liveshoes.flee(); } else "Mmm. Lemon scent! "; } else "You can't spray that! "; ]; [ XyzzySub; "A hollow voice says, ~This is a short sample 'game' designed to test out some programming ideas I had. It pays homage to the bad old sci-fi B movies. The material here is, I suppose, vaguely mystifying to small children, so parents be warned, play it through first yourself, and make your own decision about it.~"; ]; [ PrintTaskName ach; switch(ach) { 0: "dodging tetanus"; 1: "practicing your karate"; 2: "freshening your shoes up"; 3: "collecting insects"; 4: "defeating the lurking socks"; 5: "paying your respects (easter egg)"; } ]; [ PrintRank; print ", earning you the rank of "; if (monster) switch(score) { 0: "Dirty Mutant."; 1: "Shoeless Kong."; 2: "Gamera Wearing Matching Socks."; 3: "Well Groomed Werewolf."; 4: "Fashion Hound of the Baskervilles."; 5: "Sharp Dressed Mothra."; 6: "Easter Egg Godzilla."; } else switch(score) { 0: "Dirty Underwear."; 1: "Shoeless Joe."; 2: "Color Coordinated."; 3: "Well Groomed."; 4: "Fashion Hound."; 5: "Sharp Dressed Man."; 6: "Easter Egg Guru."; } if (secret) " Plus, you found the secret ending! "; ]; Verb 'spray' * held 'at' noun -> SprayAt; Verb 'xyzzy' * -> Xyzzy; Include "Grammar"; end;