! _Shade_ ! Special source-code edition ! Copyright 2000-2002 Andrew Plotkin ! http://www.eblong.com/zarf/if.html ! This source code is provided for personal, educational use only. ! See README file for details. [ LivingLookNooks; if (kitchen in Apartment && bathroom in Apartment) { print " A kitchen nook one way and a bathroom nook the other, with a closet to the side."; return; } if (bathroom in Apartment) { print " A bathroom nook and closet are to the side."; return; } if (kitchen in Apartment) { print " A kitchen nook one way and a closet the other."; return; } print " A closet to one side."; ]; Object Apartment "apartment" with articles "Your" "your" "your", seenonce false, description [ ix; if (GoalClosed(window)) { print "Sunlight cuts across the room like hot butter, blazing from the window. The room is nearly barren now; walls and ceiling are blank, but for the window, the closed front door, and the full-length mirror across from them.^^"; print "The futon sits alone in the center of the room. Next to it, askew on a pile of sand, rests the faithful old stereo.^"; DescribeParagraph(self); rtrue; } ix = FindZone(player); switch (ix) { futon, Apartment: if (~~self.seenonce) { new_line; print "Odd, how the light just makes your apartment gloomier. Pre-dawn darkness pools in the corners and around the tops of walls. Your desk lamp glares yellow, but the shadows only draw your eyes and deepen.^^"; print "Not much of an apartment, no."; } else { print "You survey your one small room."; } if (desk in Apartment) print " One desk, paper-piled, with a dusty computer shoved to the side."; print " Your futon"; if (player in futon && self.seenonce) print ", upon which you sit"; print "."; print " Second-hand stereo"; if (crate in Apartment) print " sitting on a cardboard crate"; print "."; LivingLookNooks(); kitchen: print "You survey your one small room. "; kitchen.description(); print "^The rest of the place is mostly filled by your futon"; if (desk in Apartment) print ", and the computer desk in the corner"; print "."; if (bathroom in Apartment) print " The bathroom alcove is across from you, and the closet next to it."; else print " The closet is across from you."; print " The stereo sits on"; if (crate in Apartment) print " a cardboard crate"; else print " the sandy floor"; print "."; bathroom, shower: if (player in shower) { shower.description(); print "^Beyond the curtain, your apartment is"; } else { print "You survey your one small room. "; bathroom.description(); print "^The rest of the place is"; } print " mostly filled by your futon"; if (desk in Apartment) print ", and the computer desk in the corner"; print "."; if (kitchen in Apartment) print " The kitchen alcove is across from you, and the closet just to one side."; else print " The closet is just to one side."; print " The stereo sits on"; if (crate in Apartment) print " a cardboard crate"; else print " the sandy floor"; print "."; desk: print "You glance around. "; desk.description(); print "^Behind you, the futon takes up most of the apartment."; print " A second-hand stereo sits on"; if (crate in Apartment) print " a cardboard crate"; else print " the sandy floor"; print "."; LivingLookNooks(); default: print "[BUG] Player not in zone."; } print " A broad mirror tries to make the place seem twice its size; it halfway works."; print " One window, whose shade is"; if (windowshade hasnt open) print " down"; else print " up"; print ", and the front door"; if (frontdoor hasnt open) print " firmly shut"; else print " wide open"; print ".^"; if (self.seenonce) { if (desk in Apartment) { print "^The place is still too dim, except the corner where the desk lamp is somehow too bright.^"; } else { print "^The room is very dim, now. Blackness creeps around the windowshade.^"; } } DescribeParagraph(self); if (~~self.seenonce) { print "^You are sprawled on the futon, staring up into that gloom. Your eyes feel gritty. But it's too late -- early -- no time left for sleep, anyway. In a few hours your ride will arrive.^"; self.seenonce = true; } rtrue; ], before [; Go: "You paced enough last night."; Exit: if (player notin self) rfalse; <>; Listen: if (noun == 0) { if (motornoise in self) { if (stereo in self && stereo has on) { ; new_line; } <>; } if (stereo in self) <>; } else if (noun == u_obj) { if (GoalOpen(kitchen) || GoalOpen(bathroom)) "The creaking grows louder."; } Examine: switch (noun) { d_obj: if (GoalClosed(tickets)) "It's a bit sandy."; else "It's a bit dusty."; } rfalse; ], locseealso kitchen bathroom, sand_obj 0, leave_fragment " [BUG] step out into hyperspace", enter_fragment " [BUG] fall out of hyperspace"; Object -> apartmentproxy "living room" with name 'living' 'main' 'room' 'apartment', before [; Examine, Search: <>; Enter: if (player in Apartment) "But you're already in the living room."; MoveToZone(Apartment, 1); rtrue; Receive: <>; ], has scenery; Object -> crate "cardboard crate" with name 'cardboard' 'carton' 'crate', description "The crate your computer arrived in. It's dented and disreputable now, but still serves the time-honored purpose of holding your stereo up.", before [; Take: if (GoalOpen(self)) <>; "The cardboard crate is useful where it is."; Open, Search: if (OIU(self)) rtrue; if (GoalOpen(self)) <>; "You know it's empty."; Close: if (OIU(self)) rtrue; if (GoalOpen(self)) <>; "The cardboard crate is already closed."; Attack: if (OIU(self)) rtrue; if (GoalOpen(self)) <>; "You produce a pleasing thumpty sound."; Touch: if (GoalOpen(self)) { Goaled(self); remove self; BumpSand(livingsand); "You barely touch it, and the heavy cardboard abruptly tears. Sand pours out across the living room floor. The stereo sags; in moments, the crate is reduced to paper rags, which are immediately buried in the sand."; } rfalse; Rub, Push, Pull: if (GoalOpen(self)) <>; rfalse; ], prereqs [; return (GoalClosed(bathsink) || GoalClosed(kitchensink)); ], imp [; fridge.startup(); return -1; ], has scenery; Global stereosmartcount = 0; Object -> stereo "stereo" with name 'stereo' 'radio', description [; print "The stereo is old, dating from the era when matte-black, featureless, and opaque were the watchwords of hipness. It still works, however"; if (self has on) { print ", as the strains of "; self.song(); print " demonstrate"; } "."; ], before [; Listen: if (self hasnt on) "The stereo is off."; print "You are listening to "; self.song(); "."; LookUnder: if (crate in Apartment) { "The stereo is resting on a cardboard crate."; } rfalse; ], after [; SwitchOn: self.number = random(32761); StartDaemon(self); print "The stereo buzzes, hunts, and then locates its station."; if (~~self.seenonce) { self.seenonce = true; print " Ah, your favorite small-time indy worldbeat/techno station. At least you think that's what they call it. It's a pretty stream-of-consciousness format.^^"; } else { print " "; } print "The room fills with the sound of "; self.song(); "."; SwitchOff: "You turn off the stereo."; ], startup [; if (self hasnt on) { self.number = random(32761); print "^Suddenly the room fills with the sound of "; self.song(); print ". What? Oh, yes -- you jiggered the stereo timer to act as an alarm clock, back when you still thought sleep was possible. Terrific. You've arrived at the morning, although the world outside is still dark. The taxi should be showing up soon."; print "^^Almost immediately, the hourly news comes on.^"; give self on; StartDaemon(self); } else { print "^The stereo clicks as "; self.song(); print " ends and the hourly news comes on. What? Morning must have arrived, although the world outside is still dark. The taxi should be showing up soon.^"; } self.number = -1; self.opentime = 0; ], seenonce false, number 0, opentime 2, longcount 0, daemon [; if (self hasnt on || parent(self) == 0) { StopDaemon(self); return; } if (self.number == -1) { self.opentime++; switch (self.opentime) { 2: print "^~More allegations of campaign finance misconduct...~ (Oh, fascinating news day.)^"; 3: print "^~Sharp words between the superpowers today...~ (Huh? There are still superpowers?)^"; 4: print "^~Three people reported missing at the Death Valley Om in California...~ (Hang on.) ~The popular desert arts festival was shaken yesterday when three attendees failed to return from moonlight hikes. State police are searching the area.~ (You resolve to read that desert camping book one more time.)^"; 5: print "^~In the business pages, stocks are down...~ (You once again lose interest.)^"; 6: self.number = random(32761); self.opentime = 0; print "^~And that's, um... far out. Back to the groove, folks,~ and "; self.song(); print " begins.^"; } rtrue; } self.opentime++; if (self.opentime >= random(3) + 3) { self.opentime = 0; self.number = random(32761); self.longcount++; if (self.longcount >= 15) { self.longcount = 0; print "^The radio mumbles, ~This is, um, one-oh-three... kay-tee-oh-whoa... your source for interworldbeat...~ You can practically hear the bong gurgling in the background. After a moment, "; self.song(); print " begins playing.^"; } else { print "^The radio begins playing "; self.song(); print ".^"; } } ], song [ num redundant; redundant = 0; num = self.number; if (num == -1) { print "the news"; rtrue; } if (num % 97 > 31) { switch (num % 13) { 0: print "an Afro-"; redundant++; 1: print "an Indo-"; 2: print "a reggae-"; 3: print "an Antarcto-"; 4: print "a Sino-"; 5: print "a Filipo-"; 6: print "a Hispano-"; 7: print "a Balto-"; 8: print "a polko-"; 9: print "a hypno-"; 10: print "an Austro-"; 11: print "a Franco-"; 12: print "an Appalacho-"; } } else { switch (num % 13) { 0: print "a haunting"; 1: print "a creepy"; 2: print "a jazzy"; 3: print "a thumping"; 4: print "a jittery"; 5: print "an electrifying"; 6: print "a soothing"; 7: print "a calm"; 8: print "an angry"; 9: print "a vibrant"; 10: print "a bouncy"; 11: print "a rhythmic"; 12: print "a repetitive"; } print " "; } switch (num % 19) { 0: print "Manx"; 1: print "Celtic"; 2: print "Korean"; 3: print "Japanese"; 4: print "Javanese"; 5: print "Balinese"; 6: print "Slavic"; 7: print "Hmong"; 8: print "Basque"; 9: print "Andean"; 10: print "Nigerian"; redundant++; 11: print "electronic"; 12: print "Sumerian"; 13: print "Atlantean (?)"; 14: print "Inuit"; 15: print "Estonian"; 16: print "Maori"; redundant++; 17: print "Shaker"; 18: print "Dominican"; } if (redundant==2) { stereosmartcount++; if (stereosmartcount == 1) print " (okay, it's redundant)"; } print " "; switch (num % 11) { 0: print "lullaby"; 1: print "chant"; 2: print "fugue"; 3, 4, 5: print "song"; 6, 7: print "melody"; 8, 9, 10: print "tune"; } ], has scenery switchable ~on; Object -> luggage "luggage" with name 'luggage' 'suitcase' 'suitcases', description [; print "You've packed and repacked: breakdown tent, dried food, sunscreen, compass, mylar space-blanket, long underwear and showoff tats, walking shoes and dancing shoes and hiking shoes. You're ready for the Death Valley Om.^"; BackgroundInfo(self, "As ready as you're likely to get."); if (GoalOpen(tickets)) { if (self.ticket_search == 0) { self.ticket_search = 1; print "^Oh dear. You didn't pack the tickets in with your luggage, did you?^"; } } ], ticket_search 0, background_flag false, subdescribe "Your luggage is piled untidily by the door.", before [; Open, Search: if (OIU(self)) rtrue; if (GoalOpen(self)) { Goaled(self); remove self; BumpSand(livingsand); "You grab a suitcase handle -- which crumbles dryly in your grip. In seconds and in silence, the whole row of suitcases and duffels has collapsed to white sand on the living room floor."; } if (GoalOpen(tickets)) { print "You quickly pop open each suitcase and riffle through, trying not to disarrange your tidy packing too badly. "; CheckTicket(self); rtrue; } "Oh, no. You spent hours jamming everything into the maximally packed configuration. If you disturb the luggage now, you fear, you'll still be repacking when the taxi arrives."; Close: if (OIU(self)) rtrue; "All the luggage is already closed."; Push, Pull, Take: if (OIU(self)) rtrue; if (GoalOpen(self)) <>; "That's hardly portable -- and I do mean ", (emph) "hardly."; Touch: if (GoalOpen(self)) <>; Empty, EmptyT: <>; ], prereqs closet stove, has scenery; Object -> plant "plant" with name 'pot' 'potted' 'plant' 'soil', short_name [; switch (self.number) { 0: print "hyacinth"; 1: print "spider plant"; 2: print "palm plant"; 3: print "cactus"; default: print "[BUG]"; } rtrue; ], parse_name [ wd num altwd; switch (self.number) { 0: altwd = 'hyacinth'; 1: altwd = 'spider'; 2: altwd = 'palm'; 3: altwd = 'cactus'; default: altwd = 'plant'; } wd = NextWord(); while (WordInProperty(wd, self, name) || wd == altwd) { num++; wd = NextWord(); } return num; ], subdescribe [; print "A potted "; self.short_name(); print " sits beneath the window."; rtrue; ], number 0, ! 0: hyacinth; 1: spider plant; 2: palm; 3: cactus startup [ level; if (self.number >= level) return; self.number = level; self.waterlevel = 0; ], waterlevel 1, description [; print "This plant is your one claim to actual responsibility. The "; self.short_name(); print " sits by the window, soaking up sunlight (when it's not night) and managing to thrive despite your lack of gardening skill."; switch (self.waterlevel) { 1: print " Although it looks a little parched at the moment."; 0: print " Although it looks very dry."; } new_line; rtrue; ], before [; Push, Pull, Take: if (OIU(self)) rtrue; "The plant is where it belongs."; Touch: if (OIU(self)) rtrue; switch (self.waterlevel) { 1: "The soil feels a bit dry."; 0: "The soil feels very dry."; 2: "The soil feels nicely moist."; 3: "The soil feels very moist."; } Attack: if (OIU(self)) rtrue; "The plant has enough problems."; ], receive_water [; if (self.number > 0) { "As you carry the glass over to ", (the) self, ", your foot slips. (You ", (emph) "really", " have to get that sand cleaned up.) The water spills everywhere but into the pot."; } if (self.waterlevel >= 3) { print "If you water it any more, it'll get root rot.^"; return 2; } self.waterlevel++; "You water the plant."; ], has scenery; Object -> mirror "mirror" with name 'full' 'length' 'broad' 'mirror' 'reflection', description [; print "The far side of the mirror is just as"; if (GoalClosed(window)) print " bright"; else print " shadowy"; " as this one. It's probably meant as commentary; not more space, just more of the same."; ], before [; Search, Examine: if (OIU(self)) rtrue; if (GoalOpen(self)) <>; self.description(); rtrue; Touch: if (OIU(self)) rtrue; if (GoalOpen(self)) <>; "You reach out and touch your hand to itself. It feels like glass."; Pull, Push, Take: if (OIU(self)) rtrue; "The mirror is firmly anchored to the wall."; Attack: if (OIU(self)) rtrue; "Seven years' bad luck ", (emph) "and", " a mess to clean up. You refrain."; Enter: if (OIU(self)) rtrue; if (GoalOpen(self)) { print "You look into the mirror. The far side is just as bright as this one. With the sunlight behind you, only your own face is in shadow -- the walls, the door, your furniture, are all full-lit. Beyond your reflection and the window-frame, the street outside, the houses and trees, are all --^^"; print (emph) "The street outside?"; print "^^You spin around.^^"; KeyPause(); print "^^^"; while (child(player)) { move child(player) to Apartment; } PlayerTo(FakeApartment); give stereo ~on; Goaled(self); rtrue; } "Popping in and out of mirrors, now? Wonderland isn't so close at hand."; ], prereqs window, has scenery; Object -> frontdoor "front door" with name 'front' 'door', description "The front door is white and rectangular -- yes. The door is closed.", seenonce false, before [; Open: if (OIU(self)) rtrue; if (GoalEverOpen(window)) { if (~~self.seenonce) { self.seenonce = true; desk.opentime = 9; ! no honk for a couple of turns print "You open the door.^^Outside is full night. You can see little... nothing. No taxi, no stars, not even streetlights. The world ends at your doorstep.^^^"; print (emph) "Quietly, the night begins to enter."; "^^^You are standing with your back to the closed door. You close your eyes, then tear them open; darkness is worse than the sand. Not so funny any more... you concentrate on slowing your breath."; } else { "You do not want that."; } } "The sun hasn't risen; what light you have would just leak out into the night. Anyway, the taxi hasn't arrived, so there's nowhere to go."; Search: if (OIU(self)) rtrue; "The door is closed."; Close: if (OIU(self)) rtrue; "The door is already closed."; Enter: if (OIU(self)) rtrue; if (GoalEverOpen(window)) <>; "The taxi isn't here yet."; ], has scenery; Object -> window "window" with name 'window', description [; if (windowshade hasnt open) { "The shade is drawn."; } "Outside, dunes roll away to the rising sun. Nothing else is visible. Only the sunlight that burns you, full in the face. And sand."; ], before [; Examine, Search: self.description(); rtrue; Attack: if (OIU(self)) rtrue; "You'd lose your security deposit. Also your air conditioning."; Open, Close: if (OIU(self)) rtrue; "The window-glass is sealed; it can't open or close. Some notion of thermal efficiency. Truthfully, you like it that way."; Enter: "You can't crawl through glass."; LookUnder: if (OIU(self)) rtrue; "Someone has labelled that space, in ballpoint pen."; ], prereqs kitchen bathroom desk, has scenery transparent; Object -> -> windowshade "windowshade" with name 'window' 'shade' 'windowshade' 'blind' 'blinds', parse_name [ wd firstwd num; wd = NextWord(); firstwd = wd; while (WordInProperty(wd, self, name)) { num++; wd = NextWord(); } if (num == 1 && firstwd == 'window') return 0; return num; ], description [; print "The shade is a white plastic sheet -- more yellowing, maybe. One of those roller mechanisms that never quite works."; if (self hasnt open) " The shade is pulled down against the pre-dawn gloom."; else " The shade is rolled all the way up."; ], before [; Search: if (self hasnt open) "The windowshade is opaque."; <>; LookUnder: if (self hasnt open) <>; <>; Pull, Turn: if (self hasnt open) <>; else <>; Enter: <>; Open, Raise: if (OIU(self)) rtrue; if (GoalOpen(window)) { KillImp(desk); frontdoor.seenonce = true; give self open; BumpSand(livingsand); plant.startup(3); RescueContents(closet); remove closet; Apartment.seenonce = 2; Goaled(window); print "And if you see no taxi outside? What then? ...but the angry honking comes again. You yank hard on the windowshade, and it whips up as violently.^^^"; print (emph) "Blazing daylight floods the room."; new_line; rtrue; } if (self has open) "The shade is already up."; "Darkness is already crawling around the edges of the windowshade. You have no desire to look night in the face."; Close, Lower: if (OIU(self)) rtrue; if (self hasnt open) "The shade is already down."; "But what if the night returns?"; ], has scenery ~open; Object -> closet "closet" with name 'closet' 'recess', parse_name [ wd num altwd; if (GoalOpen(self)) altwd = 'door'; else altwd = 'closet'; wd = NextWord(); while (WordInProperty(wd, self, name) || wd == altwd) { num++; wd = NextWord(); } return num; ], seenonce 0, description [ ix firsttime; print "The closet"; if (self.seenonce == 0) { self.seenonce = 1; firsttime = 1; print " (if you can call it that)"; } print " is a shallow recess"; if (bathroom in Apartment) print " next to the bathroom"; else print " next to, er, where the bathroom used to be"; print "."; if (self hasnt open) { if (~~(GoalOpen(self))) print " [BUG:]"; print " It's closed.^"; if (self.seenonce < 2) { self.seenonce = 2; print "^Wait. Didn't the closet lack a door when you moved in?^"; } rtrue; } ix = child(self); if (~~ix) { if (GoalClosed(self)) print " The closet is half-full of sand, but otherwise empty."; else print " The closet is empty."; } else { if (GoalClosed(self)) { print " Peering into the depths, you see deep-drifted sand, and also "; } else { print " Peering into the"; if (firsttime) print " (ahem)"; print " depths, you see "; } WriteListFrom(ix, TERSE_BIT + ENGLISH_BIT + CONCEAL_BIT); print "."; } new_line; rtrue; ], before [; Search, Examine: if (OIU(self)) rtrue; self.description(); rtrue; Enter: if (self hasnt open) "The closet is closed."; "It's not a walk-in closet. It's barely even a reach-in closet."; Open: if (OIU(self)) rtrue; if (GoalClosed(self)) "The closet will certainly never close again."; if (~~GoalOpen(self)) "The closet has no door. It might have once, if those are hinge-marks on the frame, but that must have been several tenants and a dozen coats of paint ago."; Goaled(self); give self open; BumpSand(livingsand); "You reach for the knob; then hesitate; then reach again.^^You might as well not have bothered. The closet door bursts off its hinges before you can touch it. You leap back, barely avoiding the cracking plywood as it smashes to the floor, buried in the torrent of sand that is pouring out of the closet.^^After a few seconds, the room is still again."; Close: if (OIU(self)) rtrue; if (GoalClosed(self)) <>; if (~~GoalOpen(self)) <>; "The closet is already closed."; ], prereqs [; return (GoalClosed(bathsink) || GoalClosed(kitchensink)); ], imp [; fridge.startup(); return -1; ], startup [; if (GoalOpen(self) && self has open) give self ~open; ], has scenery container open; Object -> -> jacket "old jacket" with name 'old' 'jacket' 'coat' 'xoron', article "an", description [; print "Your jacket hangs in the closet. This is, of course, your ", (emph) "old", " jacket -- vaguely waterproof but definitely ratty -- suitable only for errands around the city."; if (GoalClosed(luggage)) { new_line; rtrue; } print " Your ", (emph) "new", " jacket, windproof weatherproof sandproof Xoron(tm), suitable for desert hiking, is neatly packed away in your luggage.^"; BackgroundInfo(self, "Not that luggage is the important part."); if (GoalOpen(tickets)) { if (self.ticket_search == 0) { self.ticket_search = 1; print "^Now, you were wearing this jacket when you picked up the plane tickets...^"; } } ], ticket_search 0, background_flag false, before [; Take, Wear: if (OIU(self)) rtrue; "You don't need your old jacket."; Search: if (OIU(self)) rtrue; if (GoalOpen(tickets)) { print "You root through the jacket's myriad pockets. "; CheckTicket(self); rtrue; } "It's just an old jacket."; ], has static; Object -> -> vacuum "vacuum cleaner" with name 'luggable' 'vacuum' 'cleaner' 'innard' 'innards', description [; print "The vacuum cleaner is a ~luggable~ model -- meaning that it's awkward to carry, but too small to be really efficient. Fortunately, you don't generate a lot of dust."; if (self has open) { print "^^The vacuum cleaner is open, revealing vacuum cleaner innards."; } new_line; rtrue; ], before [ ix jx zowd; SwitchOn, Squeeze: if (OIU(self)) rtrue; ix = FindZone(player); if (ix && ix has supporter) "You can't use the vacuum cleaner while sitting."; jx = parent(self); if (~~(jx ofclass Zone || jx == Apartment || jx == player)) { print "The vacuum cleaner won't work usefully"; if (jx has supporter) print " on ", (the) jx; else print " in ", (the) jx; "."; } switch (ix) { kitchen: zowd = " kitchen"; bathroom: zowd = " bathroom"; shower: zowd = " stall"; default: zowd = ""; } if (self has open) { print "The vacuum cleaner can't be started while it's open."; if (self.number) print " Not that it looks likely to work in any case, now."; new_line; rtrue; } if (self.number >= 5) { if (self.number >= 10) "You squeeze the handle. Nothing happens. It's dead."; self.number = 10; Goaled(self); "You squeeze the handle. The vacuum cleaner makes an unpleasant grinding noise, and then stops entirely. The sand must have been too much for it."; } print "You squeeze the handle, and the vacuum cleaner begins humming"; if (self.number < 2) print " industriously"; else print ", albeit with a bit of a whine"; print ". You run it back and forth on the", (string) zowd, " floor"; if (GoalOpen(self) || GoalClosed(self)) { self.number++; if (ix && ix.sand_obj && ix.sand_obj.number > 0) { if (ix.sand_obj.number < 3) BumpSand(ix.sand_obj); ". But it only seems to spread the sand around. In fact, it looks like there's more sand than before you started."; } else { if (ix) BumpSand(ix); ". But after a few strokes, you hear an odd scraping sound."; } } print " for a few moments. It doesn't make much difference, but you feel tidy.^"; rtrue; SwitchOff: if (OIU(self)) rtrue; "This vacuum cleaner turns itself off automatically."; Open: if (OIU(self)) rtrue; if (self has open) "It's already open."; give self open; if (self.number) { self.number = 10; Goaled(self); ix = FindFloorZone(player); if (ix) BumpSand(ix); "You pop open the vacuum cleaner's casing. Sand spills out -- all over the floor. What the hell?"; } "You pop open the vacuum cleaner's casing. Inside are, well, vacuum cleaner innards. You've never really understood what goes on in there, but it doesn't look any different this time."; Close: if (OIU(self)) rtrue; if (self hasnt open) "It's already closed."; if (self.number) { "You try to close the casing, but sand has worked into the joints. You can't get it fully closed, even when you whack it."; } give self ~open; "You close the vacuum cleaner up again."; Examine: if (self has open && self.number) <>; Search: if (OIU(self)) rtrue; if (self hasnt open) "The vacuum cleaner is closed."; if (self.number) { print "The vacuum cleaner's innards are packed with sand."; if (~~self.seenonce) { self.seenonce = true; print " You can't imagine how it got that way."; } new_line; rtrue; } "Inside are, well, vacuum cleaner innards. You've never really understood what goes on in there, but it doesn't look any different this time."; Receive: if (self hasnt open) "The vacuum cleaner is closed."; "There's no empty space in the vacuum cleaner."; Wave: if (self has open && self.number) <>; Empty, EmptyT: if (OIU(self)) rtrue; if (self hasnt open) "The vacuum cleaner is closed."; if (self.number) { ix = FindFloorZone(player); if (ix && ix.sand_obj == 0) BumpSand(ix); "Some more sand sifts down out of the vacuum cleaner."; } "The vacuum cleaner's innards are unremovable."; Enter: if (verb_word == 'run') <>; ], seenonce false, after [; Take: "Taken. (Awkwardly.)"; ], number 0, prereqs tickets, opentime 0, imp [; self.opentime++; switch (self.opentime) { 1: stereo.startup(); 5: print "^It must be morning, after all -- your metabolism is starting to ratchet up to daytime levels.^"; 6: print "^You're definitely getting hungry.^"; 11: print "^Your stomach rumbles.^"; 18: print "^You consider the available food options.^"; 23: self.opentime = 9; } ], has rescuable ~open; Zone futon "futon" with name 'futon', articles "Your" "your" "your", description [ ix; print "The futon is definitely on the downhill side of life's rolling knolls. It serves as both couch and bed, if inadequately in each case, which makes it the most important piece of furniture you own.^"; ix = children(self); if ((player notin self && ix > 0) || ix > 1) { print "^Sitting on the futon"; if (player in self) print " next to you"; WriteListFrom(child(self), TERSE_BIT + ENGLISH_BIT + ISARE_BIT + CONCEAL_BIT); print ".^"; } rtrue; ], leave_barrier "You won't accomplish much while slumped on the futon. That's been getting slowly more apparent for hours now.", leave_fragment " stand up", enter_fragment [; if (random(101) < 40) print " flop down on the futon"; else print " sit down"; rtrue; ], locseealso kitchen bathroom, before [; LookUnder: if (OIU(self)) rtrue; if (player in self) print "You twist yourself head-down, and"; else print "You bend down, and"; if (Apartment.sand_obj && Apartment.sand_obj.number > 2) { print " see little"; if (Apartment.sand_obj.number < 5) print " but a bit of sand"; else print " but sand"; "."; } " see dust and assorted minor trash under the futon. Nothing unusual."; Pull, Push, Turn: if (OIU(self)) rtrue; "The futon is theoretically easy to move. In practice, you never bother."; Dig: if (OIU(self)) rtrue; "No loose change, sorry."; ], react_before [; Exit: if (player in self) { if (self.leave_barrier == NULL) { return self.Zone::react_before(); } self.leave_barrier = NULL; move player to Apartment; Goaled(firstgoal); "You lever yourself upright. Umf. It's amazing how much lack of sleep feels like a hangover, only without the preceding party."; } ], has supporter; Zone desk "desk" with name 'desk', description [ num; print "The desk is, of course, an organized mess; overlapping piles of paper, inches high. The computer is a dusty beige block, several generations out of date, poking up hopefully from among the strata. The lamp hangs over all.^"; if (computer has on) { print "^A game-over message is flashing on the screen.^"; } num = Locale(self, "You see", "You also see"); if (num) { print " on the desk.^"; } rtrue; ], nolocifin true, leave_fragment " stand up", enter_fragment " sit down at the desk", locseealso kitchen bathroom, before [ count ix; LookUnder: if (OIU(self)) rtrue; if (Apartment.sand_obj && Apartment.sand_obj.number > 2) { print "Nothing under the desk"; if (Apartment.sand_obj.number < 5) print " but a bit of sand"; else print " but sand"; "."; } "Nothing interesting is under the desk."; Take, Push, Pull: if (OIU(self)) rtrue; "The desk is too heavy to move."; Search: if (OIU(self)) rtrue; if (GoalOpen(self) || GoalOpen(tickets)) <>; count = 0; objectloop (ix in self) { if (ix hasnt concealed && ix hasnt scenery) count++; } print "Aside from the computer, the lamp, and piles of paper"; if (count == 0) ", there is nothing on the desk."; print ", you see "; WriteListFrom(child(self), TERSE_BIT + ENGLISH_BIT + CONCEAL_BIT); "."; ], prereqs closet shower, opentime 0, imp [; if (~~GoalClosed(kitchen)) return; if (~~GoalClosed(bathroom)) return; self.opentime++; switch (self.opentime) { 3: print "^You hear a car approaching outside.^"; 4: print "^A car horn honks outside.^"; 6: print "^The car honks again, more urgently. Your taxi -- it must be.^"; 7: print "^The taxi honks repeatedly.^"; 9: print "^The taxi honks repeatedly. The sound seems a little fainter now.^"; 11: self.opentime = 6; } ], has supporter; Object -> papers "papers" with name 'paper' 'papers' 'strata' 'pile' 'piles', description [; print "The papers encompass everything you've done, thought, or written in the past year. And none of it is really worth looking through.^"; if (GoalOpen(tickets)) { if (self.ticket_search == 0) { self.ticket_search = 1; print "^Or -- hmm. Maybe you left the plane tickets on the desk yesterday, before that late-night IF work session?^"; } } rtrue; ], seenonce false, ticket_search 0, before [; Examine: if (OIU(self)) rtrue; if (GoalOpen(desk)) <>; self.description(); rtrue; Search, LookUnder: if (OIU(self)) rtrue; if (GoalOpen(desk)) { plant.startup(2); RescueContents(desk); move computer to Apartment; give computer ~on; remove desk; Goaled(desk); "You carefully tilt up piles of paper, trying to avoid an avalanche. Yes, sand is scattered beneath.^^Carefully? You shove a paper-stack off the desk; it's a shower of sand before it hits the ground. Ha! You push another, and another, and then sweep the whole mass over the edge. White sand cascades everywhere. Laughing, you feel the desk itself give way.^^", (emph) "Pop.", " Oops. That was the light bulb imploding. The apartment is very dark and quiet of a sudden."; } if (GoalOpen(tickets)) { print "You carefully tilt up piles of paper, trying to avoid an avalanche. "; CheckTicket(self); rtrue; } "Nothing in all that mess do you want to see again, really."; Take, Push, Pull: if (OIU(self)) rtrue; if (GoalOpen(desk) || GoalOpen(tickets)) <>; print "What? And disorganize your piles? You'd never find a thing again"; if (~~self.seenonce) { self.seenonce = true; print "... well, not that you've looked for anything in these piles ever before. Your life merely accumulates, you've decided; it does not build"; } "."; ], has scenery pluralname; Object -> lamp "lamp" with name 'desk' 'lamp' 'clothespins' 'pin' 'pins', parse_name [ wd firstwd num; wd = NextWord(); firstwd = wd; while (WordInProperty(wd, self, name)) { num++; wd = NextWord(); } if (num == 1 && firstwd == 'desk') return 0; return num; ], description "The lamp is a peculiar goosenecked item that you found at a yard sale. It's clamped to the side of the desk, and balanced with a collection of clothespins. The lamp casts an uncomfortable yellow glare around the desk; it makes your eyes ache.", before [; Search: if (OIU(self)) rtrue; "You squint into the blazing light. If there is truth in there, you are blind to it."; Take, Pull, Push, Turn: if (OIU(self)) rtrue; "You don't dare fiddle with it. Only a precarious arrangement of clamps and clothespins prevents the lamp from giraffing itself flat and setting your desk on fire."; Touch: if (OIU(self)) rtrue; "The lamp is hot."; SwitchOn: if (OIU(self)) rtrue; "The lamp is already on."; SwitchOff: if (OIU(self)) rtrue; "You do not want the dark."; ], has scenery; Object -> computer "computer" with name 'computer' 'dusty' 'beige' 'block' 'screen' 'keyboard' 'monitor' 'text' 'game' 'adventure' 'if' 'interactive' 'fiction', seenonce false, description [; print "The computer is years old, and incompatible with just about everything but electricity. You use it for writing -- at least, you try to believe that you do.^"; if (self has on) { if (~~self.seenonce) { self.seenonce = true; print "^Right now, however, there's a game on the screen -- one of the text adventures, or interactive fictions, or whatever they are this month -- the only kind of game your beige antique can run, anyway.^"; } print "^The you-have-died message is blinking morosely at you. You started up ", (emph) "Ready, Okay!", " last night, trying to distract yourself until morning. But you can't get even halfway through without running out of insulin.^"; } else { print "^The computer is off.^"; } rtrue; ], nosubdescribe [; return (self in desk); ], subdescribe "The computer has survived somehow, and lies in a pile of sand.", before [; Examine, Search: if (OIU(self)) rtrue; self.description(); rtrue; Play, TypeOn: if (OIU(self)) rtrue; if (self hasnt on) "The computer isn't on."; "You've tried everything you can think of twice, and you're tired of trying. Maybe an idea will come to you later."; SwitchOff: if (OIU(self)) rtrue; if (self hasnt on) "The computer is already off."; give self ~on; "You hit the power key; the computer gives a tiny sigh and shuts down."; SwitchOn: if (OIU(self)) rtrue; if (self has on) "The computer is already on."; "You hit the power key; nothing happens. Terrific. Something's finally fried itself in the bowels of your twelve-megahertz wonder, and you may never die in a text adventure again."; Attack: if (OIU(self)) rtrue; if (self has on) "Violence isn't the answer to that game."; else "You thump hopefully. But when you hit the power key again, the computer remains dead."; Smell: if (OIU(self)) rtrue; if (self has on) "The computer smells of ozone and fried dust."; "You lean close. Yes, the scent of burnt insulation drifts from the vents."; Open: if (OIU(self)) rtrue; "This model can't be opened except at the factory. (And as far as you know, the factory was destroyed in the Pyong-Yang Flood of 1990.)"; LookUnder: if (OIU(self)) rtrue; "Yes, your computer has LRF support."; ], has scenery on; Object -> todo "to-do list" with name 'list' 'to-do' 'to' 'do' 'todo' 'task', articles "Your" "your" "your", description [; print "The task list for your impending journey is a mess of crossed-out items and scribbled corrections."; if (GoalClosed(window)) { " It is entirely illegible."; } if (GoalOpen(window)) { print " At the very bottom of the page, you see:^"; print " - call taxi^"; print " - wait for taxi^"; print " - look, make sure it's actually taxi before opening door^"; " (That last entry in a hasty, nervous script.)"; } if (GoalClosed(bathsink) || GoalClosed(kitchensink)) { print " In the middle of the page, you see:^"; if (GoalOpen(closet)) print " - clean out closet^"; if (GoalOpen(crate)) print " - buy stereo stand^"; if (GoalOpen(stove)) print " - don't leave stove on^"; if (GoalOpen(fridge)) print " - defrost refrigerator^"; if (GoalOpen(shower)) print " - unclog shower drain^"; if (GoalOpen(luggage)) print " - pack clean socks^"; if (GoalOpen(cupboard)) print " - remove package from kitchen storage^"; if (GoalOpen(desk)) print " - find notes for IFComp entry^"; if (GoalOpen(toilet)) print " - flush notes down toilet^"; if (GoalOpen(kitchen)) print " - stay out of kitchen!^"; if (GoalOpen(bathroom)) print " - stay out of bathroom!^"; rtrue; } if (GoalOpen(bathsink) || GoalOpen(kitchensink)) { " Dammit, yet another item you missed -- you have to water the plant."; } if (GoalOpen(vacuum)) { " Huh. ~Vacuum~ is checked; you remember doing it. But look at this floor."; } if (GoalOpen(tickets)) { " There, near the bottom; ~Buy plane tickets~, and a checkmark. So where did you leave them? The desk? Your coat pocket? Could they have gotten packed accidentally?"; } " However, everything seems to have gotten done. The last line reads ~Call taxi~, and it has its checkmark, and here you wait."; ], before [; Examine, Search: if (OIU(self)) rtrue; self.description(); rtrue; ], has rescuable; Object -> book "travel book" with name 'travel' 'survival' 'book' 'schmendrick' 'desert' 'camping' 'guide', saw_blank false, number 0, description [; if (GoalClosed(mirror)) { if (player.orders == 0) { print (emph) "The Desert Elemental's Handbook", " -- you've been studying it for ages. Trace moisture segregation, arthropod ecocycles, sand/grit/fines sizing distributions. And, of course, the artistic aspects of heat, time, distance, and death.^"; switch (random(91) % 9) { 0: print "^You're especially fond of"; 1: print "^You re-read"; 2: print "^You look up"; 3: print "^You come across"; 4: print "^You study"; 5: print "^You memorize"; 6: print "^You skim through"; 7: print "^You're fond of"; 8: print "^You consider"; } switch (random(107) % 9) { 0: print " the chapters on"; 1: print " a section on"; 2: print " some tables of"; 3: print " the pages on"; 4: print " a few paragraphs about"; 5: print " some key points about"; 6: print " the chapter about"; 7: print " a page of"; 8: print " an essay on"; } self.number++; switch (self.number) { 1: print " bones"; 2: print " starvation"; 3: print " scorpions"; 4: print " thirst"; 5: print " snakes"; 6: print " sandstorms"; 7: print " sunstroke"; 8: print " stings"; 9: print " thirst"; 10: print " dunes"; 11: print " aridity"; default: print " thirst"; self.number = 0; } "."; } else { self.saw_blank = true; "The cover is worn now. The pages are all blank."; } } if (GoalClosed(fridge) || GoalClosed(shower) || GoalClosed(luggage)) { print (emph) "The Schmendrick's Guide to the Desert", " -- you've been studying it for what seems like forever. Endless miles of information: colors of silence, sounds of heat and sunlight, the feel of vast distances on your skin, and death. It sounds beautiful.^"; rtrue; } if (GoalClosed(vacuum)) { print (emph) "The Schmendrick's Guide to Desert Camping", " -- you've been studying it for weeks now. Vast alien reams of information: perspiration rates, sunburn factors, how to avoid dying of thirst, how to avoid dying of heat. It sounds challenging.^"; BackgroundInfo(self, "But that's why you're going on this trip."); rtrue; } print (emph) "The Schmendrick's Guide to Desert Camping", " -- you've been studying it for weeks now. Vast alien reams of information: perspiration rates, sunburn factors, tent guying, and how to make a condensation still out of a trashbag and a tin can. You could probably write the book out longhand from memory; and none of it means a damn thing to you.^"; BackgroundInfo(self, "That's why you're going on this trip, after all."); rtrue; ], background_flag false, before [; Examine, Search, Open: if (OIU(self)) rtrue; self.description(); rtrue; ], has rescuable;