! "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 <object>' 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; <<Attack self>>;
],
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! ";
];