!Constant USE_MODULES; Constant Story "Muckabout"; Constant Headline "^A Juvenile Diversion^ Copyright (c) 1987, 2006 by Reuben Thomas.^ ^This game is distributed under the GNU GPL, version 2, or at your option, any later version. See http://www.gnu.org/licenses/gpl.html for more details.^^"; Release 1; Serial "060903"; ! Miscelleneous library setup Constant NO_SCORE; ! Standard includes, with library message changes Include "Parser"; Attribute legible; Attribute station; ! Room is part of police station ! Customise some messages Object LibraryMessages with before [; Miscellany: if (lm_n == 38) "Argle bargle blarf????"; ]; Include "VerbLib"; ! Menus Include "Menus"; Menu hints_menu "Hints for Muckabout"; Option -> "Classroom" with description "Try looking in your desk for something useful."; Option -> "Street in front of school" with description "There is something useful here. But don't be one-sided!"; Option -> "Joke stall" with description "Friends can be very helpful."; Option -> "Grassy field" with description "Bull = Goliath."; Option -> "Outside your home" with description "Bash your way into your house."; Option -> "Bank" with description "What do you need to draw money from your bank account?"; Option -> "Interrogation room" with description "Show no respect for the law!"; Option -> "Field of wheat" with description "What would you do if the scarecrow was your mummy?"; Option -> "By bin" with description "People throw away the funniest things."; Option -> "Theatre bar" with description "Did you pay attention to the video?"; Option -> "Auditorium" with description "This theatre is as bad as any other."; ! Weighty objects Property weight; Global CARRYING_STRENGTH = 20; [ carried t i; t = 0; objectloop (i in player) t = t + i.weight(i); return t; ]; Class WeightyObject with before [; Take: if (self.weight + carried() > CARRYING_STRENGTH) "You're carrying too much to pick that up."; ! Default actions to correspond to grammar redefinition Give: "Sometimes it's best to keep things to yourself."; Show: "Sometimes it's best to keep things to yourself."; ]; ! Rooms, objects and actions Object Classroom "Classroom" with description "You are sitting at your desk in the classroom, and being subjected to an incredibly boring lecture from your teacher. Outside, the sun is shining. But how can you get out?", has light; WeightyObject -> desk "desk" with name 'desk', describe [; if (self hasnt open) rtrue; ], has static container openable; WeightyObject -> -> comic "comic" with name 'comic', weight 1, before [; Examine: print "^Oh-oh! Teach catches you, and tells you to stand outside the door. But maybe you can take advantage of the situation if you hurry up...^"; remove self; PlayerTo(SchoolCorridor); StartTimer(teach_timer, 10); rtrue; ], has legible; ! Make this put you back in the classroom. ! You should be able to do something else to escape. Object teach_timer with time_left 0, time_out [; deadflag = 3; "^Teach came out to check on you and was very annoyed to find you'd gone. I think a visit to the Head is in order..."; ]; Object SchoolCorridor "Corridor" with description "You are standing in the corridor. Behind you is your classroom.", in_to [; deadflag = 3; "^You fool! Teach gets in a rage and sends you straight to the Head. I guess you blew it!!!"; ], n_to Toilets, s_to SchoolEntrance, has light; Object Toilets "Toilets" with description "You are in some extremely smelly toilets. There is some awful graffiti on the walls.", s_to SchoolCorridor, has light; Object -> "graffiti" with name 'graffiti', before [; Examine: "This adventure was originally written using the Adventure Creator (c) 1986 Incentive Software Limited."; ], has scenery legible; WeightyObject -> looroll "roll of loo paper" with name 'roll' 'loo' 'paper', weight 4, before [; Wrap: if (second == scarecrow) { scarecrow.muffled = 1; remove self; "The thick 2-ply Andrex soon shuts the scarecrow up."; } ]; Object SchoolEntrance "School entrance" with description "You're standing just inside the entrance to the school.", n_to SchoolCorridor, out_to [; StopTimer(teach_timer); StartTimer(hunger_timer, 40); PlayerTo(Street); rtrue; ], has light; Object Street "Street in front of school" with description "You are standing on the kerb of a busy street. Behind you is the school.", e_to OutsideHappyHamburger, w_to DarkAlley, in_to [; PlayerTo(SchoolEntrance); StartTimer(teach_timer); teach_timer.time_left = 0; rtrue; ], before [; Cross: PlayerTo(JokeStall); rtrue; ], has light; Object -> "kerb" with name 'kerb' 'gutter', before [; Examine: if (pound has concealed) { give pound ~concealed; "A pound coin glints in the gutter."; } ], has scenery; WeightyObject -> pound "pound coin" with name 'pound' 'coin', weight 1 has concealed; Object OutsideHappyHamburger "Outside the Happy Hamburger" with description "You are standing on the busy street outside the Happy Hamburger.", w_to Street, e_to ShoppingPrecinct, in_to HappyHamburger has light; Object DarkAlley "Dark alley" with description "You are in a dark, dank alley, with a steady dripping from the walls.", e_to Street, n_to FootballField, has light; Object JokeStall "Joke stall" with description "You are at your favourite joke stall, run by a friend on the street.", e_to BuildersYard, w_to Bank, before [; Cross: PlayerTo(Street); rtrue; ], has light; Object -> friend "friend" with name 'friend', life [; Tell, Answer, Ask, Kiss: if (catapult in friend) { move catapult to player; "Your friend gives you a catapult to test."; } ], has animate; WeightyObject -> -> catapult "catapult" with name 'catapult', weight 4, before [i s; Fire: if (catapult notin player) "You'll need to pick it up first!"; objectloop (i in player) if (i ofclass Stone) s = i; if (s) { remove s; if (bull in location) { remove bull; "The stone hits the bull right between the eyes, and it skulks off to recover in a corner."; } if (location == InterrogationRoom) { StartTimer(sergeant_timer, 10); print "^The stone hits the stupid Sergeant right between the eyes, and he slumps forward on to the desk.^"; PlayerTo(StationCorridorEnd); rtrue; } if (magpie in location && scarecrow.muffled == 0) "The scarecrow's racket keeps the magpie out of reach, and the stone falls short."; else if (magpie in location && scarecrow.muffled == 1 && magpie.hit == 0) { magpie.hit = 1; "The magpie spirals out of the sky, and lands in a heap on the ground, still clutching the object, which appears to be some sort of book, in its beak."; } else if (magpie in location && magpie.hit == 1) { move autographbook to location; remove magpie; "The magpie squawks, and flaps away, leaving the book on the ground."; } else "The stone pings out of sight."; } ]; Object HappyHamburger "The Happy Hamburger" with description "You're in the Happy Hamburger. They're doing a roaring trade right now. A sign says ~Hamburgers 1 pound each~.", out_to OutsideHappyHamburger, has light; WeightyObject -> hamburger "hamburger" with name 'burger' 'hamburger', weight 4, bought 0, before [; Take: if (self.bought == 0) "You have to pay for that!"; Buy: if (pound in player) { move self to player; remove pound; self.bought = 1; "A greasy hand grabs the coin and gives you a hamburger."; } else "How are you going to pay?"; Eat: remove self; StopTimer(hunger_timer); "Yum yum!"; ], has edible concealed; Object hunger_timer with time_left 0, warning 0, time_out [; if (self.warning == 0) { self.warning++; StartTimer(self, 10); "You're feeling rather hungry."; } else if (self.warning == 1) { self.warning++; StartTimer(self, 10); "You're gonna burst if you don't get something to eat soon!"; } else if (self.warning == 2) { deadflag = 3; "^Wally! You were so hungry, you had to go back to school to get something to eat."; } ]; Object ShoppingPrecinct "Shopping Precinct" with description "You're in the entrance to a rather posh looking shopping precinct.", w_to OutsideHappyHamburger, s_to BoxOffice, has light; Object FootballField "Football field" with description "You come to a field, where a football match is going on.", s_to DarkAlley, e_to Lane, w_to BullField, has light; Object Lane "Shady lane" with description "Ah! You are walking down a shady country lane.", w_to FootballField, s_to OutsideHome, has light; Class Stone class WeightyObject with name 'stone' 'stones//p', short_name "stone", plural "stones", weight 2; Stone ->; Stone ->; Stone ->; Stone ->; Object BullField "Grassy field" with description "A field with a gate at each end and there's a sign saying ~Beware of the Bull~.", e_to FootballField, n_to [; if (bull in location) "As you cross the field, the bull lowers its horns and charges, so you have to beat a hasty retreat."; PlayerTo(Countryside); rtrue; ], has light; Object -> bull "bull" with name 'bull', description "A massive black bull snorts at you.", has animate; Object -> sign "sign" with name 'sign' has scenery; Object BoxOffice "Box Office" with description "This is a box office, and they're advertising an Iron Maiden concert, tickets 5 pounds. This could be fun...", n_to ShoppingPrecinct has light; WeightyObject ticket "ticket" with name 'ticket', shown 0, weight 1, before [; Take: if (self.bought == 0) "You have to pay for that!"; Buy: if (fiver in player) { remove fiver; move self to player; self.bought = 1; "A ticket saying ~Iron Maiden Concert~ on it is shoved into your hand."; } else "How are you going to pay?"; Give, Show: if (location == OutsideTheatre) { self.shown = 1; "The man at the door, a heavy, closely examines the ticket, then allows you entrance."; } ] has concealed; Object OutsideHome "Outside your home" with initial [; self.initial = 0; "What a surprise! You're standing outside your home, and it looks like your mum's out, so the house will be locked."; ], description "You're standing outside your home.", n_to Lane, in_to [; if (home.forced) { PlayerTo(FrontHall); rtrue; } else "The door's locked."; ], has light; Object -> home "home" with name 'door' 'lock' 'window', forced 0, before [; Force: if (crowbar in player && self.forced == 0) { self.forced = 1; print "^Creak...Snap! Well done, you've got in.^"; PlayerTo(FrontHall); rtrue; } ], has scenery; Object FrontHall "Front hall" with description "Your own front hall, and ain't the yellow wall paper dingy? The door's behind you.", u_to Bedroom, w_to FrontRoom, out_to OutsideHome, has light; Object Bedroom "Bedroom" with description "You're in your bedroom, a small poky place at the top of the stairs, and what a mess!!!", d_to FrontHall, has light; WeightyObject -> bankbook "bank book" with name 'bank' 'book' 'bankbook' 'bank-book', weight 2, before [; Give, Show: if (location == Bank && fiver.dispensed == 0) { fiver.dispensed = 1; move fiver to player; "The lady serving reluctantly hands over a fiver."; } ]; WeightyObject -> rucksack "rucksack" with name 'rucksack' 'sack', weight 10, before [; Take: CARRYING_STRENGTH = 60; Drop: CARRYING_STRENGTH = 20; ]; WeightyObject fiver "fiver" with name 'fiver', weight 1, dispensed 0; Object FrontRoom "Front room" with description "Your front room isn't exactly Buckingham Palace, but it sure is Home Sweet Home.", e_to FrontHall, has light; WeightyObject -> videotape "videotape" with name 'video' 'tape' 'videotape', weight 6, before [; Insert: if (location == TVRoom) { remove self; "Lucky, this machine is Betamax too! The screen comes to life. It is an Iron Maiden video. It says they will only sign autographs if the booze is flowing. And then.. - Oh *@@64!$&, the video has chewed up your tape."; } else if (location == FrontRoom) "You don't have a video. Or a TV for that matter..."; else "There's nothing to put it in!"; ]; Object BuildersYard "Builders' yard" with description "A deserted builders' yard. It looks as if the builders have just vanished. They're probably having a ~coffee break~ in the Happy Hamburger.", w_to JokeStall has light; WeightyObject -> crowbar "crowbar" with name 'crowbar', weight 10; Object Bank "Bank" with description "You're in the bank where you have your account. The atmosphere is very smoky, with an undertone of people complaining about mortgages.", e_to JokeStall has light; Object Countryside "Countryside" with description "Out in the middle of the country, without a care in the world. Sheep feeding, cows lowing (and doing other things).", s_to BullField, n_to Pub has light; Object Pub "The Dandelion and Putty" with description "You're in the country pub ~The Dandelion and Putty~.", before [; StartTimer(pub_timer, 0); ], out_to [; rtrue; ], has light; WeightyObject -> vodka "bottle of vodka" with name 'vodka' 'bottle', weight 7, poured 0, before [; Drink: deadflag = 3; if (location has station) "Underage drinking in a police station is not a good idea. You are marched back to the interrogation room while a policeman calls your mum."; else "Hic! You get drunk, and are quickly arrested by a passing copper, and taken to the station while he phones your mum..."; Pour: if (location == Bar) { remove self; vodka.poured = 1; "You pour the vodka into the already alcoholic punch, and throw the bottle into the bin."; } else "That would be a waste!"; ]; Object pub_timer with time_left 0, time_out [; print "^Oh dear. Teach is having his lunch-time break and spots you. ~It's down to the police station for you,~ he says...^"; PlayerTo(InterrogationRoom); ]; Object InterrogationRoom "Interrogation room" with description "You're in a gloomy interrogation room which is rather depressing. A Sergeant is mumbling to you.", has light station; Object StationCorridorEnd "End of corridor" with description "You are at the west end of a short corridor with a door in front of you.", n_to StationCorridor, e_to [; SergeantWakesUp(); ], has light station; [ SergeantWakesUp; deadflag = 3; "^The thick arm of the law awakes and nicks you! The end of your merry little jaunt, I'm afraid."; ]; Object sergeant_timer with time_left 0, time_out [; SergeantWakesUp(); ]; Object StationCorridor "Corridor" with description "You are in a rather drab-looking corridor, typical of a police station. The atmosphere is generally depressing. On your left is a rather interesting-looking door.", e_to [; StationRoom.crouched = 0; PlayerTo(StationRoom); rtrue; ], w_to TVRoom, s_to StationCorridorEnd, has light station; Object StationRoom "Police station main room" with description "Oh-oh! The main room of the police station. The front doors are so near and yet so far. A counter runs down the middle.", crouched 0, n_to [; if (self.crouched == 0) Spotted(); else { PlayerTo(StationEntrance); rtrue; } ], w_to [; self.crouched = 0; PlayerTo(StationCorridor); rtrue; ], has light station; Object TVRoom "Television room" with description "A rather interesting room, very nicely furnished, maybe for child interrogation, with a video and T.V. in the corner.", e_to StationCorridor, has light station; Object StationEntrance "Police station entrance" with description "The exit at last!!", out_to [; PlayerTo(OutsideStation); StopTimer(sergeant_timer); rtrue; ], in_to [; Spotted(); ], has light station; [ Spotted; deadflag = 3; "^You fool. Someone saw you, so you are now in reeeeal hot water!"; ]; Object OutsideStation "Outside police station" with description "You are now just outside the police station, and on another street.", e_to SmellyAlleyEntrance, w_to StreetEnd, in_to [; Spotted(); ], has light; Object SmellyAlleyEntrance "Smelly alley entrance" with description "You are in the entrance to a dirty and very smelly back alley. Wafts of kipper mixed with cigarette smoke reach your nostrils.", w_to OutsideStation, n_to SmellyAlley, has light; Object StreetEnd "Street end" with description "You are at the end of a street where it tapers into a country track, bending to the south and towards some fields.", e_to OutsideStation, s_to WheatField, has light; Object SmellyAlley "Smelly alley" with description "You are right into the alley now, and the stench is sickening. That people can live in such a place is incredible, but you can hear faint sounds of family activity beyond the drab walls.", s_to SmellyAlleyEntrance, n_to SmellyAlleyEnd has light; Object SmellyAlleyEnd "End of smelly alley" with description "At the end of the alley, you have to make an effort to stop yourself from vomiting. There is an aroma worse than that of the local dump, and rats swarm over the litter.", s_to SmellyAlley has light; WeightyObject -> paper "piece of paper" with name 'piece' 'paper', weight 1, examined 0, before [; Examine: self.examined = 1; "You can just make out scrawled across the paper: ~Ring Ed Herr.~"; ], has legible; Object WheatField "Field of wheat" with description "You are standing in a field, surrounded by ripening wheat. In the next field to the east stands a scarecrow, and surprisingly he is doing a good job, as the only crow to be seen is a long way away, and circling anxiously.", n_to StreetEnd, e_to ByScarecrow, w_to ByBooth has light; Object ByScarecrow "By the scarecrow" with initial [; self.initial = 0; "Standing by the scarecrow, you can see why he is doing such a good job. A ghetto-blaster inside him shouts ~Stone the crows! Stone the crows!~ At this distance, you can see that the circling crow is actually a magpie, which has something in its beak."; ], description "You are standing near to the scarecrow.", w_to WheatField has light; Object -> scarecrow "scarecrow" with name 'scarecrow', muffled 0, has static; Object -> magpie "magpie" with name 'magpie' 'crow' 'bird', hit 0, before [; Take: if (self.hit == 0) "You can't jump that high!"; else "The magpie hops away out of reach."; ], has animate; WeightyObject -> -> autographbook "autograph book" with name 'autograph' 'book', weight 10, autographed 0, before [; Take: if (location ~= Bar) rfalse; if (autographbook notin player) "You don't have anything to be autographed!"; else if (Bar.drunk ~= 1) "As Iron Maiden are not very drunk, they utterly refuse to sign your autograph book."; else if (biro notin player) "Iron Maiden agree to give you an autograph, but it turns out that none of them has a pen..."; else { self.autographed = 1; "Iron Maiden all give you their autographs, signed with your biro."; } ]; Object ByBooth "By telephone booth" with description "You are standing on the road again, by a rather battered and decrepit, but seemingly working, telephone booth.", in_to Booth, e_to WheatField, n_to NarrowStreet, has light; Object Booth "Telephone Booth" with description "You are standing in the booth. It is well graffitied, but has stood the test of time well, and the phone appears to be connected.", out_to ByBooth, has light; WeightyObject -> directory "telephone directory" with name 'directory', weight 25, before [; Examine: if (paper.examined) "You examine the directory closely, but there doesn't seem to be an Ed Herr in it."; else "It's a telephone directory. Whom do you seek?"; ], has legible; Object NarrowStreet "Narrow street" with description "You are standing in a narrow street. To the north you can see an area of activity, where people are entering what appears to be a well-lit theatre of some sort.", s_to ByBooth, n_to ByBin, has light; Object ByBin "By bin" with description "You are standing by a sponsored bin in the narrow street, which from its smell would seem to be sponsored by the local sewage farm.", s_to NarrowStreet, n_to OutsideTheatre, has light; Object -> "bin" with name 'bin', before [; Examine: if (biro has concealed) give biro ~concealed; ], has scenery; WeightyObject -> biro "biro" with name 'biro' 'pen', weight 2 has concealed; Object OutsideTheatre "Outside theatre" with description "You are standing outside a theatre at the end of the street. People are entering for the Iron Maiden concert advertised, by way of the only door, guarded by a very tough-looking heavy.", s_to [; ticket.shown = 0; PlayerTo(ByBin); rtrue; ], in_to [; if (ticket.shown == 0) "The heavy at the door throws you gently across the street, to land in a heap against the wall."; else { PlayerTo(TheatreEntrance); rtrue; } ], has light; Object TheatreEntrance " " with description "You are standing in the entrance of the theatre.", e_to Bar, u_to Auditorium, out_to OutsideTheatre, has light; Object Bar "Theatre bar" with description "You are standing in the bar. There is a large bowl of punch ready for the interval on the counter.", is_interval 0, drunk 0, before [; Wait: if (vodka.poured && bar.is_interval) { self.drunk = 1; "Iron Maiden, having drunk the even more than usual alcoholic punch, are feeling pretty friendly."; } ], w_to TheatreEntrance, has light; Object Auditorium "Auditorium" with description "You are in the main body of the theatre. It has the usual red seats, and that sickly ice-cream-stained carpet always found in theatres and cinemas.", time 0, d_to TheatreEntrance, before [; Wait: if (self.time >= 0) self.time++; ], after [; if (self.time == 1) "The concert seems to be about to start. The house lights dim and the curtains go up..."; else if (self.time == 2) { self.time = -1; bar.is_interval = 1; StartTimer(end_timer, 5); "The first half is great. Either Iron Maiden is here for real, or some people can really do a good impression of them. They leap about the stage like devils, with a massive new Ernie in the background."; } ], has light; Object end_timer with time_left 0, time_out [; if (autographbook.autographed) { deadflag = 2; print "^You've succeeded in getting Iron Maiden's autographs!!!^"; } else { deadflag = 3; print "^You are a failed autograph collector!!!^"; } "^Your mum and Teach have finally caught up with you. Your escapades are so serious you will probably be expelled from your school, but your mum will not let you continue like this. While you are grounded, you could maybe write an adventure about it all..."; ]; ! Miscellaneous extensions and alterations to the library [ DeathMessage; print "You have been caught!"; ]; [ PrintWithComma s c; if (c > 0) print ", "; print (string) s; ]; [ LookRoutine c; print "^Exits: "; c = 0; if (location.n_to) PrintWithComma("north", c++); if (location.s_to) PrintWithComma("south", c++); if (location.e_to) PrintWithComma("east", c++); if (location.w_to) PrintWithComma("west", c++); if (location.u_to) PrintWithComma("up", c++); if (location.d_to) PrintWithComma("down", c++); if (location.in_to) PrintWithComma("in", c++); if (location.out_to) PrintWithComma("out", c++); if (c == 0) print "none"; print ".^"; ]; ! Grammar extensions Include "Grammar"; [ ReadSub; <>; ]; Extend 'read' first * legible -> Read; Extend 'cross' replace * 'street' / 'road' -> Cross; [ CrossSub; "There's nothing to cross here."; ]; Verb 'fire' * noun -> Fire; [ FireSub; "You can't fire that!"; ]; Verb 'wrap' 'wind' * noun 'round' / 'around' noun -> Wrap; [ WrapSub; "Are you trying to wind me up?"; ]; Verb 'hints' 'hint' * -> Hints; [ HintsSub; hints_menu.select(); ]; Extend 'force' replace * noun -> Force; Extend 'break' replace * noun -> Force; [ ForceSub; "You can't break that!"; ]; Extend 'show' replace * noun -> Show; Extend 'give' replace * noun -> Give; Extend 'insert' replace * noun -> Insert; Verb 'crouch' * -> Crouch; [ CrouchSub; if (player in StationRoom) { StationRoom.crouched = 1; "You crouch behind the counter."; } else "You feel a bit silly."; ]; Verb 'pour' * noun -> Pour; [ PourSub; "That was a poor command."; ]; ! Start the game [ Initialise; location = Classroom; ];