!% -~S !% $OMIT_UNUSED_ROUTINES=1 ! The very first lines of the main source code file for a game can contain compiler options, like the two lines above. ! -~S disables strict error checking. This is otherwise used in z5 and z8 games by default. While useful for debugging, ! it adds ~10 KB to the story file size and it makes the game slower. ! $OMIT_UNUSED_ROUTINES=1 makes the compiler remove all routines which aren't used. This can save some space. ! This game is meant to be compiled with the Inform v6 compiler and the PunyInform library Abbreviate ". "; Abbreviate ", "; Abbreviate " the "; Abbreviate "You"; Abbreviate "The"; Abbreviate "thing"; Abbreviate "you"; Abbreviate "| |"; Abbreviate "It's"; Abbreviate "dartboard"; Abbreviate "@@92"; Abbreviate "tion"; Abbreviate "logram kettlebell"; Abbreviate "'t se"; Abbreviate " th"; Abbreviate "ing"; Abbreviate " do"; Abbreviate " be"; Abbreviate " and"; Abbreviate " to"; Abbreviate " wa"; Abbreviate " ma"; Abbreviate " have"; Abbreviate "'s no"; Abbreviate " can"; Abbreviate " of"; Abbreviate "That"; Abbreviate "seems"; Abbreviate " it"; Abbreviate "_to/"; Abbreviate "ight"; Abbreviate "Paul"; Abbreviate "'t understand"; Abbreviate " some"; Abbreviate " on"; Abbreviate " pu"; Abbreviate "Inform"; Abbreviate " are"; Abbreviate " su"; Abbreviate " already"; Abbreviate " me"; Abbreviate "which"; Abbreviate " need"; Abbreviate " button"; Abbreviate " is no"; Abbreviate " mo"; Abbreviate " out"; Abbreviate " any"; Abbreviate "broom closet"; Abbreviate " with"; Abbreviate " we"; Abbreviate " co"; Abbreviate " for"; Abbreviate " lo"; Abbreviate " pr"; Abbreviate "her"; Abbreviate " ha"; Abbreviate " no"; Abbreviate "n't"; Abbreviate "e a"; Abbreviate "und"; Abbreviate " ki"; Abbreviate "ead"; Abbreviate "'s a"; Constant Story "The job"; ! Change! Constant Headline "^A PunyJam #1 game by Fredrik Ramsberg.^"; ! Change if you like Release 5; Serial "210930"; Array UUID_ARRAY string "UUID://B41662E1-57A2-4045-B14C-F554A2B549FE//"; #Ifdef UUID_ARRAY; #Endif; Constant STATUSLINE_TIME; Statusline time; Constant NO_SCORE = 0; ! Uncomment to add optional features to PunyInform !Constant DEBUG; Constant CUSTOM_ABBREVIATIONS; !Constant OPTIONAL_EXTENDED_METAVERBS; Constant OPTIONAL_EXTENDED_VERBSET; Constant OPTIONAL_PRINT_SCENERY_CONTENTS; Constant OPTIONAL_SIMPLE_DOORS; !Constant OPTIONAL_GUESS_MISSING_NOUN; Constant OPTIONAL_MANUAL_SCOPE; Constant OPTIONAL_MANUAL_REACTIVE; Constant OPTIONAL_REACTIVE_PARSE_NAME; Constant RUNTIME_ERRORS = 0; ! 0, 1 or 2. 0 = smallest file, 2 = most info #Ifv5; Constant OPTIONAL_PROVIDE_UNDO; #Endif; Constant INITIAL_LOCATION_VALUE = BroomCloset; Constant AMUSING_PROVIDED; Include "globals.h"; #Iffalse PUNYINFORM_MAJOR_VERSION == 3 && PUNYINFORM_MINOR_VERSION == 0; Message fatalerror "This is not the correct version of PunyInform for this program. Look at this line in the source code to see what version is required."; #Endif; Constant GS_ARRESTED = 3; [ DeathMessage; if(deadflag == GS_ARRESTED) print "You have been arrested"; ]; [ Amusing; "Hints you may or may not have seen that you're a diver and the entire game happens under water:^ ^* You have a knife with a stainless steel blade, which is a good choice for a diver but not for a burglar. ^* ~examine me~, ~examine suit~ (or diving suit). The colour of your suit is normal for a diver, but not for a burglar. ^* Try to take off your suit. (With increasing water pressure comes the risk of ~nitrogen narcosis~, which makes it hard to think straight.) ^* The door is heavy to open. ^* The electricity doesn't work, and you're not surprised. ^* Examine the tables. ^* Type ~swim~, or ~swim east~. ^* Try examining, pushing or drinking the water. ^* Try smelling something. ^* Try throwing something at the dartboard. ^* You lose your consciousness if you take too long, since you run out of air. ^* The only reason the piece of paper has lasted is that it happens to be laminated. ^* If you drop the note or the piece of paper and go to the pub, the item will appear there after a while, due to the current. ^* If you load Paul's weight on the mat, it's not enough. The lock mechanism is flawed, so you can figure out the needed weight by reading the message you get when pushing down the door handle, and it's 95-99 kg (97 kg of iron under water weighs like 80 kg at the surface.) ^* Standing on the mat doesn't change anything since you have neutral buoyancy, unless you are carrying weights of course. "; ]; Constant MSG_GO_CANT_GO "There's no obvious exit in that direction."; Constant MSG_SWIM_DEFAULT "Well duh! Just say which direction you want to go."; Constant MSG_SMELL_DEFAULT "You know you can't."; Include "ext_menu.h"; Include "ext_quote_box.h"; Include "ext_cheap_scenery.h"; Include "puny.h"; Extend 'swim' * noun=ADirection -> Go; Extend 'turn' * noun 'around'/'upsidedown' -> Turn; Extend 'turn' * noun 'upside' 'down' -> Turn * noun 'up' 'side' 'down' -> Turn * noun 'to' special -> SetTo; Verb 'flip' 'spin' = 'turn'; Extend 'pull' * 'out' noun -> Pull * noun 'out' -> Pull; Extend 'look' * 'under' noun -> LookUnder; Extend 'jump' * 'on' noun -> Enter; Extend 'drop' first * multiexcept 'on'/'onto' noun -> PutOn; Extend only 'push' 'press' first * 'down' noun -> Push * 'down' 'on' noun -> Push; Verb meta 'help' 'hint' 'hints' 'about' 'instructions' 'commands' 'verbs' * -> Help; Extend 'lock' * noun -> LockWithoutKey; Extend 'unlock' * noun -> UnlockWithoutKey; ! Since there is only a single lockable object in the game, we can make ! Lock/Unlock without key very simple. [LockWithoutKeySub; "That can't be locked."; ]; [UnlockWithoutKeySub; "That can't be unlocked."; ]; [ HelpSub; DoMenu(HelpItems, HelpMenu, HelpInfo); ]; [ LookUnderSub; "You find nothing of interest."; ]; [ HelpItems; print "Choose an option:^^"; print " Instructions^"; print " About this game^"; print " Game credits^"; print " Hints^"; ]; [ HelpMenu; switch(menu_item) { 0: item_width=20; item_name="Help and Information"; return 4; 1: item_width=12; item_name="Instructions"; 2: item_width=15; item_name="About this game"; 3: item_width=12; item_name="Game credits"; 4: item_width=5; item_name="Hints"; } ]; [ HelpInfo; switch(menu_item) { 1: "This is a text adventure, or an interactive fiction game. You experience a story, where you play the protagonist. You tell the game what you want to do by typing orders and the game tells you what the result is. Some possible orders are ~go east~, ~open door~, , ~examine note~, ~take the knife~ and ~put the knife in the locker~.^^ If you have never played a game like this before, I recommend you go to http://pr-if.org/doc/ and click on ~How to play Interactive Fiction~. There's a handy card there which you can keep open in your browser, or print and keep next to your computer."; 2: "The Job is a short game, written for the PunyJam #1 game jam in 2021. The jam version was severely under-implemented and under-tested, making the game pretty incomprehensible. This is a post-jam release which is hopefully a bit better."; 3: "The Job was created by Fredrik Ramsberg. It uses the PunyInform library, created by Fredrik Ramsberg and Johan Berntsson. PunyInform is based on the Inform 6 standard library and uses the Inform 6 programming language, both by Graham Nelson.^^ This game was betatested by Johan Berntsson, Rickard Nobel and Gaston Noblia.^^ RetroFan made the font PXLfont, used in the Commodore 64, Commodore 128, Commodore Plus/4 and MEGA65 versions of the game.^^ Many thanks to the people who contributed."; 4: DoMenu(HintItems, HintMenu, HintInfo); return 2; ! This means "return to the previous menu" } ]; [ HintItems; print "There are hints provided on:^^"; print " The broom closet^"; print " The pub^"; print " The gym^"; print " The kitchen^"; print " The office^"; print " A room not mentioned above^"; ]; [ HintMenu; switch(menu_item) { 0: item_width=6; item_name="Hints"; return 6; 1: item_width=16; item_name="The broom closet"; 2: item_width=7; item_name="The pub"; 3: item_width=7; item_name="The gym"; 4: item_width=11; item_name="The kitchen"; 5: item_width=10; item_name="The office"; 6: item_width=26; item_name="A room not mentioned above"; } ]; [ NextHint _dummy; #IfV5; print "^^N = next hint. "; @read_char -> _dummy; new_line; if(_dummy == 'n' or 'N') {new_line; rfalse; } #IfNot; print "^^Type N + [ENTER] for the next hint: "; _dummy = 1; @sread buffer parse; if(buffer->1 == 'n') { new_line; rfalse; } #EndIf; ]; [ HintInfo; switch(menu_item) { 1: print "You may want to read the note..."; if(NextHint()) rtrue; "But there's nothing you really have to do here."; 2: "There's nothing you need to do in the pub."; 3: "There's nothing you need to do in the gym."; 4: "There's nothing you need to do in the kitchen."; 5: print "There is one object here which can be manipulated to get you closer to the necklace."; if(NextHint()) rtrue; print "It's the dartboard."; if(NextHint()) rtrue; print "Turn it."; if(NextHint()) rtrue; print "To progress further, press down on the handle."; if(NextHint()) rtrue; print "The handle is connected to the mat."; if(NextHint()) rtrue; print "You need to put a certain weight on the mat for the handle to work."; if(NextHint()) rtrue; print "If you have the wrong weight, the handle can't be fully depressed."; if(NextHint()) rtrue; print "If you have tried a lot of different weights and you think it fails in the same way every time, you haven't been paying attention."; if(NextHint()) rtrue; "You get different messages when pushing down the handle, depending on if there's too little or too much weight on the mat."; 6: print "Now you should have arrived at the safe."; if(NextHint()) rtrue; print "You set the dials to a four-digit combination using e.g. ~set dials to 1234~. If it's the correct combination, the safe is immediately unlocked."; if(NextHint()) rtrue; print "Paul was scared he might forget the combination."; if(NextHint()) rtrue; print "So he hid the combination in his office."; if(NextHint()) rtrue; print "Look under stuff."; if(NextHint()) rtrue; print "It may not look like a number at first."; if(NextHint()) rtrue; print "Maybe it depends on your perspective?"; if(NextHint()) rtrue; print "Try turning it upside down!"; if(NextHint()) rtrue; "You need to think old numbers here."; } ]; [ TotalLoad p_obj _o _w; objectloop(_o in p_obj && _o provides weight) _w = _w + _o.weight; return _w; ]; Constant TEXT_PUB "Your friend's pub, where you used to hang out all the time. And now it has come to this. It's all so sad."; Constant TEXT_STOOL "They have black metal frames with reddish leather on top."; Constant TEXT_TABLE "Their frames are made of solid wood. The table tops are made from some laminated board, all ruined now of course."; Object LightSwitch "light switch" with name 'light' 'switch', describe [; rtrue; ], before [; SwitchOn, SwitchOff, Push: "You do. Nothing happens of course."; ], found_in [; if(location ~= SecretRoom or Street) rtrue; ], has static; Object Water "water" with name 'water', description "It's wet. There's lots of it.", before [; Take, Remove: "You could if you had a container to take it in, but it would still be utterly pointless."; Turn, Push, Pull: "You swirl your hand around a bit in the water."; Drink: "Actually, you do your best to avoid it."; ], found_in [; rtrue; ], has static scenery; Object BroomCloset "Broom Closet" with description "You're in the rather dirty broom closet of The Red Anchor. Various cleaning appliances line the walls. There's a pile of fabric in a corner.", cheap_scenery 'broom' 'closet' "It's not a nice place to hang out." 'cleaning' 'appliances' "Miscellaneous tools which were used to clean the pub.", e_to BroomClosetDoor; Object -> PileOfFabric "pile of fabric" with name 'pile' 'of' 'fabric', before [; Take: "You decide against it. You know where to find the fabric, should you need it."; ], has scenery; Object -> Note "note" with name 'note', initial "A note has been fixed to the wall with a knife.", description "Written with a broad pen is ~RETURN WITH THE NECKLACE, OR DON'T RETURN!~ You're guessing Ricky wrote it.", after [; Take: if(Knife hasnt moved && self hasnt general) { ! Use the general attribute to say we've already pulled ! the note from the wall, so we don't print this twice. give self general; "The knife rips a long hole in the note as you pull the note from the wall."; } ]; Object -> Knife "knife" with name 'knife', description [; if(self hasnt general && self hasnt moved) { give self general; print "Hey, that looks a lot like your knife. It is your knife!"; } else print "It's your trustly old knife."; " Black handle, stainless steel blade, and just the perfect size."; ], describe [; if(self hasnt moved) { if(Note hasnt moved) { ! Knife and note haven't moved. Knife is mentioned in ! description of note rtrue; } ! The knife hasnt been moved but the note is gone. "^The knife is still deeply embedded in the wall."; } ! The knife has been moved. Now it should just be described as a ! regular object rfalse; ], before [; Pull: if(self hasnt moved) <>; ], after [; Take: if(Note hasnt moved && Note hasnt general) { move Note to player; update_moved = true; "You pull out the knife and get the note that's impaled on it."; } ]; Object BroomClosetDoor "broom closet door" with react_before [; if(action == ##Go && self hasnt open && ((location == BroomCloset && selected_direction == e_to) || (location == Pub && selected_direction == w_to))) { print "(first opening the door)^"; keep_silent = true; ; keep_silent = false; if(self hasnt open) rtrue; ! Failed, don't proceed new_line; } ], after [; Open: "Opening the door is incredibly heavy at first, but gets a lot easier when there's a crack wide wide enough to see through."; ], parse_name [ w1 w2 w3; w1 = NextWord(); w2 = NextWord(); w3 = NextWord(); if(w1 == 'broom' && w2 == 'closet' && w3 == 'door') return 3; if(w1 == 'closet' && w2 == 'door') return 2; if(w1 == 'door') return 1; ], when_open [; if(self in BroomCloset) "You can see the pub through the door opening to the east."; "The door to the west is open, revealing a broom closet."; ], when_closed [; if(self in BroomCloset) "The pub lies beyond the closed door to the east."; "There's a closed door to the west."; ], found_in BroomCloset Pub, door_dir (e_to) (w_to), has static door openable reactive; Object Pub "Pub" with description "This used to be your local watering hole. Paul, the owner, is also a good friend of yours. A number of high tables are screwed to the walls, with bar stools in front of them. The oak counter sits along the north wall. There's no activity behind the counter tonight though. The light switch is next to the counter, right beside the doorway to the kitchen. The gym lies to the east, while the exit is to the south.", cheap_scenery 'pub' 'room' TEXT_PUB 'red' 'anchor' TEXT_PUB 1 'stool' TEXT_STOOL 'bar' 'stools' TEXT_STOOL 1 'table' TEXT_TABLE 'high' 'tables' TEXT_TABLE 'oak' 'counter' "Such a beautiful counter. You haven't really stopped to admire it before.", w_to BroomClosetDoor, e_to Gym, n_to Kitchen, s_to [; if(Necklace in player) return Street; "You don't dare to go back without the necklace."; ]; Class KettleBell with #IfV5; name 'kettle' 'bell' 'bells//p' 'kettlebell' 'kg' 'kilo' 'kilos' 'kilogram' 'kilograms', #IfNot; parse_name [ _i; while(NextWord() == 'kettle' or 'bell' or 'bells//p' or 'kg' or 'kilo' or 'kilos' or 'kilogram' or self.&name-->0 or self.&name-->1) _i++; return _i; ], #EndIf; weight 0, description "You know the kind. Made of iron, with a layer of a rubbery material on it.", before [; Take, Remove: if(TotalLoad(player) + self.weight > 50) "Your load is too heavy."; ], has reactive; Object Gym "Gym" with description "The Gym is really only big enough for one or two people. You remember when Paul threw out all the old stuff that had been tucked away here over the years and converted the room to a gym, to assist in his weight loss. The regulars could use it too, and you for one often did just that. The pub lies to the west.", cheap_scenery 'gym' 'room' "This room used to smell of sweat. Not now, of course.", w_to Pub; Object -> Locker "locker" with name 'big' 'steel' 'locker', when_open [; print "A black locker stands in a corner. "; ; ], when_closed "A closed black locker stands in a corner.", description "It's a big steel locker.", has static container openable; KettleBell -> -> Bell2 "two kilogram kettlebell" with weight 2, name '2//' 'two'; KettleBell -> -> Bell5 "five kilogram kettlebell" with weight 5, name '5//' 'five'; KettleBell -> -> Bell10 "ten kilogram kettlebell" with weight 10, name '10' 'ten'; KettleBell -> -> Bell20 "twenty kilogram kettlebell" with weight 20, name '20' 'twenty'; KettleBell -> -> Bell30 "thirty kilogram kettlebell" with weight 30, name '30' 'thirty'; KettleBell -> -> Bell40 "forty kilogram kettlebell" with weight 40, name '40' 'forty'; KettleBell -> -> Bell50 "fifty kilogram kettlebell" with weight 50, name '50' 'fifty'; Object Kitchen "Kitchen" with description "Just the kind of kitchen you typically find in small pubs - it has what's needed to serve a burger, fish'n chips and what not. You get a glimpse of the office through the doorway to the west, and the pub lies to the south.", cheap_scenery 'kitchen' 'room' "A bit worn, but not terribly so. Paul and his staff always seemed to enjoy working here.", s_to Pub, w_to Office; Object Office "Office" with name 'hatch' 'compartment' 'glue', description [; print "You've been here a few times before, with Paul. There's a big desk close to the west wall, and a heavy chair behind it. There's a dartboard on the north wall, and a square black rubber mat just in front of it. "; if(DoorHandle has general) "There are doorways leading north and east."; "A doorway leads east."; ], cheap_scenery 'office' 'room' "It's a neat and tidy office. At least you can see it used to be.", e_to Kitchen, n_to [; if(DoorHandle has general) return SecretRoom; return 0; ]; Object -> Desk "desk" with name 'big' 'desk', description "It's a quite impressive desk.", before [; Push, Pull, Turn, Take: "The desk is incredibly heavy. You can't move it at all."; LookUnder: if(CodeNote in nothing) { move CodeNote to player; scope_modified = true; update_moved = true; "Oh, you find a piece of paper attached with some sticky substance under the desk! You take it."; } ], has static scenery supporter enterable; Object -> -> Photo "photo" with name 'framed' 'frame' 'photo', description "It's a framed photo of Paul, you and some of the other regulars at the pub. Paul looks like he just won a million dollars. You remember the occasion - Paul wanted to celebrate reaching his goal weight after losing forty kilograms, which was actually a third of his original weight. That was six months ago, and he hasn't gained a kilogram since.", before [; Remove: if(second == self) <>; Open: "The frame seems to be sealed shut. Better not waste any more time on it."; ]; Object -> Chair "chair" with name 'heavy' 'chair', description "It's Paul's heavy, comfortable chair.", has static scenery supporter enterable; Object -> Dartboard "dartboard" with name 'dartboard' 'dart' 'board', description "Standard dartboard, and of course it's mounted at the correct height. Along the outer edge someone has written: ~PROPRIETE DU CAPITAINE LOUI~", before [; ThrownAt: move noun to Office; "Standing at the correct distance, you throw ", (the) noun, " but, as expected, you fail to hit the board."; Search: BlackMat.step_on(); "You find circles, numbers etc - the stuff you'd expect to find on a dartboard."; Open, Close: "You'd have to describe just how you mean to do that."; Turn: BlackMat.step_on(); if(self hasnt general) { give self general; move DoorHandle to Office; BlackMat.number = 100; ! Don't print any more clue messages scope_modified = true; "As you turn the dartboard ninety degrees counterclockwise, a small hatch you hadn't noticed, set in the wall just below the dartboard, opens, revealing a door handle!"; } "The dartboard seems to be stuck in its turned position."; Pull, Take: BlackMat.step_on(); "The dartboard flexes a little. Weirdly enough, it feels like it's only attached to the wall at the very center of the board."; Push: BlackMat.step_on(); "The dartboard doesn't move at all."; ], has static scenery; Object -> BlackMat "black mat" with name 'square' 'black' 'rubber' 'mat', description [; if(Dartboard hasnt general && self.number < 3) "A mat of a kind that's common below dartboards, to protect the floor."; <>; ], rattle_counter 0, rattle [ _r; _r = self.rattle_counter++; if(_r == 0) ", and there's a faint metallic rattle, but you can't tell where it comes from."; ", and there's that metallic rattle again."; ], before [; Cut: if(Knife in player) <>; "You don't have anything to cut it with."; Attack: if(second == Knife) "You make some cuts into the mat, but it stays firmly attached to the floor."; Rub, Push, Pull, LookUnder, Take: give self general; "The mat seems glued to the floor, but also it moves a little when you tug at it with your hand. Or it's more like a piece of the floor is loose and the mat is glued to that piece."; Enter: if(player in self) <>; ], react_before [; Jump: if(player in self) { print "The mat wiggles a bit"; self.rattle(); rtrue; } ], after [; Enter: print "The mat wiggles a bit"; self.rattle(); rtrue; Receive: if(noun provides weight && noun.weight > 9) { print "The mat wiggles a bit"; self.rattle(); rtrue; } ], number 0, step_on [ _step; if(Dartboard has general) rtrue; ! The passage is already open _step = ++self.number; if(_step < 3) rtrue; switch(_step) { 3: if(self has general) "As you happen to put your foot on the black mat in front of the dartboard, you notice that the mat, or rather the mat and the piece of floor beneath it, move a little as you step on the mat."; "As you happen to put your foot on the black mat in front of the dartboard, you could have sworn that the mat moved a little, as if it was on wheels or something. But surely you must have been mistaken.^"; 5: "There it is again! The mat moved a little, but if anything you think it sank into the floor, every so slightly. And some kind of noise came from the wall where the dartboard hangs."; } ], has static scenery supporter enterable reactive; Object DoorHandle "door handle" with name 'door' 'handle', initial "Just below the dartboard is a small compartment in the wall, featuring a door handle.", description "Looks like a perfectly normal door handle. Like a lever you press down on to open a door, only there's no door here.", before [ _w; Take: "It seems quite securely fixed to the wall. "; Pull: "It won't budge at all when you tug at it."; Open, Push: if(self hasnt general) { _w = TotalLoad(BlackMat); ! Ideal weigth is 97 kg (= 80 kg at surface) if(player in BlackMat) _w = _w + TotalLoad(player); if(_w < 95) "You can't push it down more than about a centimeter before it stops and won't go any further."; if(_w > 99) "The door handle won't budge at all."; give self general; "As you push down on the handle, a large panel in the wall next to the dartboard slides aside. There is now an opening into a dark room to the north."; } "Nothing happens."; ], has static; Object SecretRoom "Secret Room" with description "A small space, only about two by two meters. The walls are black. A doorway leads south.", cheap_scenery 'wall' 'walls' "Looks painted. In fact, it looks like someone who wasn't very good at painting painted it, perhaps Paul himself.", s_to Office; Object -> Safe "safe" with name 'safe', description "It's pretty big and must weigh a lot. It's probably screwed to the floor or the wall as well.", when_open [; print "There is an open safe at the north wall, with a set of dials and a button on the door. "; ; ], when_closed "A closed safe stands at the north wall. It has a set of dials and a button on the door.", before [ _r; UnlockWithoutKey: if(self hasnt locked) "It doesn't seem to be locked."; "You may need to use the dials and the button to do this."; Unlock: if(self has locked) "There's no keyhole. Maybe the dials and button have something to do with it."; LockWithoutKey: if(self has open) "The safe is currently open."; if(self has locked) "The safe is already locked."; give self locked; while(_r == 0 or 1009) _r = random(9999); Dials.entered = _r; "Using the dials and the buttont, you somehow manage to lock the safe."; Lock: "The safe doesn't have a keyhole."; ], add_to_scope Dials Button, has static container openable lockable locked reactive; Object -> -> Necklace "necklace" with name 'necklace', description "It's absolutely beautiful, and no doubt quite valuable."; Object Dials "set of dials" with name 'set' 'of' 'dials' 'dial', entered 0, description [ _comb; print "It's a set of four dials, each showing numbers from 0 to 9. They're currently set to "; _comb = self.entered; print _comb / 1000; print (_comb % 1000) / 100; print (_comb % 100) / 10; print (_comb % 10), ".^"; ], before [; Turn, Push, Pull, Open: "To unlock the safe, try e.g. ~set dials to 1234~."; SetTo: if(parsed_number < 0 || parsed_number > 9999) "The dials can be set to a number between 0 and 9999."; self.entered = parsed_number; print "You set the dials and press the button. "; <>; ], has static; Object Button "button" with name 'button', description "It's a heavy duty metal button that protrudes a good centimeter from the door. It's placed just to the right of the dial.", before [; Push: if(Dials.entered == 1009) { if(safe has locked) { give Safe ~locked; "A loud CLICK is heard from the safe."; } "The button can be fully depressed. Nothing happens."; } "The button can hardly be depressed at all."; ], has static; Object Street "Street" with description "You are in the street just outside the Red Anchor. The street leads east and west. You can't see very far, but you can make out the outlines of the small church to the east and the public library down the street to the west.", cheap_scenery 'small' 'church' "That's where you used to go to church, before. It may not have looked like much on the outside, but it was beautiful on the inside." 'public' 'library' "It was a great small town library really. The staff were very knowledgable and keen on helping people find what they wanted." 1 'pub' TEXT_PUB 'red' 'anchor' TEXT_PUB 1 'fish' "You can't see any fish right now.", number 0, each_turn [ _n; _n = self.number++; switch(_n) { 3: "^A fish swims by."; 5: "^You hear an engine revving up above."; 10: deadflag = GS_ARRESTED; "^The engine above revvs up and speeds off in the distance. Soon you're out of air and have to ascend. You are greeted by the police who pull you up into their boat."; } ], before [; Swim: <>; ], n_to Pub, u_to Boat, cant_go "You don't really have the time to look around now. It's time to go."; Object Boat "Boat" with description "As you reach the surface, the crew in the boat pull you out of the water. Ricky and the other divers are already in the boat. Ricky grabs the necklace, gives you a pat on the back and starts the engines. ^^You feel horrible about stealing the necklace belonging to Paul's wife, but at the same time you know you were forced to do it. Paul's been struggling with the insurance company over the last weeks, ever since the dam burst and flooded this part of town. You can only hope he gets fair compensation for his pub. ^^You notice a police boat approaching, but Ricky assures you they'll never catch up. With roaring engines and lights out, you head off. It seems you have made it.", after [; deadflag = GS_WIN; ]; Array codenote_quote --> 4 26 " @@92 / | | | " " @@92/ | | | " " /@@92 | | /@@92 | " " / @@92 | |/ @@92| "; Array codenote_quote_flip --> 4 26 " |@@92 /| | @@92 / " " | @@92/ | | @@92/ " " | | | /@@92 " " | | | / @@92 "; Object CodeNote "piece of paper" with name 'laminated' 'piece' 'of' 'paper', orientation 0, description [ _x _i; _i = 0; _x = codenote_quote; if(self.orientation) _x = codenote_quote_flip; print "It's a laminated piece of paper. Someone has scrawled on it with a pen:"; #Ifv5; new_line; @read_char _i; #Endif; QuoteBox(_x, true); ], before [; Turn: self.orientation = 1 - self.orientation; "You turn it around."; ]; Object Flashlight "flashlight" with name 'flashlight' 'lamp', description "It's your trusty flashlight. It has never failed you.", before [; SwitchOff: "You made sure the batteries were fully charged before leaving home. There is no need to conserve power."; ], has light switchable on; Object Suit "suit" with parse_name [ _w1; _w1 = NextWord(); if(_w1 == 'suit') return 1; if(_w1 == 'dive' or 'diving' && NextWord() == 'suit') return 2; ], description "You've had it for years and you had another one just like it before that. Fits you perfectly. It's bright orange, which may not be perfect for this kind of job, but this is not the kind of job you usually do either.", before [; Push, Pull, Turn: "You could play with your suit all day, but you have more pressing matters to deal with."; Take, Remove, Disrobe: "You've seen some guys lose it on the job due to the pressure, but you usually manage to think straight. You keep the suit on."; ] has reactive static worn; Object Death with time_left 0, time_out [; if(Necklace in player) { if(player in Street) { print "^You suddenly feel you're running out of air, and you decide to ascend.^^"; <>; } else { deadflag = GS_DEAD; "^You discover too late that your time is up. Your head grows dim and you can't figure out what to do. You won't make it out in time."; } } deadflag = GS_DEAD; "^You suddenly notice that you've run out of time, but you know you can't return without the necklace. You ponder your options, but your head keeps getting dimmer, until you start to lose consciousness. A warm, calm feeling ensues."; ]; Object Current "current" with float_object [ p_obj _ceil _parent _dest; if(p_obj hasnt moved || p_obj in Pub || random(100) > 25) rtrue; _ceil = TouchCeiling(p_obj); if(_ceil == location) rtrue; ! Don't move while the player watches if(_ceil == BroomCloset && BroomClosetDoor has open) _dest = Pub; if(_ceil == Kitchen or Gym) _dest = Pub; if(_ceil == Office) _dest = Kitchen; if(_ceil == SecretRoom) _dest = Office; if(_dest) { _parent = parent(p_obj); if(_parent ~= _ceil) move p_obj to parent(_parent); else move p_obj to _dest; scope_modified = true; } ], daemon [; if(~~IndirectlyContains(player, Note)) self.float_object(Note); if(~~IndirectlyContains(player, CodeNote)) self.float_object(CodeNote); ]; [ PlayerAddToScope; PlaceInScope(Suit); ]; [Initialise _min; _min = 120; lookmode = 2; move Flashlight to player; player.add_to_scope = PlayerAddToScope; give player reactive; player.description = "Not too shabby. You've got the same old suit on, the one you always use for work."; StartTimer(Death, _min); StartDaemon(Current); SetTime(24 * 60 - _min, 1); print "^^Sure, your job has taken you on all sorts of trips and you've done some weird stuff, I mean you've got to pay the bills right? But tonight's assignment is one you didn't ask for.^^ Business has been slow lately, and if it hadn't been for Ricky lending you some money a few months ago, you would've had to close the firm. When Ricky showed up at your house the other day, he wasn't exactly asking if you wanted the job - it was more of an order.^^ And now you're here. You were busy searching in the broom closet, thinking you were alone, when you got a push from behind and fell over. Whoever pushed you also left a message...^^ (Type HELP for game information.)^^ "; ];