! Originally hacked together in QuickBASIC in early or mid-1998, ! and ported to PHP for the Web in early 2005, thence to Inform. ! I've made hundreds of improvements since that first version. Constant STORY "Teacher Feature"; Constant HEADLINE "^(c) Copyright 1998, 2006 Paul Equinox Collins.^"; Constant LM_I_NOTHING 1; Constant LM_I_CARRYING 2; Constant LM_MISC_BLANK 10; Constant LM_MISC_X_SELF 19; Constant LM_TOUCH_SELF 3; Constant CAT_TALK_INTERVAL = 15; ! i.e. 1/15 chance of mewing, etc. Constant MATHS_TEST_DURATION = 20; ! Oscar's Maths test lasts this many turns Constant AMUSING_PROVIDED; ! offer list of amusing things after game is won ! Task-based scoring. ! When adding a task, increase NUMBER_TASKS and MAX_SCORE, add a "1" to ! task_scores, add the new description to PrintTaskName, and add a call to ! Achieved(task_number) where the score should first be given. Constant TASKS_PROVIDED; Constant NUMBER_TASKS = 15; Constant MAX_SCORE = 15; Array task_scores -> 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1; [ PrintTaskName task_number; switch (task_number) { 0: "disguising yourself as a first-year"; 1: "renewing Katie's faith in your relationship"; 2: "feeding ~Neo-Nazi~ Redcough"; 3: "helping Oscar pass his mental arithmetic test"; 4: "defeating Johnny Pike in a fight"; 5: "finding Johnny Pike's cannabis stash"; 6: "charting the staff room maze"; 7: "opening a secret passage"; 8: "searching in vain for a broom"; ! optional 9: "infecting the computer with a virus"; 10: "fencing a stolen trophy to Mr Nixon"; 11: "helping the sixth-formers to relax"; 12: "getting onto the roof"; 13: "making a really loud noise"; 14: "digging up an alien artefact"; } ]; Include "parser"; Include "writelist"; Object LibraryMessages with before [; Ask: if (noun == player) "You won't learn anything by talking to yourself."; print (The) noun; if (noun has pluralname) print " have"; else print " has"; " little to say on that topic."; Attack: "Let's not be too drastic."; Fill: "That wouldn't help."; Inv: switch (lm_n) { LM_I_NOTHING: "You aren't carrying anything."; LM_I_CARRYING: print "You have about your person"; rtrue; ! avoid auto-newline of "..."; } Jump: if (player in Gym) ! floor "squeals when you jump on it" "The floor squeals."; "You don't feel the need to exercise right now."; Miscellany: switch (lm_n) { LM_MISC_BLANK: "Hey, don't be shy."; LM_MISC_X_SELF: "You glance down and see a slightly chubby 14-year-old in school uniform. It's you, Rick Hejlsberg, academic failure and master troublemaker."; ! ^ a nod to Anders Hejlsberg, lead architect of C# } Pray: "Oh, please. You're not in assembly now."; Sing: "There's a reason you're not in the school choir."; Sleep: "Time enough for that in tomorrow's Geography lesson."; Strong: "Careful! People have been suspended for less."; Think: "You ponder your predicament."; Touch: switch (lm_n) { LM_TOUCH_SELF: "Honestly! Wait until you get home."; } Wake: "You're wide awake already."; Wave, WaveHands: "That wouldn't help."; Yes, No: "Right."; ]; Include "verblib"; ! must follow LibraryMessages [ catTalk; print (string) random("looks at you curiously", "mews", "miaows", "purrs", "yowls", "utters a sound like ~prrrow~"); ]; [ afterGiveFakeFoodToCook; if (flies.given && polyfilla.given) ! i.e. both items now given { katie.showInDiningHall = true; } ]; [ win; ! after a successful 'get report' print "At last, the report is yours! You return to your empty form room to read it.^"; anyKey(); print "^English: ~Rick has a lively imagination. His excuses for late homework are always witty and inventive. Rick often lacks motivation in his studies, but does possess some skill with the pen. Indeed, I have frequently had to caution him against flicking ink at his classmates.~^^Well, that one could definitely be worse.^"; anyKey(); print "^French: ~Richard's vocabulary is limited and he sometimes struggles to express his thoughts. He has similar problems in French.~^^Oh, thanks a lot.^"; anyKey(); print "^Art: ~Richard is a quiet student of average ability.~^^Mr Blister writes that same phrase in every report, every year. And people call you lazy.^"; anyKey(); print "^History: ~This boy is insolent, indolent, and ignorant. His failure is a certainty, not only in this year's history examinations, but across the entire school curriculum and beyond.~^^Good old Redcough - always the optimist. Hope he enjoys his scones.^"; anyKey(); print "^Mathematics: ~Rick's ratio of chatter to work has been converging to infinity this year. As far as I can extrapolate from my colleagues' comments, Rick's mathematical skills are commensurate with his progress in other subjects.~^^~Extrapolate~? ~Commensurate~? Is that a good thing or a bad thing? On the up side, if you don't know what she's talking about, your parents probably won't either.^"; anyKey(); print "^Geography: ~Rick's geographical abilities are extremely limited, to the extent that he rarely manages to find his way to lessons. I understand that he may not anticipate a career in geography, but I hope that his chosen path will be morally sound: the head urgently wishes to see Rick in connection with a school sports trophy.~^^Whoops. Now, where did you leave that correction fluid...?^"; anyKey(); deadflag = 2; ! won ]; [ anyKey temp; @read_char 1 temp; ]; Object -> gum "wad of chewing gum" with name 'wad' 'chewing' 'gum', with found false, with given false, with takenBefore false, description "The chewing gum is of a greyish hue and has fluff stuck to it.", before [; Eat: "I think you're just supposed to chew it."; ], after [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You peel the gum away from the desk with a moist plopping sound. It's still warm! Yeuch."; } ]; Object -> blazer "green blazer" with name 'green' 'blazer', with takenBefore false, with found false, description "Ah yes, this brings back memories. All first-years have to wear these green monstrosities. It's a prestige thing.", before [; Disrobe: if (blazer has worn) { "It's too tight. You can't take it off!"; } ], after [; Take: if (~~self.takenBefore) { self.takenBefore = true; } Wear: Achieved(0); "It's far too small for you, but you struggle into the blazer. Now you look just like a first-year!"; ], has clothing; Object -> scissors "pair of scissors" with name 'pair' 'scissors', with takenBefore false, description "Despite the childish red plastic handles, these scissors are passably sharp.", after [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You give the scissors a few practice snips and drop them into your pocket."; } ]; ! don't give 'pluralname', else "some pair of scissors" Object -> papers "pile of papers" with name 'pile' 'paper' 'papers//p', with found false, description [; print "A whole stack of school reports - but only one that matters to you!^"; if (report notin location) move report to location; ], before [; Take: "You don't need all of these papers."; ]; Object -> historyEssays "hastily scribbled essays" with name 'hastily' 'scribbled' 'essay' 'essays//p' 'on' 'world' 'war' 'ii' 'wwii' 'ww2', article "some", with description "You don't want to read them. If history repeats itself, you'll get the gist at some point anyway.", before [; Take: "They're stapled firmly to the wall."; ], has scenery pluralname; Object -> textbooks "tatty textbooks" with name 'tatty' 'textbook' 'textbooks//p' 'book' 'books//p', article "some", description "The textbooks are from the ~Maths is Fun!~(tm) range, and their covers depict various smiling children (exactly one of whom is Chinese, and exactly one of whom is black) weighing and measuring items. You aren't fooled for a second.", before [; Take: "You can't. You're allergic to calculus."; ], has scenery pluralname; Object -> trowel "garden trowel" with name 'garden' 'trowel', description "It's a small triangular-bladed implement for digging and weeding."; Object -> flies "sticky pile of dead flies" with name 'sticky' 'pile' 'dead' 'flies' 'fly', with found false, with takenBefore false, with given false, description "Seven or eight members of the Diptera genus, sadly passed away. Their small, black, hairy corpses are an outrage against hygiene.", before [; Eat: "Remember the old lady who swallowed a fly? You don't want to start on that slippery slope to horse consumption."; ], after [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You surreptitiously scoop the flies into your pocket. Never know when you might need 'em!"; } ]; Object -> katie "girlfriend Katie" with name 'kate' 'katie' 'girl' 'girlfriend' 'friend', articles "Your" "your" "your", description "Katie has light brown hair and green eyes. You've been involved with her for about two months, but it feels like forever. The funny thing is, whenever you tell anybody that, they think you're being romantic.", with showInDiningHall false, ! meet her there when leaving kitchen life [; Give: if (noun == roses) { move roses to katie; move oscar to CarPark; Achieved(1); "~Oh, how sweet!~ Katie gives you a hug.^~Anything for you, babe,~ you exaggerate. ~You know that.~^~Ooh, I almost forgot,~ Katie adds, ~Oscar wanted to talk to you. He said he'd be in the car park.~"; } Answer: TalkToInsteadSub(); rtrue; Ask: switch (second) { 'flowers', 'roses': if (roses in katie) { "~You like the roses?~^~They're beautiful!~ Katie exclaims, then narrows her eyes. ~Why? Are you about to own up to something?~"; } else if (roses.found) { "You're supposed to give them to the one you love, not chat about them!"; } 'herself', 'self': print "~Hi, babe,~ you say.^"; if (roses notin katie) { print "She seems distracted. ~You know, Rick, I've been thinking about our relationship.~^Uh oh.^"; } rtrue; 'relationship', 'love', 'us': if (roses notin katie) { "~What's wrong with our relationship?~^Katie sighs. ~You're just not romantic, Rick. I wish you'd do things for me sometimes.~^You grit your teeth and wonder which Hugh Grant movie she just watched."; } "~So things are okay between us, right?~^~Of course, Rick,~ Katie smiles.^Well, you think to yourself, at least that's one problem out of the way."; 'sex': "You don't feel like that discussion today. Katie is ~just not ready~, she ~needs some space right now~, and she has at least a dozen more phrases from Swizz! magazine to batter you with."; } ], before [; Attack: "That's no way to treat your sweetheart."; Kiss: if (roses notin katie) "She doesn't seem particularly impressed. Hmph."; "You exchange pecks on the cheek."; ], has animate female; Object -> bladdeySeenFromWindow "Bladdey the caretaker" has proper, with name 'bladdey' 'caretaker' 'janitor', description [; ! similar to real 'bladdey' object if (~~bladdey.conscious) ! i.e. the real Bladdey { "The caretaker is out cold."; } "He stands at the base of the tower, peering suspiciously around."; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: if (~~bladdey.conscious) ! i.e. the real Bladdey { "The caretaker is out cold."; } "You shout down to Bladdey, but there is no response."; Give: "How do you propose to do that from a first-floor window?"; ], before [; Attack: "How do you propose to do that from a first-floor window?"; Receive: if (~~bladdey.conscious) "Dropping anything else on him would be overkill."; if (window hasnt open) "You'll have to open the window first."; else if (noun == dictionary) { <>; } "Dropping that on Bladdey wouldn't work very well."; ], has animate scenery; Object -> mrBlister "Mr Blister the Art teacher" has proper, with name 'mr' 'blister' 'teacher', with awake false, description [; print "Mr Blister is a rather fat, grumpy teacher with a ludicrous black beard. He is in charge of the Art department and responsible for the computer room, but avoids teaching if he can help it."; if (caesium.justUsed) { print " He looks rather startled, having been woken by the pool explosion."; caesium.justUsed = false; ! don't show again } else if (~~self.awake) print " Right now, he is avoiding teaching by being sound asleep."; print "^"; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: if (~~self.awake) "He's asleep."; if (WordInProperty(second, disk, name)) ! any word for the disk { ! (Mr Blister is never around before you've seen the disk.) if (disk notin drive) "~Do you know anything about computer viruses?~ you ask.^~I'll know who to blame next time I see one,~ snarls Mr Blister."; else "~The PC in the computer room has a virus!~ you announce.^Mr Blister frowns, evidently thinking of all those stairs to climb. ~Oh, you probably just saw it doing something you don't understand. After all, you don't have any evidence of a virus, do you?~"; } switch (second) { 'art', 'paint', 'painting', 'sculpture', 'sculptures': "~Nice artwork in here,~ you comment.^Mr Blister snorts."; 'computer', 'computers', 'computing', 'PC', 'BBC', 'BBCs': "~Can I use the computer room?~ you ask.^~It's open,~ Mr Blister replies, ~but you'd better behave up there.~"; 'himself', 'self', 'teaching': "~How are things?~ you ask brightly.^Mr Blister makes a sarcastic little noise."; 'pages': if (pages in player) "~Look what the PC printed out!~ you cry in mock alarm.^~What's that?~ demands Mr Blister. ~Let me see that! Hand it over!~"; } Give: if (~~self.awake) "He's asleep."; if (noun == disk) "You don't want Mr Blister to confiscate that."; else if (noun == pages) { move pages to mrBlister; move mrBlister to computerRoom; move firstYear to languages; pages.given = true; "You show Mr Blister the pages of garbage.^~Another virus,~ he sighs, lumbering off to the computer room. ~Well, I suppose I'd better go and take a look.~^Just then, you hear someone crying. Looking outside, you see a familiar first-year pupil running into the languages block."; } ], before [; WakeOther: if (~~self.awake) "He shifts in his chair, grunts, and goes back to sleep."; ], has animate; Object -> redcough "~Neo-Nazi~ Redcough the History teacher" has proper, with name 'neo' 'nazi' 'neonazi' 'neo-nazi' 'mr' 'redcough' 'teacher', with askedForDinner false, description "Never look directly at ~Neo-Nazi~ unless you fancy a detention for rudeness. Oscar swears blind that Redcough once foamed at the mouth when he received homework two days late.", time_left, time_out [; if (self in location) "^~Are you still here, boy?~"; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: "You wouldn't dare."; Give: if (noun == dinner && ~~dinner.cooked) { StartTimer(self, 1); self.askedForDinner = true; ! so he won't ask as you leave, in case you gave it to him first "~How dare you!~ booms the fascist. ~I said I wanted my dinner to be hot! Didn't I say that?~^~Yes sir.~^~This is stone cold!~^~Yes sir.~^~Well? Don't just stand there, you fool; take my dinner and bring it back hot!~"; } else if (noun == dinner) ! must have been cooked { remove dinner; Achieved(2); SwimmingPool.occupied = false; self.askedForDinner = true; ! so he won't ask as you leave, in case you gave it to him first StartTimer(self, 1); "Redcough frowns down at the mixture of mash, peas, and sausage.^~Well, at least it's hot!~^~Yes sir.~^~What, are you still here? You look like you need some exercise, boy. Go down to the swimming pool and try fifty laps. I'll be checking up on you!~"; } else if (noun == mask) ! from Redcough's wall display { move mask to location; "Redcough glowers at you. ~What are you doing with that, boy?~ He replaces it on the wall display."; } else ! not the dinner or gas mask { "~I don't want that!~ Redcough exclaims."; } ], has animate; Object -> oscar "friend Oscar", with name 'oscar', articles "Your" "your" "your", with mentionedTest false, with mathsTestTurnsLeft MATHS_TEST_DURATION, description "Oscar, your sometime partner in crime, shares your academic incompetence and love of mischief. His spiked blond hair projects in all directions.", time_left, time_out [; if (--self.mathsTestTurnsLeft == 0) { ! StopTimer(self); ! not necessary remove self; if (player in MuddyPath or Garden or Field or CrashSite or Mound or Playground or CarPark) "^You see a crowd of pupils swarming out of the Maths block. Oscar's test must have finished."; } else StartTimer(self, 1); ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: ! pretty much regardless of topic if (~~self.mentionedTest) { self.mentionedTest = true; "~You took your time!~ complains Oscar. ~Listen: I need your help. I've got a mental arithmetic test in, like, ten minutes, and you know I can't do maths to save my life.~"; } else if (WordInProperty(second, phone, name)) ! any word for the phone { if (phone in player) "You show Oscar the mobile phone. ~Looks like it has a calculator mode.~^~Hey, if I could sneak that in... can I borrow it?~"; "You don't have it."; } else "Oscar is only interested in finding a way to survive his upcoming mental arithmetic test."; Give: if (noun ~= phone) { "~How's that going to help me in a maths test?~"; } else { move phone to oscar; move oscar to Maths; StartTimer(oscar, 1); ! the Maths test ends later so you can get back in there move disk to player; Achieved(3); print "You hand the mobile phone to Oscar. ~There you go. Just pray it doesn't ring while you're adding up on it.~^~Ah, this should help me, uh, check my answers,~ he grins. ~By the way, my brother gave me this. I thought you might have some fun with it.~^He flips a computer disk in your direction and walks off towards the Maths block, whistling."; move mrBlister to Art; "^^Just then, Mr Blister walks past from the car park.^~What was that huddle all about? Not a drug deal, I hope!~^You quickly pocket the disk, hoping that Mr Blister hasn't spotted it - after all, he's in charge of the computer room - but he just emits a cavernous yawn and bumbles onward to the Art block."; } ], has animate; Object -> ball "tennis ball" with name 'tennis' 'ball', with found false, with takenBefore false, description [; if (self hasnt container) "It's a soggy tennis ball."; else if (cannabis notin self) "The soggy tennis ball has been slit open. The empty space cries out to be filled."; else "What a neat hiding place! You found this ball in the grass, but nobody would think to find grass in the ball."; ], before [; Cut: if (ball has open) "The ball has already been slit open."; else if (second == knife) { give ball container; give ball open; "You slit the ball open, revealing its grey rubber insides."; } else if (second == scissors) { "The scissors make no impact on the tough tennis ball."; } "You can't cut the ball with that."; LetGo: ! i.e. 'remove weed', but also indirectly if you 'give weed' and not 'give ball' "You're best off keeping it hidden inside the ball."; Receive: if (noun ~= cannabis) "You don't need to hide that."; ], after [; Receive: "You stuff the sachet of cannabis inside the tennis ball."; Take: if (~~self.takenBefore) { self.takenBefore = true; "You retrieve the soggy tennis ball."; } ], invent [; ! avoid "(which is empty)" when it's on the ground if (inventory_stage == 2) rtrue; ]; Object -> rope "severed length of rope" with name 'severed' 'length' 'rope', with takenBefore false, description "A piece of strong rope, just the thing for... well, whatever strong rope is for.", before [; Pull: if (ring.ropeTied && ~~map.found) { map.found = true; move map to location; "You tug on the rope. The brick drops to the ground, revealing a creased old map tucked into the crevice."; } else if (ring.ropeTied) { "There's no point in pulling a loose brick around!"; } else "The rope isn't attached to anything!"; Take: if (ring.ropeTied) "It's tied to the iron ring."; Tie: ! a tribute to Blizzard Pass! if (rope in player && second == ring) { move self to location; ring.ropeTied = true; "You deftly knot the rope around the ring."; } else if (rope notin player) { "You aren't carrying the rope."; ! but in same room } ], after [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You wind the rope around your hand and take it with you."; } ]; Object -> locker "locker number 102" has proper, with name 'locker' 'number' '102', description [; print "This is the lost first-year's locker."; if (lockerKey in player) print " And you have the key!"; print "^"; ], with_key lockerKey, has static openable container lockable locked; Object -> johnny "Johnny Pike" has proper, with name 'johnny' 'pike', description "Johnny, the school bully, looks very much at home in his usual haunt, the toilets. His trendy Puffa jacket and Air Head trainers do little to counter the ugly scowl on his face.", before [; Attack: if (whisky.drunk) { remove self; secretary.showInMiddleOfSchool = true; Achieved(4); "Emboldened by the head's whisky, you accept Johnny's offer of a fight. A few awkward blows are exchanged; then Johnny mutters a rude word and stumbles out of the toilets with a hand over his nose."; } "You'd like to take him at his word - but, remembering that Johnny is a veteran of many playground scraps, you decide that this would be unwise."; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: "~Some *@@64!# took my hash,~ Johnny spits. ~You wanna *@@64!#ing fight?~"; ], has animate; Object -> secretary "head's secretary", with name "head^s" 'secretary', article "the", with showInMiddleOfSchool false, ! meet her there after fighting Johnny description [; print "The secretary is one of those people who are practically allergic to their own allergies. She is trying to sort a pile of papers, but keeps stopping to sneeze or rub her eyes.^"; if (~~papers.found) { papers.found = true; move papers to location; } ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: "~Not now - atishoo! - I'm busy with these reports.~"; Give: if (noun == cat) { remove cat; remove secretary; if (~~papers.found) ! in case you never examined her { papers.found = true; move papers to location; } "You place the fidgeting animal on the secretary's desk. ~I found this and thought someone might have lost it.~ The secretary replies with a remarkable volley of sneezes and abandons her papers in search of more tissues. The cat, too, darts out of the room."; } ], has animate female; Object -> passage "secret passage" with name 'secret' 'passage', description [; if (self in English) "Left of the blackboard, the narrow passage leads north into darkness."; else "The narrow passage leads back to the English classroom."; ], with opened false, door_to Alcove, door_dir n_to, found_in [; return (self.opened && (location == English)); ], has static open door; Object -> ring "iron ring" with name 'iron' 'ring', with found false, with ropeTied false, description [; print "The iron ring is slippery and stained orange with rust."; if (self.ropeTied) print " A piece of rope is tied to it."; print "^"; ], before [; Pull: if (~~map.found) "The brick seems loose, but you can't get a good grip on the slippery iron ring."; "There's no point in pulling a loose brick around!"; ], has scenery; Object -> pages "stack of printed pages" with name 'stack' 'printed' 'pages' 'printout' 'paper', with given false, with takenBefore false, description "Each sheet in this stack of paper is filled with the crazed outpourings of a mentally traumatised computer.", after [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You gather up the wasted sheets of paper."; } ]; Object -> lining "jacket lining" with name 'jacket' 'lining', description [; if (~~cannabis.found) { cannabis.found = true; move cannabis to location; Achieved(5); "Oh-ho, what have we here? A sachet of cannabis!"; } "Nothing else here."; ], has scenery; Object -> report "your school report" has proper, with name 'school' 'report', description "Like a fatal bullet, the report has your name on it; and if your parents get hold of it before you do, it might be equally dangerous.", before [; Take: if (secretary in location) "~If you think you can just waltz in here for your report, you're mistaken,~ says the secretary. ~You can pick it up tomorrow when it's signed and sealed.~"; win(); rtrue; ! suppress "Taken" message ]; Object -> mask "old gas mask" with name 'old' 'gas' 'mask' 'gasmask', with found false, with takenBefore false, with turnsWorn 0, description "This gas mask is a genuine wartime relic. It seems to be in working order.", time_left, time_out [; if (location == Toilets) ! repeat until we leave toilets { StartTimer(mask, 1); } else if (self has worn) ! anywhere else { give self ~worn; "^Realising how silly you look, you take the gas mask off again."; } ], before [; Disrobe: if (mask has worn && location == Toilets) "In here? You must be joking."; else self.turnsWorn = 0; ], after [; Take: if (~~self.takenBefore) { self.takenBefore = true; } Wear: StartTimer(self, 1); "You don the gas mask."; ], has clothing; Object -> clip "paper clip" with name 'paper' 'clip' 'paperclip' 'twist' 'wire', with found false, description "The paper clip has unwound slightly. It's more like a twist of wire."; Object -> dinner with name 'school' 'dinner', short_name [; if (self.cooked) print "over"; else print "under"; print "cooked school dinner"; rtrue; ], with cooked false, with takenBefore false, description [; if (~~self.cooked) "The cook's own ~bangers and mash~, garnished with a few stray hairs. It looks rather cold and chewy."; else "The cook's own ~bangers and mash~, now somewhat overcooked. The mashed potato is crispy and the topmost sausage looks positively post-nuclear."; ], parse_name [ w rv; w = NextWord(); if ((w == 'school') || (w == 'overcooked' && self.cooked) || (w == 'undercooked' && ~~self.cooked)) { w = NextWord(); ++rv; } if (w == 'dinner') ++rv; return rv; ], before [; Eat: "You decide against this dangerous act of masochism."; ]; Object -> roses "bunch of roses" with name 'rose' 'roses//p' 'bunch' 'of' 'flower' 'flowers//p' 'bouquet', description "You have a furious gardener to thank for this attractive bouquet.", with found false, before [; Eat: "You aren't hungry. You aren't a swarm of aphids, either."; ]; Object -> herring with name 'herring' 'fish', short_name [; if (self.cooked) print "black"; else print "red"; print " herring"; rtrue; ], with cooked false, with takenBefore false, description [; if (~~self.cooked) "It can't be of any use... can it?"; else "Aha! Now we're talking."; ], parse_name [ w rv; w = NextWord(); if ((w == 'black' && self.cooked) || (w == 'red' && ~~self.cooked)) { w = NextWord(); ++rv; } if (w == 'herring' or 'fish') ++rv; return rv; ], before [; Eat: "You'd rather not. Something about it looks fishy."; ], after [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You take the slippery little fish."; } ]; Object -> caretakersKey "caretaker's key" with article "the", parse_name [ w rv; w = NextWord(); while (w == 'caretaker' or 'bladdey' or 'caretaker^s' or 'bladdey^s') { w = NextWord(); ++rv; } if (w ~= 'key') { if (bladdey in player or location) { rv = 0; ! assume they meant Bladdey himself } } else rv++; return rv; ], with found false, description "The caretaker's brass key unlocks Bladdey's cupboard in the tower."; Object -> lockerKey "locker key" with name 'locker' 'key', with given false, description [; if (locker notin Tower0) move locker to Tower0; "The small, shiny key dropped by the first-year bears the number 102."; ]; Object -> map "creased old map" with name 'creased' 'old' 'map', with found false, with usedInMaze false, description [; if (location == StaffRoom) { print "Staring at the map, you gradually work out your position in the labyrinth. You follow the marked path and find yourself in...^"; self.usedInMaze = true; PlayerTo(HeadsOffice); Achieved(6); rtrue; } print "This old map shows a twisting path through"; if (self.usedInMaze) " the staff room maze."; " a labyrinth of some kind."; ]; Object -> book "inconspicuous book" with name 'inconspicuous' 'book' 'one' 'unremarkable', ! from initial description with found false, description "Nothing noticeable about this one. It certainly doesn't look like the sort of book that would open a secret passage when pulled, or anything like that.", before [; Pull: passage.opened = ~~passage.opened; if (passage.opened) { Achieved(7); "You hear a grating noise somewhere above you."; } else "You hear another grating noise and a clunk."; Take: "How strange. It seems to be attached to the shelf."; ]; Object -> money "dinner money" has proper with name 'dinner' 'money' 'cash' 'coin' 'coins//p', with takenBefore false, description "The exact money for a school dinner. Don't worry: no first-years were harmed during the creation of this game. (Well, just the one - but let's not talk about my hobbies.)", after [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You gather up the handful of coins."; } ]; Object -> towel with name 'towel', short_name [; if (self in MuddyPath) print "soggy"; else print "clean white"; print " towel"; rtrue; ], with takenBefore false, description [; if (self in MuddyPath) "The towel is no longer clean or white, but it's doing a good job of covering the worst of the mud."; else "Solicitously washed and ironed by somebody's mother, the towel is spotlessly clean and eye-achingly white."; ], parse_name [ w rv; w = NextWord(); if ((w == 'clean' or 'white' && self notin MuddyPath) || (w == 'soggy' && self in MuddyPath)) { w = NextWord(); ++rv; } if (w == 'towel') ++rv; return rv; ], before [; Take: if (location == MuddyPath) "You don't want the soggy towel."; ], after [; Drop: if (location == MuddyPath) { "You spread the towel over the muddy patch."; } Take: if (~~self.takenBefore) { self.takenBefore = true; "You roll up the towel and tuck it under your arm."; } ]; Object -> whisky "bottle of whisky" with name 'bottle' 'whisky' 'whiskey', with drunk false, with takenBefore false, description "A bottle of the finest Butchered Grouse malt whisky.", before [; Eat: if (self.drunk) "Any more of it would make you sick."; else { self.drunk = true; "You take a swig of the head's whisky. Suddenly you feel strong and fearless."; } ], After [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You stow the bottle away in your jacket."; } ]; Object -> disk "virus disk" with name 'virus' 'disk' 'disc' 'floppy', article "the", description "It looks like any other floppy disk - but, knowing Oscar's brother, this one is primed to wreak digital havoc on some unfortunate terminal.", before [; Read: "There's no label on the disk."; ]; Object -> cannabis "sachet of cannabis" with name 'sachet' 'packet' 'cannabis' 'marijuana' 'hash' 'hashish' 'weed' 'pot' 'ganja' 'grass', with found false, with takenBefore false, description "Hash. Weed. Ganja. A small plastic packet of whatever you choose to call it.", before [; Eat: "That would make you ill. Especially the sachet."; Open: "You're not going to smoke it, so there's no point in opening the sachet."; ], after [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You furtively slip the packet into your pocket. Hey, that sort of rhymes."; } ]; Object -> translator "universal translator" with name 'universal' 'translator', article "a" ! not "an" with found false, with firstUsed false, description "This rather nifty gadget is covered in blinking lights and emits a soft rippling sound. Proof of extra-terrestrials - or just another Japanese toy?", before [; SwitchOn, SwitchOff: "It doesn't have any buttons."; ], after [; Take: "The translator burrs as you pick it up."; ]; Object FormRoom "Form room" has light with description "Sunlight filters into your form room, where you are obliged to register each morning and afternoon, and falls across the tables as though reluctant to get itself dusty on the linoleum floor. The school's budgetary concerns are manifested in the hard wooden chairs and scratched, worn desks which surround you. A doorway leads east.", e_to Tower2; Object -> formRoomFloor "linoleum floor" with name 'linoleum' 'floor' 'lino', description [; "The floor is scuffed and dusty. Bladdey the caretaker has been neglecting it again."; ], has scenery; Object -> formRoomDesks "desks" with name 'scratched' 'worn' 'desk' 'desks//p' 'table' 'tables//p', article "some", description [; print "These desks have been in the wars - and by the looks of things, they lost. Each desk bears numerous obscene carvings which testify to hours of boredom."; if (~~gum.found) { gum.found = true; move gum to location; print " One of them has chewing gum stuck underneath."; } print "^"; ], has scenery pluralname; Object -> carvings "obscene carvings" with name 'obscene' 'carving' 'carvings//p', article "some", description "Dirty words, dirty poems, and initialled love-hearts which, if not exactly dirty, at least have an air of sloppy hygiene.", has scenery pluralname; Object -> chairs "chairs" with name 'hard' 'wooden' 'chair' 'chairs//p', article "some", description "They look about as old as it's possible to be without actually becoming valuable.", before [; Enter: "No time to sit around. You need to find that report!"; ], has scenery pluralname; Object -> jacket "Johnny Pike's jacket" has proper with name 'johnny' 'pike' "johnny^s" "pike^s" 'jacket' 'coat' 'puffa', description [; move lining to location; "A ridiculous Puffa jacket that makes its wearer look like the Michelin Man's evil twin. It's black on the outside, with a garish orange lining."; ], before [; Take: "Being seen with Johnny Pike's jacket would earn you a severe kicking."; ]; Object StaffRoom "Staff room maze" has light with description "You are lost in the nightmarish staff room maze, with indistinguishable exits in all directions. Wherever you look, your eyes are accosted by half-finished crosswords and mugs of tepid coffee. Pale, haggard teachers pass you in all directions, clutching worn briefcases and faded notes for lessons that never happened.", with timesMovedInMaze 0, n_to [; return getMazeTarget(); ], e_to [; return getMazeTarget(true); ], s_to [; return getMazeTarget(); ], w_to [; return getMazeTarget(); ], u_to [; return getMazeTarget(); ], d_to [; return getMazeTarget(); ]; [ getMazeTarget isEast; if (++StaffRoom.timesMovedInMaze == 7) { print "You turn a corner and find yourself back in reception.^"; return Reception; } else if (StaffRoom.timesMovedInMaze == 1 && isEast) ! tried to leave immediately print "Huh? Where did that door go?^"; else if (StaffRoom.timesMovedInMaze == 3) print "Christ. This place is terrifying.^"; else if (StaffRoom.timesMovedInMaze == 6) print "You feel as though you've somehow walked in a circle.^"; return StaffRoom; ]; Object -> mazeTeachers "teachers" with name 'pale' 'haggard' 'teacher' 'teachers//p', article "some", description [; "They look like zombies. You wonder how long they've been lost here."; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: "~Excuse me,~ you begin.^The teachers stumble past, staring, unheeding."; ], has animate scenery pluralname; Object -> mugs "mugs of coffee" with name 'mug' 'mugs//p' 'cup' 'cups//p' 'of' 'tepid' 'coffee', article "some", description "Most of the chipped enamel mugs are stone-cold; and they are too gloomily similar to serve as landmarks in the maze.", before [; Receive: if (noun == caesium) "There are safer ways to make a frothy cappuccino."; else if (noun == phone) "This phone doesn't have Java support."; "Soaking that in coffee wouldn't help you."; Take: "You'd feel bad. There might still be some wizened old professor wandering the maze in search of the lukewarm pick-me-up he mislaid in his youth."; ], has scenery pluralname; Object -> crosswords "crosswords" with name 'half' 'finished' 'crossword' 'crosswords//p' 'puzzle' 'puzzles//p', article "some", description "You've never understood these ~cryptic~ crosswords. Judging by the ratio of question marks and other ballpoint scribbles to actual completed clues, neither have the teachers at St Borogrund's.", before [; Take: "You don't have the heart to take away the one last diversion available to these poor souls."; ], has scenery pluralname; Object HeadsOffice "Headmaster's office" has light with description "You stand in the headmaster's office, deep within the fiendish labyrinth. The room is an opulent shrine to all that is plush and expensive. A number of wall-mounted portraits offset a bookcase and a cabinet. The maze is north.", n_to Reception; Object -> headsPictures "wall-mounted portraits" with name 'wall' 'mounted' 'picture' 'pictures//p' 'portrait' 'portraits//p', article "some", description "Austere depictions of former headmasters and staff members.", before [; Pull, Push, Take: "You carefully tilt the portraits, but there's nothing behind them. The headmaster must have a better financial strategy than the old ~safe behind the picture~ - a bank account in some offshore tax haven, perhaps, judging by the furniture in here."; ], has scenery pluralname; Object -> bookcase "bookcase" with name 'case' 'bookcase', description "The glass-fronted bookcase holds many books.", has scenery openable; Object -> headsBooks "books" with name 'book' 'books//p', article "some", description "Education, public speaking, child psychology... Your eyes slide off the spines like butter from a non-stick pan.", before [; Read, Take: "The books don't interest you at all."; ], has scenery pluralname; Object -> cabinet "cabinet" with name 'handsome' 'oak' 'cabinet', description "Compared with the bog-standard furniture in your form room, this handsome oak cabinet is a museum piece.", has scenery openable container; Object Art "Art block" has light with description "Your unartistic presence defiles the Art block. Splashes of paint in various primary colours are liberally distributed over the wooden desks and wall displays. The room also boasts some clay sculptures which exhibit no particular form or talent - hence termed ~abstracts~. The playground is east.", e_to Mound; Object -> paint "splashes of paint" with name 'splash' 'splashes//p' 'paint', article "some", description "You see patches of red, yellow, and blue, or what Mr Blister would insist on calling vermilion, ochre, and ultramarine.", has scenery pluralname; Object -> sculptures "clay sculptures" with name 'clay' 'sculpture' 'sculptures//p' 'abstract' 'abstracts//p', article "some", description "Not very inspired. Take this one, for example. Is it an owl? A dog? A sarcophagus, perhaps? The only thing it definitely isn't is art.", has scenery pluralname; Object -> artDesks "wooden desks" with name 'wooden' 'desk' 'desks//p' 'table' 'tables//p', article "some", description "The phallic carvings on some of the desks are actually very good. Mind you, anything looks good when it's in the same room as the second-years' sculptures.", has scenery pluralname; Object -> artWallDisplays "wall displays" with name 'wall' 'display' 'displays//p', article "some", description "You can only hope that the walls were graced with these efforts so that the more competent artists could take their work home. Even ~efforts~ is something of an overstatement.", has scenery pluralname; Object -> marker "red marker pen" with name 'red' 'marker' 'pen', description "Very red, and very permanent. Only a lid stands between it and crimson chaos.", has transparent; Object -> -> lid "lid" with name 'lid', description "The lid of the marker pen is a chunky red cylinder.", before [; Remove, Take: if (location == FirstYears && window hasnt open) { give window open; "You remove the lid of the marker pen. Poisonous marker pen fumes rapidly fill the air. A quick-thinking first-year opens the window. You replace the lid."; } else if (location == FirstYears) { "You remove the lid of the marker pen. The open window quickly dispels the toxic marker pen fumes. You replace the lid."; } print "You remove the lid of the marker pen - and hastily replace it as the air fills with poisonous fumes."; if (mask has worn) print " Even the gas mask can't stop your eyes from watering!"; print "^"; rtrue; ], has static; Object Cupboard "Caretaker's cupboard" has light with description [; if (self hasnt visited) { print "You creep cautiously into Bladdey's supply cupboard, half-expecting to brush against a skeleton but stumbling into the light switch instead."; } else print "This is Bladdey's supply cupboard."; " In the dim electric glow, you perceive an array of brushes, chemicals, and other cleaning equipment. The exit is west."; ], w_to Tower1; Object -> cleaningEquipment "cleaning equipment" with name 'cleaning' 'equipment' 'brush' 'brushes//p' 'chemical' 'chemicals//p', article "some", with broomHandleSuggested false, description [; if (self.broomHandleSuggested && skylight hasnt open) { Achieved(8); "Remembering the skylight in the Maths block, you look around for a broom, but find nothing suitable. Nice try, though!"; } "There's nothing of interest here."; ], before [; Take: "The cleaning equipment is of no use to you."; ], has scenery; Object -> polish "tin of polish" with name 'tin' 'polish', description "~Silver polish~? It looks pale pink to you."; Object -> polyfilla "tub of Polyfilla" with name 'tub' 'polyfilla' 'putty', with takenBefore false, with given false, description "The king of proprietary putties: sticky, greyish, and oh so versatile.", before [; Eat: "You'll decide you'll leave that kind of filling to a qualified dentist."; Receive: "You can't. The tub is full."; ], after [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You take the tub of Polyfilla. A ghostly voice booms, ~Polyfilla is a registered trade mark of Polycell Products!~"; } ], has openable; Object ComputerRoom "Computer room" has light with description "You find yourself in the snake-pit of trailing cables that is the computer room. Most of the space is occupied by a collection of somewhat battered BBC Micros, but the pride of the IT department is an early IBM PC. Since the IT department consists of a single part-time Art teacher, its efforts are to be praised. You can go north.", n_to Tower3; Object -> pc "IBM PC" with name 'ibm' 'pc' 'computer', description [; if (disk in drive) "It doesn't look very well."; else "It has a floppy disk drive and a dot-matrix printer. Not quite state of the art? Well, you should see the state of the Art block."; ], before [; SwitchOff: "Nobody - but nobody - is allowed to turn off the PC. This wouldn't normally stop you, but Mr Blister has actually removed the power button: a bold gambit, since the school's wiring is a dangerous mess and localised power cuts are not uncommon."; SwitchOn: "It's already on."; ], has scenery; Object -> cables "cables" with name 'cable' 'cables//p' 'wire' 'wires//p' 'lead' 'leads//p', article "some", description "The cables weave around the room attractively.", has scenery pluralname; Object -> bbcs "BBC Micros" with name 'bbc' 'bbcs//p' 'micro' 'micros//p' 'beeb' 'beebs//p' 'computer' 'computers//p', article "some", description "The 1980s are alive and well at St Borogrund's. The BBC computers are venerable beige boxes with red function keys. These ones look a bit battered, but their sturdy construction has withstood the ravages of time, boredom, and potato crisp fragments.", before [; SwitchOff: "You turn off one of the BBC Micros. Its screen display dwindles to a tiny dot and vanishes."; SwitchOn: "~Burp - BLEEP.~"; ], has scenery pluralname; Object -> drive "floppy disk drive" with name 'drive' 'diskdrive' 'discdrive', ! and see below parse_name [ w rv; w = NextWord(); while (w == 'disk' or 'disc' or 'floppy') { w = NextWord(); ++rv; } if (w ~= 'drive' or 'diskdrive' or 'discdrive') { if (disk in player or location) { rv = 0; ! assume they meant the disk } } else rv++; return rv; ], description [; print "This is a 3 1/2~ floppy disk drive"; if (disk in self) " with a disk in it."; else ". It's empty."; ], before [; LetGo: if (noun == disk && disk in self) { "You'd better leave it. You wouldn't want to be caught with the incriminating evidence."; } Receive: if (noun ~= disk) "That doesn't belong in a disk drive."; else { move disk to drive; move pages to location; Achieved(9); "You place the disk in the drive and restart the computer. The usual delay is followed by an interesting selection of beeps and error messages. The printer soon joins the fun and churns out page after page of meaningless garbage."; } Take: "You can't. It's part of the PC."; ], has scenery container open; Object -> printer "dot-matrix printer" with name 'dot-matrix' 'dot' 'matrix' 'printer' 'screecher', description "This ageing dot-matrix printer is known to staff and pupils as the Screecher. (The headmaster has vetoed all attempts at obtaining a modern laser printer, on the grounds that laser pointers are banned in school and it ~would send out a conflicting message~.) A green light indicates that it is ready to print.", before [; SwitchOff: "You can't find a power switch, and you can't reach the plug. Anyway, the printer is supposed to stay on."; SwitchOn: "The printer is already on."; ], has scenery; Object Tower0 "Tower - ground floor" has light with description "You are at the bottom of the leaning, decrepit structure known as the tower. To one side you see rows of dusty lockers, their numbers obscured by the fungal growth of many years. Stairs lead up, and a door to the east leads out of the tower.", u_to Tower1, e_to Middle; Object -> lockers "lockers" with name 'rows' 'dusty' 'door' 'doors' 'locker' 'lockers', article "some", with description "The lockers have plastic doors in a faded orange hue that shows signs of once having been bright red. Judging by the accumulated dust and grime, most of them haven't been used for years.", before [; Close, Open: "You try a random locker, but it won't open."; ], has scenery openable container lockable locked pluralname; Object Tower1 "Tower - first floor" has light with description "This is the first floor of the tower. Litter-strewn stairs lead up and down. Westwards is the English classroom, whereas to the east is a cupboard owned by Bladdey, the caretaker, rumoured to contain all manner of gruesome secrets. To the north is a classroom filled with first-years.", u_to Tower2, d_to Tower0, w_to English, n_to [; if (blazer has worn) return FirstYears; "You can't just walk into a first-year lesson!"; ], e_to [; if (cupboardDoor has locked && ~~cupboardDoor.everBeenUnlocked) { print "The cupboard is locked. Your suspicions increase tenfold."; if (~~cupboardDoor.seenLocked) { cupboardDoor.seenLocked = true; } else print "^[** Programming error: too many suspicions **]"; print "^"; rtrue; } else return cupboardDoor; ]; Object -> litter "litter" with name 'litter' 'rubbish' 'refuse' 'garbage' 'trash' 'apple' 'core' 'cores//p' 'sweet' 'wrapper' 'wrappers//p' 'empty' 'crisp' 'packet' 'packets//p', article "some", description "Apple cores, empty crisp packets, and sweet wrappers.", before [; Take: "Picking up litter is supposed to be the caretaker's job."; ], has scenery; Object -> cupboardDoor "cupboard door" with name 'cupboard' 'door', with description "The cupboard door is tall and dark but not especially handsome, making it only partially suitable for a banal horoscope.", with seenLocked false, with everBeenUnlocked false, door_to Cupboard, door_dir e_to, with_key caretakersKey, before [; Unlock: if (second == clip) ! wrong door! "You insert the paper clip into the keyhole and jiggle it around. The door refuses to budge."; ], after [; Unlock: self.everBeenUnlocked = true; ], has static scenery door openable lockable locked; Object Tower2 "Tower - second floor" has light with description "This, the second floor of the tower, reputedly harbours that curious branch of academia known as ~humanities~. In practice, however, this consists only of the History room, to the east, and your form room, to the west. Stairs lead up and down, as they generally do.", w_to FormRoom, u_to Tower3, d_to Tower1, e_to [; if (~~SwimmingPool.occupied) { "Redcough seems to have locked his door. You don't suppose he's the kind to have guests for dinner. Unless he's a cannibal."; } return History; ]; Object Tower3 "Tower - top floor" has light with description "You now stand at the top of the tower. Thankfully, stairs lead down, but you also have the option of visiting the isolated Geography department, somewhere to the west, or the computer room, to the south.", d_to Tower2, w_to Geography, s_to [; if (mrBlister in ComputerRoom) { "You try the door, but it's locked. Mr Blister must be trying to fix the infected computer."; } return ComputerRoom; ]; Object -> firstYear "lost first-year" with name 'lost' 'first-year' 'first' 'year' 'firstyear', description [; print "Smartly attired in green blazer and polished shoes, the first-year looks lost and"; if (self in Tower3) " scared."; " even more scared than previously."; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: if (location == Tower3) { print "He stares studiously ahead and tries to pretend you're talking to someone else."; if (knife in player) print " You can't help wondering whether the knife would get something more out of him."; print "^"; rtrue; } else ! not in the tower any more { if (~~lockerKey.given) "~It's you again!~ he snivels. ~You took my locker key!~"; else if (~~gum.given) "~So why are you crying?~ you ask. He shakes his head. ~I don't trust you. You took my dinner money. I couldn't even afford any sweets.~"; else if (johnny notin Toilets) { remove jacket; move johnny to Toilets; "~So what happened?~^~I - I went to the toilet, and there was a horrible bully there! I hate this school.~^At least he's starting to fit in."; } else "He chews silently and looks at you with bovine eyes."; } Attack: if (knife notin player && location == Tower3) "You don't have a suitable weapon!"; else if (location == Tower3) { remove self; move money to location; move lockerKey to location; "You've always wanted to try this. ~Give us your dinner money!~ you advise. The first-year drops some money and a key on the floor and runs off crying."; } else "The poor kid's been through enough already."; Give: if (noun == blazer) "He already has one of those."; else if (noun == knife) "There's no point in handing it to him, but you might be able to give him a good scare with it."; else if (noun == lockerKey) { lockerKey.given = true; remove lockerKey; "You return the locker key to its owner. The sense of moral rectitude is almost overwhelming."; } else if (noun == gum && lockerKey.given) { gum.given = true; remove gum; "You squash the chewing gum into the first-year pupil's palm. Surprisingly enough, he accepts your goodwill gesture and cheers up slightly."; } ], has animate; Object Playground "Playground" has light with description [; print "You are squelching across the freshly tarmacked playground: the only part of the school to receive a facelift in recent years and, you note wryly, the only part that didn't really need one. Parts of the old surface are still visible where the playground borders the field to the north. You can also go west to the Mound, east to the car park, or south into the main school building."; if (bladdey.justRemoved) { bladdey.justRemoved = false; print "^^No sign of Bladdey. He seems to have recovered - or perhaps they hired a new caretaker to move him out of the way."; } print "^"; ], w_to Mound, e_to CarPark, s_to Middle, n_to [; if (bladdey in location && bladdey.conscious) { "Bladdey raises a warning finger. ~Yer can't go on the field, 'cause it's muddy.~"; } return Field; ]; Object -> surface "playground surface" with name 'surface' 'playground' 'tarmac' 'floor' 'ground', article "the", description [; print "Grey, cracked, and uneven."; if (~~clip.found) { move clip to location; clip.found = true; print " You notice a paper clip lying here."; } print "^"; ], has scenery; Object -> bladdey "Bladdey the caretaker" has proper, with name 'bladdey' 'caretaker' 'janitor', with conscious true, with justRemoved false, description [; ! compare 'bladdeySeenFromWindow' object if (~~self.conscious) { print "The caretaker is out cold."; if (~~caretakersKey.found) { move caretakersKey to location; caretakersKey.found = true; print " A key has fallen out of his pocket."; } print "^"; rtrue; } "He stands at the base of the tower, peering suspiciously around."; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: print "Bladdey does not respond. His selective deafness is legendary"; if (~~self.conscious) print " - oh, and he's unconscious"; "."; ], before [; Attack: if (~~self.conscious) "How mean!"; "He grunts and shoves you away."; ], has animate; Object ChangingRoom "Changing room" has light with description "The changing room is sparsely furnished with narrow benches. Clothes and bags hang above them. A single long window at ceiling height brightens the silent gloom a little. Doors lead west to the gym, east to the swimming pool, and north back outside to the car park.", n_to CarPark, w_to Gym, e_to [; if (SwimmingPool.occupied) "The swimming pool is in use. You'll have to come back later."; return SwimmingPool; ]; Object -> changingWindow "long window" with name 'long' 'window', description [; "The window runs along the west wall just below the ceiling, admitting a moderate amount of daylight without compromising the privacy of the changing room."; ], before [; Close, Open: "You can't reach the window."; ], has scenery; Object -> benches "narrow benches" with name 'narrow' 'bench' 'benches//p', article "some", with description "Meanly designed to fit in as many rows as possible, the narrow benches provide just enough support for half a buttock.", before [; Enter: "The hanging clothes and bags make that impossible."; ], has scenery; Object -> bags "bags" with name 'bag' 'bags//p' 'schoolbag' 'schoolbags//p' 'satchel' 'satchels//p' 'overpriced' 'sports' 'gear', article "some", with description "The schoolbags, tokens of their owners' social status, run the gamut from weather-beaten satchels to the latest in overpriced sports gear.", before [; Open, Take: "That would be getting a little too close to serious theft."; ], has scenery; Object -> clothes "clothes" with name 'clothes//p' 'shirt' 'shirts//p' 'sock' 'socks//p' 'trousers//p' 'white' 'black' 'charcoal' 'grey' 'gray', article "some", description [; print "White shirts, black socks, and charcoal-grey trousers. St Borogrund's is eagerly working towards an Orwellian dystopia where colours are prohibited."; if (~~blazer.found) { blazer.found = true; move blazer to location; print "^^A solitary flash of green draws your attention to a blazer."; } print "^"; rtrue; ], before [; Take: "You've got your own school uniform."; ], has scenery pluralname; Object History "History classroom" has light with description "This is the History classroom, usually occupied by ~Neo-Nazi~ Redcough. The tables are arranged in straight lines with military precision, while the wall display is anti-Semitically asymmetrical on the back wall. The door is west.", w_to [; if (redcough in History && ~~redcough.askedForDinner) { redcough.askedForDinner = true; StartTimer(redcough, 1); "Redcough wheels on you as you turn to leave.^~You, boy! Go down to the kitchen and see if that idle wretch has finished preparing my dinner! Bring it back here on the double. And it had better be hot!~^~Yes sir,~ you reply."; } return Tower2; ]; Object -> historyTables "tables" with name 'table' 'tables//p' 'desk' 'desks//p', article "some", description "No chewing gum or carvings on these. Like everything else in Redcough's classroom, they have an air of spit and polish. More spit than polish, if you sit in the front row.", has scenery pluralname; Object -> display "wall display" with name 'wall' 'display', description [; print "A selection of hastily scribbled essays on World War II"; if (historyEssays notin location) move historyEssays to location; if (~~mask.found) { mask.found = true; move mask to location; print ", and an old gas mask"; } "."; ], has scenery; Object Geography "Geography classroom" has light with description "The flaking, yellowish walls of the Geography classroom are half-obscured by stacks of old textbooks and National Geographic back issues. A globe of the world stands on Mr Nixon's desk at the front, and there is a large window at the back. The exit is east.", e_to Tower3; Object -> geogMagazines "National Geographic back issues" with name 'magazine' 'magazines//p' 'national' 'geographic' 'geographics//p' 'back' 'issue' 'issues//p', article "some", description "He must have been collecting these for years. You could probably arrange them in chronological order by the fadedness of the cover pictures.", before [; Take: "Pointless."; ], has scenery pluralname; Object -> geogTextbooks "old textbooks" with name 'stack' 'old' 'textbook' 'textbooks//p' 'book' 'books//p', article "some", description "Various outdated tomes about rocks and glaciers.", before [; Take: "No. They're good for plagiarising when you have to write an essay, but that's about it."; ], has scenery pluralname; Object -> mrNixon "Mr Nixon the Geography teacher" has proper, with name 'mr' 'nixon' 'teacher', description "The Geography teacher is a pale, worried sort of chap. His broad northern accent means that nobody can understand a word he says, and his dull personality ensures that nobody wants to.", life [; Answer: TalkToInsteadSub(); rtrue; Ask: if (translator notin player) "It's no good. You can't understand his northern accent."; else if (~~translator.firstUsed) { translator.firstUsed = true; print "The universal translator hums into life.^"; } switch (second) { 'flies', 'window': "~Have you seen all those dead flies under your window?~ you ask.^~Aye,~ Mr Nixon sighs. ~Bladdey never comes oop 'ere to clean. Too many stairs, I reckon.~"; 'geography': "~Is Mount Everest really the tallest in the world?~ you ask.^~Oh, aye. 29,035 feet,~ Mr Nixon responds with startling rapidity.^~Don't you have any other interests?~^~Silverware,~ he admits sheepishly. ~I've quite a collection.~"; 'globe', 'world': "~Nice globe,~ you remark."; 'himself', 'self', 'teaching': "~How did you get into teaching?~ you ask.^~Do you know, lad, I can't rightly remember,~ he admits. ~How do I get out?~^~What would you rather be doing?~^~Ah, I don't know. I keep meaning to sort my collection of silver spoons.~"; 'map': if (map in player) ! same response as trying to give it to him { "~Any ideas about this map?~ you ask.^~A maze? That's not my kind of map,~ says Mr Nixon."; } else "You don't have it."; 'silver', 'silverware', 'spoon', 'spoons', 'trophy': print "~You collect silverware?~ you ask.^~Oh, aye.~"; if (~~trophy.given) print "^~Would you be interested in, oh, say, a sports trophy?~^~That I might, lad.~"; print "^"; rtrue; 'textbook', 'textbooks', 'book', 'books', 'magazine', 'magazines': "~What's in these books?~ you ask.^~Facts!~ Mr Nixon proclaims. ~You can only form the minds of reasoning animals upon facts.~"; ! Gradgrind in Hard Times 'translator': "~Ever see one of these before?~ you ask.^~Is it one of those Nintendo Playboys? You'd better keep it out of my lessons,~ says Mr Nixon."; } Give: if (noun == translator) "You can use the translator to talk to him without giving it away!"; ! Otherwise, ensure the player can't give him the trophy ! until they've got the translator (whether or not they ! bother to talk to him with it and get silverware hints). if (~~translator.firstUsed) "You can't very well start throwing things at him until you've found a way to communicate."; if (noun == map) ! same response as trying to talk about it { "~Any ideas about this map?~ you ask.^~A maze? That's not my kind of map,~ says Mr Nixon."; } if (noun == trophy) { if (trophy.polished) { remove trophy; trophy.given = true; move redcough to History; Achieved(10); "~Ee!~ Mr Nixon exclaims loudly, ~This could be worth summat!~^From the floor below, a voice barks, ~Silence!~ Apparently, ~Neo-Nazi~ Redcough is back in residence."; } else "Mr Nixon turns the trophy over in his hands, looks distastefully at the layer of dust it deposits on his palms, and passes it back. ~If it was real silver, who'd have treated it like that?~"; } ], has animate; Object -> globe "globe" with name 'globe' 'world', description "All the fun of a world map - on a sphere!", before [; Push, Pull: print "You spin the globe. It stops at "; ! Note: Ritimba is from Don Priestley's 'Dictator'! print (string) random("Austria", "Botswana", "Canada", "China", "Colombia", "Denmark", "Egypt", "Eritrea", "Finland", "Greece", "Iraq", "Italy", "Jamaica", "Japan", "Kenya", "Luxembourg", "Mexico", "New Zealand", "Peru", "Poland", "Portugal", "Ritimba", "Russia", "Switzerland", "Taiwan", "Uganda", "Vanuatu"); "."; Take: "Mr Nixon would never allow his globe to leave the classroom."; ], has scenery; Object -> geographyWindow "large window" with name 'large' 'window', description [; print "The highest in the school, this window affords a less than picturesque view of your unpleasant little town."; if (~~flies.found) { flies.found = true; move flies to location; print " You notice some dead flies lying underneath."; } print "^"; ], before [; Close, Open: "This window isn't designed to open - and no wonder. Teaching geography to thirty kids must make a fifty-foot drop seem tempting."; ], has scenery; Object Kitchen "Kitchen" has light with description "Steam rises to obscure your vision in the stainless steel jungle that is the school kitchen. Huge piles of plates are stacked to one side of the metal sink, while from somewhere around the back you hear the thuds and squeals of what is apparently a live cow being chopped up for tomorrow's beef lasagne. The dining hall is north.", n_to DiningHall; Object -> cook "school cook", with name 'school' 'cook', article "the", description [; move saucepan to location; "The cook is ugly and grey-haired, rather like the meals she serves up, but she's a friendly sort. She is stirring the noxious contents of an industrial-grade saucepan."; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: switch (second) { 'cookery', 'cooking', 'food', 'pan', 'saucepan', 'scone', 'scones': print "~What's cooking?~ you enquire.^~Scones!~ says the cook"; if ((~~flies.given) || (~~polyfilla.given)) { print ", then squints at you. ~Hey, you're the delivery boy, right? I need"; if (~~flies.given) { print " some raisins"; if (~~polyfilla.given) print ", and"; } if (~~polyfilla.given) print " some more dough"; print ".~"; } else print "."; print "^"; rtrue; 'dinner', 'dinners': print "~I'd like a school dinner,~ you say."; if (dinner.takenBefore) "^~Again?~ chuckles the cook. ~You're having me on.~^She's right: no mortal man could stomach two of those in a day."; else "^~Got your dinner money, love?~ asks the cook."; 'herself', 'self': "~Is it fun being a cook?~ you ask.^~Good enough for me, love,~ she nods."; 'plate', 'plates', 'sink': "~How do you stack the plates so high?~ you ask.^The cook slyly taps the side of her nose. ~Trade secret.~"; } Give: if (noun == cat) "The cook may be short-sighted, but she doesn't cook anything that's still moving."; else if (noun == caesium) "No. There are practical jokes, and then there's manslaughter."; else if (noun == flies) { flies.given = true; remove flies; afterGiveFakeFoodToCook(); "The cook drops the ~raisins~ into the simmering saucepan."; } else if (noun == polyfilla) { polyfilla.given = true; remove polyfilla; afterGiveFakeFoodToCook(); "You wince as the cook stirs the putty into the scone mixture."; } else if (noun == money) { remove money; dinner.takenBefore = true; move dinner to player; "You give the dinner money to the cook. She hands you a plate of... of... something."; } ], before [; Attack: "This would be a dangerous place for a fight."; ], has animate female; Object -> saucepan "industrial-grade saucepan" with name 'industrial' 'grade' 'industrial-grade' 'sauce' 'pan' 'saucepan' 'contents', description "You don't even want to know what's in there.", before [; Receive: "The cook isn't quite that short-sighted."; Take: "You can't. The cook is using it."; ], has scenery; Object -> steam "steam" with name 'steam' 'cloud' 'clouds//p', article "some", description "It's like being in a sauna. One that smells of school dinners.", has scenery; Object -> sink "sink" with name 'metal' 'kitchen' 'sink', description "It seems reasonable to hypothesise that the sink has hot and cold taps and a plughole, but the clouds of steam make it impossible to find out.", before [; Enter, Receive: "If you got that close to the sink, the steam would boil you alive."; ], has scenery; Object -> plates "plates" with name 'huge' 'pile' 'piles//p' 'plate' 'plates//p' 'dish' 'dishes//p', article "some", description "The stack of plates rises majestically into the mist. Now you can say you've seen the great wall of china.", before [; Climb, Pull, Push: "~Careful with those, love!~ the cook admonishes."; Take: "You wouldn't be able to reach the top of the pile."; ], has scenery pluralname; Object -> knife "very sharp knife" with name 'very' 'sharp' 'knife', with takenBefore false, description "Looks threatening.", before [; Rub: "The knife is already bright and clean."; ], after [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You slip the knife into your pocket. Oops - that'll need mending later."; } ]; Object English "English classroom" has light with description "You stand in the English classroom, blessed by its south-facing window with more sunlight than any other room in the tower and by its proximity to Bladdey's cupboard with an occasional cleaning. There is a large blackboard. The desk at the front of the room bears a small snowstorm of unmarked essays. The exit is east.", e_to Tower1, n_to [; if (passage.opened) return passage; return false; ]; Object -> desk "desk" with name 'desk' 'table', with description "The teacher's desk has a pile of essays on it.", has scenery; Object -> essays "unmarked essays" with name 'small' 'snowstorm' 'of' 'unmarked' 'essay' 'essays//p' 'pile', article "some", with description "~Romeo loves Julleit a lot. You can tell this because Romeo say's for swear its sight, I never saw true beatty till this night. This shows he really loves Julleit. Shackspear wanted to convey the amount of love between the lovers.~^^No wonder nobody's bothered to mark them.", before [; Take: "You can do without this trash."; ], has scenery pluralname; Object -> blackboard "blackboard" with name 'blackboard' 'large' 'black' 'board', with description "The blackboard holds some fascinating secrets about ~your~, ~you're~, ~their~, and ~they're~. You should probably know about these things, but you don't want too. You still have trouble distinguishing between a catastrophe and a coma.", ! apostrophe, comma - and 'too' for 'to' before [; Rub: ! clean, polish, etc. "There's no blackboard eraser. Teachers have started locking them away to discourage amateur attempts at stage smoke."; ], has scenery; Object -> englishWindow "south-facing window" with name 'south' 'facing' 'window', with description "Most of the windows in the tower are grimy, but this one has been cleaned in the past few days. Light twinkles erratically from the patches of cleaning solution that Bladdey neglected to rinse off.", before [; Close, Open: "It doesn't seem to open."; ], has scenery; Object -> dictionary "big heavy dictionary" with name 'big' 'heavy' 'dictionary' 'dict' 'book', with takenBefore false, description "Whew! This is heavy enough to stun somebody! As an added bonus, it contains an alphabetically ordered list of words and their definitions.", before [; Read: "What are you: some kind of swot?"; Take: if (~~bladdey.conscious) "You're not lugging that thing around again!"; ], after [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You heave the dictionary off the table and secrete it about your person."; } ]; Object CrashSite "UFO crash site" has light with description [; print "Away towards the perimeter fence, this is one of the quieter parts of the school field, rumoured to be a UFO crash site. There is an elliptical scorch mark in the grass here"; if (translator.found) print " that has been disturbed by digging."; else print ", but no actual remains are visible since (claim the UFO advocates) the military removed all traces in the dead of night and even now are experimenting on the surviving alien. You, of course, believe none of this."; " The field stretches south."; ], s_to Field; Object -> mark "elliptical scorch mark" with name 'elliptical' 'scorch' 'mark', description [; "It's quite convincing. It looks as though a large burning disc struck the ground with great force. The truth is out there."; ], has scenery; Object Garden "Somebody's garden" has light with description "Technically out of bounds, this is the garden of some unfortunate soul whose house borders the school field. An irregular path meanders from east to west between the rose beds. A toolshed stands on one side. The school field is east.", e_to MuddyPath, w_to [; "Being in the garden is risky. You're not going right up to the house."; ]; Object -> toolshed "toolshed" with name 'toolshed' 'tool' 'shed', description "The toolshed is a small windowless building painted reddish-brown.", before [; Enter: "You don't want to trespass further than necessary!"; ], has scenery openable container; Object -> roseBed "rose beds" with name 'rosebed' 'rosebeds//p' 'flowerbed' 'flowerbeds//p' 'flower' 'flowers//p' 'rose' 'roses//p' 'bed' 'beds//p', article "some", description ! it's supposed to rhyme "Roses are red; violets are blue. These roses look quite thorny to you.", before [; Cut: if (roses.found) "You don't need any more roses."; if (second == knife) { "You can't grip the thorny stems, and they just bend under the knife. There must be a better tool for the job."; } else if (second == scissors) { roses.found = true; move roses to player; "You snip through a few stems and take the roses."; } else "You can't cut the roses with ", (ThatOrThose) second, "!"; Take: "Ouch! The stems are laden with thorns. You suck your injured fingers."; ], has scenery pluralname; Object Chemistry "Chemistry lab" has light with description "You are in the main Chemistry lab. A pungent smell of burnt rubber creeps into your nostrils. The desks and stools bear the permanent scars of corrosive chemicals and ~accidental~ fires. Doorways lead east and south.", s_to Mound, e_to [; if (mask has worn) return Toilets; "As you approach the toilets, the stomach-churning smell drives you back. It's nauseating!"; ]; Object -> chemLabDesks "desks" with name 'desk' 'desks//p' 'table' 'tables//p' 'sink' 'sinks//p' 'bunsen' 'burner' 'burners//p', article "some", description "These ingenious desks have Bunsen burners and sinks built into them, so that pupils can not only start localised fires but also put them out before the teacher comes back.", has scenery pluralname; Object -> stools "stools" with name 'stool' 'stools//p' 'chair' 'chairs//p', article "some", description "Most of the four-legged stools have taken considerable chemical damage. You trust that the experimenters wrote up their findings with a hypothesis, diagram, and conclusion.", before [; Enter: "Nah. They're terribly uncomfortable."; Take: "You wouldn't get far with one of these."; ], has scenery pluralname; Object -> caesium "jar of caesium" with name 'jar' 'caesium' 'cesium', with justUsed false, description "This small brown jar contains several submerged chunks of caesium and bears a multitude of safety warnings. Apparently, it reacts violently with water. Hmmm.", before [; Eat: "Caesium salad would probably be fatal."; ! Caesar salad ], after [; Close: "You screw the cap back onto the jar."; Open: "You unscrew the cap from the jar of caesium."; ], has openable; Object Reception "Reception" has light with description "This swanky, richly carpeted area of the school, complete with coffee table, is the reception, where prospective parents are led and/or misled. The receptionist typing away in the office next door glares indignantly at you whenever she makes a spelling error. An impressive archway leads north, while to the west you see a small, plain door.", n_to Middle, w_to [; if (map.usedInMaze) return HeadsOffice; ! only do the maze once else if (staffRoomDoor hasnt open && ~~staffRoomDoor.everBeenOpened) { "The door is closed. Another darned puzzle to solve..."; } return staffRoomDoor; ]; Object -> receptionist "receptionist" with name 'receptionist' 'typist' 'typing' 'woman', description "The receptionist scowls back at you through the glass partition. She must be incredibly good at making coffee, you decide, because she clearly wasn't chosen for her people skills.", life [; Answer: TalkToInsteadSub(); rtrue; Ask: "She waves her hands at you angrily. Perhaps she really wanted to be a traffic warden. At any rate, she doesn't want to deal with you."; ], has scenery animate; Object -> office "office" with name 'office', article "the", description "The office is a small, untidy room of fax machines and photocopiers. A glass partition separates it from the main reception area.", before [; Enter: "You can't get into the office from here."; ], has scenery; Object -> partition "glass partition" with name 'glass' 'window' 'partition', article "the", description "It's a partition. It's made of glass. Ergo, it is a glass partition.", has scenery; Object -> coffeeTable "coffee table" with name 'coffee' 'table' 'mahogany', description "This handsome piece of mahogany is a coffee table in name only. You're quite certain that nobody would ever be permitted to place a hot, spillable drink on it.", has scenery; Object -> carpet "rich carpet" with name 'rich' 'carpet', description "The carpet is deep red and expensive.", has scenery; Object -> archway "impressive archway" with name 'impressive' 'archway' 'arch' 'way', description ! This is a hint about the rather non-obvious "red herring" puzzle, ! where you must cook the herring to make it black and thus usable. "The archway bears an ornate coat of arms and the inscription, ~Un poisson cuit est un poisson utile~. Pff, you've never had time for fancy Latin.", ! French really! has scenery; Object -> trophy with name 'trophy', short_name [; if (self.polished) print "gleaming silver"; else print "tarnished old"; print " trophy"; rtrue; ], with polished false, with given false, with takenBefore false, description [; if (~~self.polished) "The trophy just looks like a tarnished, two-handled metal cup."; else "The silver trophy now flashes in the light. Well, gosh."; ], parse_name [ w rv; w = NextWord(); if ((w == 'gleaming' or 'silver' && self.polished) || (w == 'tarnished' or 'old' && ~~self.polished)) { w = NextWord(); ++rv; } if (w == 'trophy') ++rv; return rv; ], before [; Rub: if (polish in player) { self.polished = true; remove polish; "You blow some dust off the trophy and set to work, using your shirt as a cloth. Minutes later, the trophy looks like new, and your shirt rather less so. You throw the empty polish tin in the general direction of a bin you once saw."; } else "You don't have any polish."; ], after [; Take: if (~~self.takenBefore) { self.takenBefore = true; "You slide the trophy under your shirt. Nobody saw a thing, right?"; } ]; Object -> staffRoomDoor "staff room door" with name 'staff' 'room' 'staffroom' 'door', with description "A printed label on the door warns, ~No Entry~. Underneath, a poor speller has scrawled in yellow chalk, ~No exit ether~.", with everBeenOpened false, door_to StaffRoom, door_dir w_to, before [; Attack: if (self has open) "The door is already open."; "You bang on the door. It stays closed."; ], after [; Open: print "You cautiously push the door open."; if (~~self.everBeenOpened) print " Gasp! It's the staff room!"; self.everBeenOpened = true; print "^"; rtrue; ], has static scenery door openable; Object Languages "Languages block" has light with description "You are in the entrance lobby of the languages block, festooned with drawings. This is as far as you can penetrate, because all of the classrooms are perpetually occupied. From one of them, a guttural German love song drifts out to offend your ears. You can see the car park outside to the south.", before [; Listen: ! from Beborn Beton's _Im Innern Einer Frau_: ! "You are intolerable, you are egotistical, you drive me to madness!" "~Du bist unertraeglich; du bist egoistisch; treibst mich in den Wahnsinn ...~"; ], s_to CarPark; Object -> drawings "drawings" with name 'drawing' 'drawings//p', article "some", description "You're still not sure how drawing Asterix and Obelix was supposed to help your class learn French, but it sure was fun.", has scenery pluralname; Object Toilets "Toilets" has light with description "The evil-smelling area colloquially referred to as ~the bogs~ comprises the usual fittings, viz. mirror, basin and urinal. The tiled wall opposite is covered in badly scrawled graffiti, and on the floor are a few puddles of dubious origin. You can go west. Please.", w_to Chemistry; Object -> mirror "mirror" with name 'mirror' 'glass' 'reflection', description "The mirror also looks into you.", ! Nietzsche ("the abyss ...") before [; Attack: "Seven years' bad luck on top of a week of detention?"; Take: "The mirror is built into the wall."; ], has scenery; Object -> basin "basin" with name 'basin' 'wash' 'washbasin' 'sink' 'hot' 'cold' 'tap' 'taps//p', description "The basin has hot and cold taps. There's a mirror above it.", before [; Receive: "You don't need to put things in there."; SwitchOff: "The water isn't running."; SwitchOn: "You turn on one of the taps, eliciting a spluttering trickle of rusty sludge that runs for a few seconds and tails off."; ], has scenery; Object -> urinal "urinal" with name 'urinal', description "You'd rather not.", before [; Receive: if (noun == caesium) "You can do without a golden shower."; ], has scenery; Object -> puddles "puddles" with name 'puddle' 'puddles//p', article "some", description "They might just be water, but you're not inclined to investigate.", before [; Receive: if (noun == caesium) "You can do without a golden shower."; ], has scenery pluralname; Object -> graffiti "graffiti" with name 'graffiti' 'grafitti', article "some", description "~My mother made me a homosexual~, one reprobate has scrawled across the tiles. Underneath, in a neater hand, someone has added: ~If I give her the wool, will she make me one too?~", has scenery; Object Library "Library" has light with description "Flimsy off-white shelves stretch from one end of the library to the other, populated with carefully selected young adult literature. Somewhere behind this literary jungle, you hear the assistant librarian shouting for quiet at the top of her repellent voice. The exit is south.", s_to DiningHall; Object -> literature "young adult literature" with name 'young' 'adult' 'literature' 'book' 'books//p', article "some", description [; print "Dozens of books. Most of them are stupid teenage angst novellas in bite-proof plastic covers. You're no fan of literature, but even you know when to feel patronised."; if (~~book.found) { book.found = true; move book to location; print "^^One book looks particularly unremarkable."; } print "^"; ], before [; Take: "You decide to wait for the film."; ], has scenery; Object -> bookshelves "bookshelves" with name 'flimsy' 'off' 'white' 'offwhite' 'shelf' 'shelves//p' 'bookshelf' 'bookshelves//p', article "some", description [; "Each shelf is filled with books of all descriptions. It strikes you that this doesn't say much for the library's filing system."; ], has scenery pluralname; Object SixthForm "Sixth form block" has light with description [; print "Loud music blasts into your ears as you stand in the smoke-filled sixth form common room. The walls are bedecked with posters. Various saggy sofas are occupied by sixth-formers, who sit and smoke around the pool table. The exit is west."; if (sixthFormers.stoned) { print "^^The air smells like burning rope and urine."; } print "^"; ], w_to CarPark; Object -> sofas "sofas" with name 'saggy' 'sofa' 'sofas//p', description "The sofas seem to have taken their cue from the surrounding decor and reverted to an earlier evolutionary stage, something akin to Siamese beanbags.", before [; Enter: "No time to sit around. You need to find that report!"; ], has scenery pluralname; Object -> cue "pool cue" with name 'pool' 'cue', description "The cue is actually a vandalised chair leg. You have to admire the initiative of the sixth form.", before [; Take: if (~~sixthFormers.stoned) "The pool cue is in use - and sixth form pool games rarely end."; ], after [; Take: "Noticing that the pool game has been abandoned, you reach across and take what serves for a cue."; ]; Object -> poolTable "pool table" with name 'pool' 'table', description "The pool table's sine wave cross-section complements the bent cue.", has scenery; Object -> smoke "smoke" with name 'smoke', article "some", description "Bluish cigarette smoke fills the room.", has scenery; Object -> sixthFormPosters "posters" with name 'poster' 'posters//p', description "The posters advertise cancelled gigs by unknown indie bands.", has scenery pluralname; Object -> microwave "microwave oven" with name 'microwave' 'oven', with available false, description "Splashed with sauce and boasting a large ~Failed~ sticker, the microwave oven is a major source of radiation, which local action groups have erroneously blamed on the nearby power station for years.", before [; Receive: ; rtrue; Open, Close, SwitchOn: "Just try cooking something."; Take: "There's no way you're carrying that around."; ]; Object -> sixthFormers "sixth-formers" with name 'sixth' 'former' 'formers//p' 'sixthformer' 'sixthformers//p' 'sixth-former' 'sixth-formers//p', article "some", with stoned false, with pluggedSequel false, description [; print "What monumental slackers! They are certainly well prepared for life at university."; if (~~self.pluggedSequel) { print "^(And if you want to know what happens there, you'll have to play the sequel - Lecture Feature!)"; self.pluggedSequel = true; } print "^"; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: if (self.stoned) "They smile and wish you peace. It's bizarre!"; switch (second) { 'himself', 'themselves', 'self', 'selves': "~What's up, guys?~ you ask.^~More to the point, what are you doing in our common room?~ one of the sixth-formers replies."; 'microwave', 'oven': "~Hey, could I use the microwave?~ you ask.^~No!~ comes the reply."; 'smoking', 'smoke', 'cannabis', 'marijuana', 'hash', 'hashish', 'weed', 'pot', 'ganja', 'grass': ! Note: 'smoking' in general as well as the cannabis. "~Don't you know smoking is dangerous?~ you ask.^~It's relaxing!~ one of the sixth-formers protests.^~Wish we had something more relaxing to smoke,~ mutters another, glancing at you doubtfully."; 'pool', 'cue', 'table', 'pool cue', 'pool table': "~I bet I could kick your lazy arses at pool,~ you exclaim.^~I bet we could kick your scrawny arse out of our common room,~ comes the reply."; 'band', 'bands', 'gig', 'gigs', 'poster', 'posters', 'music': "~Do these bands even exist?~ you ask, indicating the posters.^~Listen, kid,~ says one of the sixth-formers. ~One day you'll grow out of mainstream pop and start getting into serious bands.~^~Yes,~ you reply, ~seriously fictional ones.~"; } Give: if (noun == cannabis) { "Some of them are prefects. You can't just hand over a packet of drugs in plain view."; } else if (noun == ball && cannabis in ball) { self.stoned = true; microwave.available = true; move ball to sixthFormers; Achieved(11); "You hand the ball to the nearest sixth-former, uttering the cryptic words, ~Johnny Pike asked me to give you this free sample.~ A great cheer goes up from the sixth-formers as they bundle the prefects out of the room on various pretences. Cigarettes of a dubious nature are rolled and smoked."; } ], has animate pluralname; Object Field "Field" has light with description "This is a singularly uninspiring area of the school field, which extends north and west. The long grass is in need of mowing. To the south, the field gives way to tarmac.", n_to CrashSite, w_to MuddyPath, s_to Playground; Object -> grass "long grass" with name 'long' 'grass' 'field' 'floor', article "some", description [; if (~~ball.found) { move ball to location; ball.found = true; "You discover a soggy old tennis ball."; } else "It seems to be greener on the other side."; ], before [; Take: "That's of no use to you."; ] has scenery; Object Middle "Middle of the school" has light with description "You stand at the junction of two corridors, the main one connecting the tower (to the west) with the dining hall (east). A trail of muddy footprints originates from the battered glass doors that open north onto the playground. The reception area is south.", after [; Go: if (secretary.showInMiddleOfSchool) { secretary.showInMiddleOfSchool = false; print "~Oof!~^~Oh, excuse me.~^You bump into the head's secretary. You have barely got your apology out before she hurries into reception and through the staff room door.^"; move secretary to HeadsOffice; } ], w_to Tower0, e_to DiningHall, n_to Playground, s_to Reception; Object -> glassDoors "battered glass doors" with name 'battered' 'glass' 'door' 'doors//p', article "the", with description "These rain-spattered glass doors open onto the playground.", before [; Open, Close: "The doors are propped open all day. Having pupils open and close them was found to cost a lot in replacement glass."; ], has scenery; Object -> footprints "trail of muddy footprints" with name 'trail' 'muddy' 'footprints//p' 'foot' 'print' 'prints//p', with description "There aren't any solid clods of mud among the shiny wet footprints today, which suggests that the marshy field has been declared ~out of bounds~.", has scenery; Object Music "Music room" has light with description "Devoid of pupils and their cacophony, the Music room drowses in silence. A few rows of rickety tables await the next class. Some curiously shaped instruments are propped against the back wall; others lie in cases on the floor. A muffled hubbub comes from the dining hall, to the west.", w_to DiningHall; Object -> musicTables "tables" with name 'row' 'rows//p' 'of' 'rickety' 'table' 'tables//p', article "some", description "The Music department is something of a red-headed stepchild at St Borogrund's, relying chiefly on hand-me-downs from the rest of the school. These old-fashioned tables even have slots for ink-wells.", has scenery pluralname; Object -> instruments "musical instruments" with name 'curiously' 'shaped' 'musical' 'instrument' 'instruments//p' 'case' 'cases//p', article "some", description "You look at the instruments. A few are familiar to you, but others look more like instruments of torture than the musical variety. The last school concert only reinforced this impression.", before [; Open: "No! The cases look like little coffins."; Play: "You cast a speculative glance at one brass monstrosity, but realise you wouldn't even know which end to blow into."; Take: "Leave the instruments alone. They're heavy, expensive, and fragile."; ] has scenery pluralname; Object -> piano "moth-eaten piano" with name 'moth-eaten' 'moth' 'eaten' 'piano', description "One or two keys are missing, but the piano seems to be in working order.", before [; Play: move herring to location; remove self; "Never mind the piano. It's a red herring - wait, what's this?"; Push, Pull: "You shift the piano slightly, but find nothing."; Take: "Now you're just being silly."; ]; Object Maths "Maths classroom" has light with description "This is your Maths classroom. Its cream walls are plastered with unidentifiable pictures made from coloured paper - or, as political correctness would have it, ~work done by some of the less able students~. Unit bricks and fragments of plastic are scattered over the floor, and a cupboard is set into the west wall. Beneath a small skylight, a doorway leads north.", n_to MuddyPath, u_to [; if (skylight has open) { print "You grab the frame of the open skylight and slowly haul yourself onto the roof.^"; Achieved(12); return MathsRoof; } else "The skylight is closed."; ]; Object -> unitBricks "unit bricks" with name 'unit' 'brick' 'bricks//p', article "some", description "These wooden blocks are used to illustrate the process of counting. Most secondary schools have no need for them - but at St Borogrund's, either the pupils throw unit bricks around, or they start throwing calculators.", before [; Take: "Thanks, but you already know how to count."; ], has scenery pluralname; Object -> plasticFragments "fragments of plastic" with name 'fragment' 'fragments//p' 'of' 'plastic' 'ruler' 'remains//p', article "some", description "The remains of a ~shatterproof~ ruler, no doubt.", before [; Take: "These shards of plastic are useless to you."; ], has scenery pluralname; Object -> pictures "unidentifiable pictures" with name 'unidentifiable' 'picture' 'pictures//p' 'work', article "some", description "Plenty of lurid triangles, but they're not exactly Picasso.", before [; Take: "You've never fancied yourself as an art thief."; ], has scenery pluralname; Object -> mathsCupboard "cupboard" with name 'cupboard', description "It's a varnished wooden wall-mounted cupboard. Tasteful.", has scenery openable container; Object -> skylight "skylight" with name 'skylight' 'sky' 'light', description [; print "The square hinged window is filmed with dirt."; if (self hasnt open) " It is closed."; " It is open, revealing a cloudless sky."; ], before [; Close: if (self hasnt open) "It's already closed."; "Opening it was a pain. You'd rather leave it open."; Lock: "You can't lock the skylight."; Open: if (second ~= cue && self hasnt open) { cleaningEquipment.broomHandleSuggested = true; "You stand on a chair and push at the skylight, but you aren't quite tall enough to push it all the way open. Perhaps a broom handle or some such implement would help."; } Unlock: if (second ~= cue) "You can't open the skylight with that."; ], after [; Unlock: give self open; ! not just "unlocked" but opened "You jab the pool cue skywards. Small pieces of moss and gravel rain into the room as the skylight falls all the way open."; ], with_key cue, has scenery openable lockable locked; Object -> phone "mobile phone" with name 'mobile' 'phone' 'cell' 'cellphone' 'telephone', description "Somebody must have confiscated this mobile phone: they're not allowed in lessons. It's in a trendy black and silver case and appears to be capable of doing sums and playing some stupid blocky game, but you don't have time to work out all the different modes.", before [; Open: "You consider removing the batteries, but decide against it. They're probably weird, tiny ones that wouldn't work in anything else."; SwitchOff: "The mobile phone is switched off."; SwitchOn: "You've got nobody to call. No point wasting the batteries."; ]; Object FirstYears "First-year classroom" has light with description "The first-year classroom is in a chaotic state. The pupils are doing every conceivable thing except work. A substitute teacher pleads ineffectually for silence. Above a sea of paper aeroplanes, a large window looks out across the playground. The door is south.", s_to Tower1; Object -> substTeacher "substitute teacher" with name 'substitute' 'sub' 'supply' 'teacher', description [; "The substitute teacher is trying to establish some order in the classroom, but it's painfully clear that she doesn't know where to begin. She was probably knee-deep in paper aeroplanes by the time she finished announcing her name."; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: switch (second) { 'aeroplane', 'aeroplanes', 'paper', 'plane', 'planes': "~Do you like our aeroplanes, Miss?~ you ask in the best first-year voice you can muster.^~Pick those up right away!~ the teacher snaps unconvincingly."; 'lost', 'firstyear', 'first-year': ! only topics without spaces work "~There's a lost first-year wandering the school,~ you say. ~One of yours?~^~How do you know?~ demands the teacher. ~Have you been sneaking out of my lesson?~"; 'pupil', 'pupils': "~Lively bunch of scallywags, aren't we?~ you comment.^~Yes, you little mother- I mean, your mother should buy you a blazer that fits,~ the substitute teacher improvises lamely."; 'herself', 'self', 'selves', 'teaching': "~How's teaching?~ you ask.^~Get back to your seat!~ orders the exasperated substitute."; 'window': print "~Can we have the window "; if (window has open) print "closed"; else print "open"; ", Miss?~ you ask.^~Yes! No! I don't care. Go and sit down!~ says the teacher."; } ], has animate scenery; Object -> pupils "pupils" with name 'pupil' 'pupils//p' 'first-year' 'first-years' 'first' 'year' 'years//p' 'firstyear' 'firstyears//p', article "some", description [; "Horrid little things."; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: "You have no desire to interact with these giggly menaces."; ], has animate scenery pluralname; Object -> paperPlanes "paper aeroplanes" with name 'sea' 'of' 'paper' 'aeroplane' 'aeroplane//p' 'plane' 'planes//p', article "some", description "They're rather clumsily made. Still, the first-years haven't had your years of plane-building experience.", before [; Take, Drop: ! so that 'throw' will work "You pick up one of the paper aeroplanes and throw it. The plane nosedives back into the pile."; ] has scenery pluralname; Object -> window "large window" with name 'large' 'window', description [; print "The window is "; if (self has open) print "open"; else print "closed"; print ". You look down to the playground"; if (bladdey in playground) { print " and notice Bladdey, the caretaker, directly below"; if (~~bladdey.conscious) ". He seems to have been concussed by a dictionary. So much for the old assertion that ~words can never hurt me~."; else move bladdeySeenFromWindow to location; } "."; ], before [; Close: if (self has open) "You reach to close the window. At once, every girl in the room wails, ~Leave the window open: it's hot in here!~ You sigh."; Open: if (self hasnt open) "You reach to open the window. At once, every girl in the room wails, ~Don't open the window: it's freezing in here!~ You are clearly outnumbered."; Receive: if (self hasnt open) "You can't. The window is closed."; else if (noun == dictionary) { move dictionary to Playground; bladdey.conscious = false; "You heave the dictionary out of the window. It plummets down onto Bladdey's head and knocks him out for the count!"; } else "Throwing that out of the window wouldn't help."; ], has scenery openable; Object Mound "The Mound" has light with description "This central region of the playground is known as the Mound, although the origins of that picturesque moniker are lost in the mists of time. The Chemistry lab is north, the Art block is west and the playground stretches to the east. There is a large grassy mound here.", n_to Chemistry, w_to Art, e_to Playground, u_to [; <>; ]; Object -> theMound "mound" with name 'mound' 'hill' 'hillock', description "The mound is a lush green island in a sea of bland tarmac. Regrettably, its idyllic slopes are out of bounds to pupils.", before [; Climb, Enter: "Climbing on the mound is forbidden, and it's visible from half the classrooms in the school."; ] has scenery; Object DiningHall "Dining hall" has light with description "This is the dining hall, a constant hive of activity since the introduction of sliding timetables and their multiple lunch periods. Teachers cower over their plates as the more unruly pupils catapult food at each other. Plates fly in and out of a hatch to the kitchen, located to the south. The library is north, the Music room is a fair distance to the east and a pair of swing doors leads west.", after [; Go: if (katie.showInDiningHall) { katie.showInDiningHall = false; print "You leave the kitchen just in time to see your girlfriend Katie wander through the dining hall.^~Hey, Rick, I'm going to the Art block to hand in some homework. Meet me there in a little while, okay?~^She is gone before you can reply.^"; move katie to Art; } ], s_to Kitchen, n_to Library, e_to Music, w_to Middle; Object -> diningHallPupils "pupils" with name 'pupil' 'pupils//p', article "some", description [; "The pupils are sitting in close-knit social clusters in order to chatter, eat, and gesticulate, sometimes managing all three simultaneously."; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: "The pupils pay no attention to you."; ], has animate scenery pluralname; Object -> teachers "teachers" with name 'teacher' 'teachers//p', article "some", description [; "The teachers are tucking into their food with relish. Pupils tend to prefer ketchup. Anyway, you have to cover school dinners in something."; ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: switch (second) { 'cook', 'kitchen': "~Where can I find the cook?~ you ask.^~She's in the kitchen,~ says one of the teachers, waving her fork in that general direction."; 'food', 'dinner', 'dinners': print "~Good food?~ you ask.^The nearest teacher stifles a snort. ~You're new around here, eh?~"; if (~~dinner.takenBefore) { print "^~How do I get served?~ you persist.^~Give the cook some money. Tell you what, though, she should be paying us to eat this stuff.~"; } print "^"; rtrue; 'himself', 'herself', 'themselves', 'self', 'selves', 'teaching': "~How's it going?~ you enquire.^~There is a general murmur of dissatisfaction."; 'pupil', 'pupils': "~I can't believe how badly these kids are behaving!~ you exclaim.^~That's a good one, coming from Rick Hejlsberg,~ says your woodwork teacher."; 'redcough', 'mr redcough': "~Why doesn't Mr Redcough eat with the rest of you?~^~Because he's a very kind fellow,~ sneers the Religious Education teacher.^The others snigger behind their hands."; } ], has animate scenery pluralname; Object -> platesOfFood "plates of food" with name 'plate' 'plates//p' 'of' 'food', article "some", description [; "The food doesn't look very appetising."; ], before [; Take: "You can't run off with somebody else's dinner. Get your own!"; ], has scenery; Object -> hatch "hatch" with name 'serving' 'hatch', article "the", description [; "The serving hatch connects the kitchen and dining hall."; ], before [; Enter: "It's not nearly big enough. If you want to go into the kitchen, you can just walk south!"; Close: "You don't know how to close it."; Open: "The serving hatch is already open."; Receive: "It's already being used for plates."; Search: ! applies to "look through" "You peer through the serving hatch into a cloud of steam. ~Mind out, love,~ comes the cheerful voice of the cook. ~Hot dinners coming through!~"; ], has scenery; Object Alcove "A secret alcove" has light with description "You are in a small, shadowy recess behind the blackboard. The brickwork is damp and blotched with mildew. You see daylight to the south.", s_to English; ! since the passage must be open if you're here Object -> brickwork "brickwork" with name 'brick' 'bricks//p' 'brickwork', article "the", description [; if (~~ring.found) { move ring to location; ring.found = true; } "There is an iron ring set into one of the bricks."; ] has scenery; Object -> mildew "mildew" with name 'mildew', article "some", description [; "You've seen this powdery white stuff in the nastier parts of school before, but never in such quantities."; ] has scenery; Object SwimmingPool "Swimming pool" has light with description "The school's swimming pool stretches before you, surrounded by an endless chequerboard of blue and white tiles. There is a grimy ring of green in the pool corresponding to a decrease in the level of water - popularly believed to be siphoned off by the school kitchen. A trail of large puddles marks the recently travelled route west from pool to changing rooms.", with occupied true, before [; Swim: "The thought of diving into that sludge isn't very appealing, and Redcough probably won't check up on you; so you decide against it."; ], w_to ChangingRoom; Object -> poolPuddles "trail of large puddles" with name 'trail' 'of' 'large' 'puddle' 'puddles//p', article "some", description [; "The spilled water reflects the lights and chequered tiles."; ], has scenery; Object -> tiles "tiles" with name 'chequered' 'chequerboard' 'chequer' 'board' 'blue' 'and' 'white' 'tile' 'tiles//p', article "some", description [; "The chequered tiles are stippled and shining with condensation."; ] has scenery; Object -> pool "swimming pool" with name 'swimming' 'pool' 'water', description "Twenty metres in length, the pool is about two thirds full of greenish water.", before [; Enter: ; rtrue; Receive: if (noun == caesium) { if (caesium hasnt open) { move caesium to location; "You throw the caesium into the pool. The unopened jar bobs about harmlessly."; } else if (mrBlister in Art) { mrBlister.awake = true; caesium.justUsed = true; Achieved(13); remove caesium; remove bladdey; ! you've found his key by now remove bladdeySeenFromWindow; bladdey.justRemoved = true; "You hurl the open jar of caesium into the murky depths. Seconds later, a mushroom cloud of boiling water erupts up to the ceiling, to the accompaniment of an ear-shattering crash fit to wake the dead.^^Who said science can't be fun?"; } else { "That would certainly go with a bang. Perhaps you should wait until you really need a loud noise."; } } else if (noun == cat) "Ooh, you wouldn't!"; else if (noun == phone or disk or translator) "No. It probably wouldn't work after that."; else if (noun == cue) "That's the wrong kind of pool, Einstein."; else if (noun == herring) "It's too late to put this fish back in the wild."; else if (noun == money) "You won't get any good luck that way."; else "Throwing that in the pool would achieve nothing."; ], has scenery; Object MuddyPath "Muddy path" has light with description "You are on a very muddy east-west path leading alongside the field. The deep-brown monotony is divided by a few waterlogged bicycle tracks. The bottom of somebody's garden is visible to the west. The entrance to the Maths block is south.", e_to Field, w_to [; if (towel notin MuddyPath) { "It's just too muddy. You're in enough potential trouble over your report without ruining your shoes as well. You'd need to put down a plastic sheet or something."; } return Garden; ], s_to [; if (oscar in Maths) { "There's a test in progress. You peer in through the window in search of Oscar. He gives you a furtive thumbs-up sign."; } return Maths; ]; Object -> path "muddy path" with name 'mud' 'muddy' 'path' 'deep' 'brown' 'bicycle' 'track' 'tracks//p', description "Rain, feet and bicycles have turned the path into something of a swamp. It gets even muddier to the west.", has scenery; Object CarPark "Car park" has light with description "The school car park, bordered by a row of large oak trees, is empty but for a few teachers' cars and a dilapidated minibus. You can go north to the languages block, west to the playground or east to the sixth form block. A metal door leads south to the changing room.", n_to Languages, w_to Playground, e_to SixthForm, s_to changingRoomDoor; Object -> trees "trees" with name 'oak' 'oaks//p' 'tree' 'trees//p', article "some", description "The spreading boughs of the oaks protect any vehicles parked below from rain, other than the occasional hail of acorns. Their upper branches sway gently in the breeze.", before [; Climb: "You've got better things to do."; ], has scenery pluralname; Object -> cars "cars" with name "teacher^s" "teachers^" 'car' 'cars//p' 'vehicle' 'vehicles//p', article "some", description "The cars are pretty nondescript. If only your school had one of those ~wacky~ teachers, there might be a car with funny stickers in the window; but the best on offer is Mr Redcough's menacing ~Careless work costs lives~.", before [; Enter: "Better not. You don't want to set off any alarms."; ], has scenery pluralname; Object -> minibus "school minibus" with name 'dilapidated' 'old' 'school' 'mini' 'minibus' 'bus', article "the", description "The old school minibus is a veteran of four failed MOTs and a small fire.", before [; Enter: "You try the doors of the minibus, but they won't open."; ], has scenery; Object -> changingRoomDoor "changing room door" with name 'metal' 'changing' 'room' 'door' 'lock' 'keyhole', with description "This door leads to the changing rooms; its sturdy metal construction and proximity to the showers imbue it with vague, unpleasant connotations of Nazi Germany. To the chagrin of the girls, who claim that Bladdey the caretaker squints in at them, it is fitted with a standard keyhole.", with everBeenUnlocked false, door_to ChangingRoom, door_dir s_to, with_key clip, before [; Attack: "You kick the metal door. It doesn't seem to care."; Lock: if (self has locked) "It's locked already."; "Without a key, you suspect it would be harder to lock this door than it was to unlock it."; Search: ! applies to "look through" "You can't see anything through the keyhole, but you can hear that nobody's in there at the moment."; ], after [; Unlock: self.everBeenUnlocked = true; give changingRoomDoor open; "You insert the paper clip into the keyhole and jiggle it around. Eventually there is a click and the door swings open."; ], has static scenery door openable lockable locked; Object Gym "Gym" has light with description "The squeaky floor of the gym, divided by coloured lines into courts and goal areas, bears a surreal resemblance to a London Underground map. The far wall is a disorganised blockade of gym equipment, with a basketball hoop suspended eight or nine feet above the mess. A climbing rope hangs invitingly from the ceiling. The changing room is east.", e_to ChangingRoom; Object -> gymFloor "squeaky floor" with name 'squeaky' 'floor', description [; "The floor is made of something beige and plasticky that squeals when you jump on it."; ! and 'jump' responds to this ], has scenery; Object -> gymStuff "gym equipment" with name 'disorganised' 'blockade' 'mess' 'gym' 'equipment', article "some", description "Blue gym mats, vaulting horses, benches, and related paraphernalia. You're really not interested in any of this.", before [; Take: "That's not remotely practical."; ], has scenery; Object -> fixedRope "climbing rope" with name 'climbing' 'rope', with severed false, description [; if (~~self.severed) "The rope is very slightly frayed in places, but it looks safe enough."; else "The vandalised rope droops sadly, cut down in its prime."; ], before [; Cut: if (self.severed) "You can't reach high enough to cut any more rope."; else if (second == scissors) "You can't cut a thick rope with plastic-handled school scissors!"; else if (second == knife) { self.severed = true; move rope to location; "Small shavings drift to the ground as you frantically saw at the rope with the kitchen knife. After a minute's work, the tail of the rope drops to the ground."; } else "You can't cut the rope with ", (ThatOrThose) second, "!"; Climb: "You've never been one for heights."; Pull: print "You tug on the"; if (self.severed) print " remaining"; " rope. It sways slightly."; Take: "It's attached to the ceiling."; ], has scenery; Object -> hoop "basketball hoop" with name 'basketball' 'hoop', description "The basketball hoop projects from a miscellany of metalwork on the ceiling.", before [; Receive, ThrownAt: if (noun == ball) { move ball to location; "You miss the hoop. The soggy tennis ball lands with an unhealthy thump and makes no effort to bounce."; } "That's not really appropriate."; ], has scenery; Object MathsRoof "Maths block roof" has light with description "You are standing on the flat, gravelled roof of the Maths block. From this vantage point, you can see the tower, the playground, the car park, and most of the field. The only safe exit, however, is down through the skylight.", d_to Maths; Object -> cat with name 'cat', short_name [; if (self.fed) print "slightly less "; print "irritable cat"; rtrue; ], with fed false, with takenBefore false, description [; print "The cat has a cute ickle nose and pwitty fluffy fur."; if (~~self.fed) print " It looks dissatisfied and hungry."; print "^"; ], parse_name [ w rv; w = NextWord(); if ((w == 'slightly' or 'less' && self.fed) || (w == 'irritable')) { w = NextWord(); ++rv; } if (w == 'cat') ++rv; return rv; ], each_turn [; if (random(CAT_TALK_INTERVAL) == 1) { print "^The cat "; catTalk(); print ".^"; } ], life [; Answer: TalkToInsteadSub(); rtrue; Ask: print "You talk to the cat. It "; catTalk(); "."; Give: if (noun == herring) { if (herring.cooked) { remove herring; self.fed = true; "The cat gobbles up the scorched little fish and rubs against your legs. Mercenary."; } "You are about to offer the fish to the cat, when you remember that it's a red herring. It can't be of any use!"; } ], before [; Attack: "You don't like the look of those claws."; Take: if (self.fed) { move cat to player; self.takenBefore = true; "You gingerly pick up the cat."; } "The cat, more agile than you are, keeps its distance."; ], has animate; [ Amusing; print "Have you tried:"; print "^* eating cannabis, caesium, Polyfilla, roses, or dead flies?"; print "^* asking the sixth-formers about music?"; print "^* throwing the tennis ball at the basketball hoop?"; print "^* talking to your girlfriend about sex?"; print "^* dropping the mobile phone in a mug of coffee?"; print "^* dropping caesium in the coffee or the urinal?"; print "^* asking the teachers in the dining hall about Redcough?"; print "^* cooking the cat in the microwave?"; print "^* spinning Mr Nixon's globe of the world?"; print "^* throwing the herring or pool cue in the swimming pool?"; print "^* playing pool - or another game?"; ! play pool, play game print "^* listening in the languages block?"; print "^* trying Bladdey's cupboard door twice while it's still locked?"; "^* singing, praying, and sleeping?"; ]; [ HelpSub; "Spend some time in every location, and examine anything that might be of interest. Talk to people: some of them will help you, but they might want something first. Collect items and use them creatively to advance in your quest.^^You can always 'save' your game progress and 'restore' it later."; ]; Verb 'help' * -> Help; [ XyzzySub; "A hollow voice says something obscene."; ]; Verb 'xyzzy' * -> Xyzzy; [ UseSub; "Please be more specific about what you want to do."; ]; Verb 'use' * noun -> Use; [ SmokeSub; "You don't smoke. You don't even have a lighter!"; ]; Verb 'smoke' * held -> Smoke; [ CookSub; if (microwave in location && microwave.available) { if (noun == dinner) { if (~~dinner.cooked) { dinner.cooked = true; "... *Ping*!"; } "That doesn't need to be cooked again."; } else if (noun == herring) { if (~~herring.cooked) { herring.cooked = true; "... *Ping*!"; } "That doesn't need to be cooked again."; } else if (noun == cat) "Nah. You're not a fan of Chinese food."; else "That's not really suitable for microwave cooking."; } else if (microwave in location) { "~Oi! That's our microwave!~ exclaims one indignant sixth-former. ~You kids can't come in here and use it.~"; } else if (location == Kitchen) { "You wouldn't be able to steal cooking utensils from under the cook's nose. Anyhow, you're frightened of this kitchen. Everything seems to be made of scalding hot steel."; } else "There's no oven here."; ]; Verb 'cook' * held -> Cook; [ PlaySub; "That isn't something you can play."; ]; [ PlayMusicSub; "You lack the necessary musical skill."; ]; [ PlayPoolSub; if (poolTable in location) { "Text adventure pool wouldn't be much fun."; } else "There's no pool table in sight."; ]; [ PlayGameSub; if (location == ComputerRoom) { "You survey the computer room with a critical eye. Even if there were games on these relics, they'd probably be text-based. Ugh!"; } else if (phone in player) { "You don't know how to operate the mobile phone."; } else "You're nowhere near a computer. (Oh, don't try to be witty.)"; ]; Verb 'play' * 'music' -> PlayMusic * 'pool' -> PlayPool * 'game' -> PlayGame * 'games' -> PlayGame * noun -> Play; [ TalkToInsteadSub; "[To talk with another character, ~talk to about ~.]"; ! or, of course, "ask about ", but don't list both or they might seem like distinct commands. ]; [ TalkNoTopicSub; ! 'noun' will default to yourself if nobody else is around. "What do you want to talk to ", (the) noun, " about?"; ]; Verb 'talk' * 'to' animate -> TalkNoTopic * 'to' animate 'about' topic -> Ask; [ SpinSub; if (noun == globe && globe in player or location) <>; "You can't spin ", (ThatOrThose) noun, "."; ]; Verb 'spin' * noun -> Spin; [ ChewSub; if (noun == gum && gum in player) { "Hmm. The previous owner got most of the flavour out of it."; } "That's not something you want to chew on."; ]; Verb 'chew' * held -> Chew; [ PhoneSub; if (phone in player or location) { "The mobile phone is switched off."; ! and you can't turn it on } "You can't see a telephone here."; ]; Verb 'phone' * -> Phone * topic -> Phone; Verb 'dial' = 'phone'; Verb 'call' = 'phone'; Verb 'ring' = 'phone'; [ SitNoNounSub; "What do you want to sit on?"; ]; [ PickUnlockedSub; "That's already unlocked."; ]; [ CutNoNounSub; if (noun ~= nothing) "What do you want to cut ", (the) noun, " with?"; else "What do you want to cut?"; ]; [ MyDigSub; if (noun == nothing && trowel in player) { noun = trowel; print "(with ", (the) trowel, ")^"; } if (noun == nothing) "What do you want to dig with?"; else if (noun ~= trowel) "That's not a suitable digging implement."; else ! digging with trowel { if (player in Garden) "You don't think there's any treasure down there."; else if (player in Field or Mound or MuddyPath) "You'd be caught if you started an excavation so close to the school buildings."; else if (player in CrashSite) { if (translator.found) "Frankly, you're afraid to dig around here any more."; else { move translator to location; translator.found = true; Achieved(14); "You thrust the trowel into the burnt earth. Hey, there's some kind of silvery object down here. It's a universal translator!"; } } else "You can't see any earth to dig into."; } ]; [ PickFlowersSub; if (roseBed in location) <>; else "You don't see any flowers growing here."; ]; [ ReadSub; ! Examine by default, but allow other things to override. <>; ]; [ NoSuchVerbSub; return L__M(##Miscellany, 38); ]; [ NewRoom; if (location ~= StaffRoom) { StaffRoom.timesMovedInMaze = 0; } ]; [ Initialise; location = FormRoom; move scissors to mathsCupboard; move textbooks to mathsCupboard; move whisky to cabinet; move towel to locker; move trowel to toolshed; "^^Welcome to the world of St Borogrund's School - a world of intrigue, mystery, deceit, and excruciatingly bad dinners. Above a scattering of ugly grey outbuildings, Borogrund's four-storey tower block rises to assault the eye in a bitter and largely futile attempt to get a second glance. ^^The end of term looms, and with it the prospect of your school report. Your parents have made it very clear that the report must praise you as a talented and conscientious individual. Being none of the above - but ever loyal to your parents - you make it your quest to seek out the offending report and... amend it. ^^Borogrund's isn't just a strange name. It's a strange place. Expect the unexpected. Predict the unpredictable. And for pity's sake, don't go into the staff room unprepared...^^"; ]; Include "Grammar"; Verb 'hide' = 'insert'; ! for cannabis in tennis ball Verb 'kick' = 'attack'; ! for doors, etc. Extend 'sit' replace * -> SitNoNoun ! so 'sit' alone won't make silly assumptions * noun -> Enter * 'in' noun -> Enter * 'on' noun -> Enter; Extend 'dig' replace * -> MyDig * 'with' held -> MyDig; Extend 'search' replace * noun -> Examine; Extend 'drink' replace * held -> Eat; ! Allow for 'pick' on locks (not replacing 'pick up', though!). ! Note "pick lock" vs. "unlock door", so this only works because ! I've made "lock" and "door" synonyms for that object. Extend only 'pick' first * locked 'with' held -> Unlock ! pick lock with clip * lockable 'with' held -> PickUnlocked ! same, when already unlocked * 'flower' -> PickFlowers * 'flowers' -> PickFlowers * 'rose' -> PickFlowers * 'roses' -> PickFlowers; Extend only 'drop' * held 'out' 'of' noun -> Insert; ! drop dictionary out of window Extend only 'throw' * held 'out' 'of' noun -> Insert ! throw dictionary out of window * held 'through' noun -> Insert; ! throw dictionary through window ! Get rid of the dodgy default 'feed' verb, so that the player ! won't mess around with it when trying to give herring to cat. ! Same for 'buy' (buying dinner from the cook). Extend only 'feed' replace * -> NoSuchVerb ! feed * topic -> NoSuchVerb; ! feed Extend only 'buy' replace * -> NoSuchVerb ! buy * topic -> NoSuchVerb; ! buy ! Replace default 'cut' so that things must be cut *with* something. Extend only 'cut' replace * noun -> CutNoNoun * noun 'with' held -> Cut; ! Also get rid of show, because we want them e.g. to talk ! to Mr Nixon about the map rather than trying to show it. Extend only 'show' replace * -> NoSuchVerb ! show * topic -> NoSuchVerb; ! show ! Change 'remove' from the default, which is ... ! * held -> Disrobe ! * multi -> Take ! * multiinside 'from' noun -> Remove; ! ... so e.g. "remove lid" (vs. "remove lid from marker") won't try ! to pick up the lid with a spurious message, "first taking the lid". Extend 'jump' replace * -> Jump * 'on' 'floor' -> Jump; ! for the squeaky gym floor Extend 'remove' replace * clothing -> Disrobe * multi -> Take * multiinside 'from' noun -> Remove; ! Disable standard dialogue (see exercise 28 in manual). ! You must use 'talk to X about Y' (actually mapped to Ask). Extend 'answer' replace * topic -> TalkToInstead; Extend 'tell' replace * topic -> TalkToInstead; Extend 'ask' replace * animate -> TalkToInstead * animate 'about' topic -> Ask * animate 'for' topic -> TalkToInstead; Extend 'read' replace * held -> Read;