!% -~S !% $OMIT_UNUSED_ROUTINES=1 !% $TRANSCRIPT_FORMAT=1 !% $MAX_ABBREVS=96; !% $MAX_DYNAMIC_STRINGS=0; ! Writing todos ! TODO : REREAD THE WHOLE TEXT AND CAREFUL WITH THE SEMICOLONS ! TODO : not enough weather related talk: big blue sky, sun that burns your skin a bit (to hint at drying stuff), nice chill wind Constant Story "TRISTAM ISLAND"; Constant Headline "^By Hugo Labrande.^"; Release 4; Constant STATUSLINE_SCORE; Statusline score; !Constant IS_DEMO; !Constant DEBUG; !Constant DEBUG_PARSEANDPERFORM; !Constant DEBUG_PARSEPATTERN; !Constant DEBUG_PARSETOKEN; !Constant DEBUG_CHECKNOUN; !Constant DEBUG_GETNEXTNOUN; !Constant DEBUG_SCOPE; Constant OPTIONAL_MANUAL_SCOPE; Constant CUSTOM_ABBREVIATIONS; !Switches f; ! see how useful abbreviations are ! 155196 sans abbrev ! PunyInform : 142396 bytes !Abbreviate ". " ", " "You " "'t " "That's not something you can " "_to/" "nothing" "That " "close" "already" "(which is " " is ""thing" "ed." "t's" "lock" "rea" "witch" "can" "open" "empty" "You" "t first." "rrying" "contain" "when_" "that." "t wa" "But you" "t of" "Tha" "Res" " the " "all" "yourself" "_to" "ter" "here" "able" "ing" "are" "have" "and" "unexpected" "ion" "side" "talk" "see" "sco" "ake" "ame" "urn" " to " "ore" "the" "tha" "you" "ome" "t i" "off" "rin" "pec" "on." "ste"; ! Inform -u : 139036 bytes !Abbreviate ". " ", " " the " "You" "The" "ing" "and" "you" "This" "ther" "all" "is " "the" "'t " "nd " "to " "'s " "re " "that " "ould " "ight " "ll " "; it " "r a" "with " "of " "probably " "have " "ut " "look" "ds " "which " "lbatross " "platform" "It " " a " "here" "white" "ght" "wit" "ook" "abl" "ator" "nder" "while" "house" "door" "s it" "some" "d i" "already" "air" "our" "side" "for" "any" "close" "ver" " on" " th" " wa" " do" " like" "rea"; ! My python script : 135744 bytes !Abbreviate " the " "You " " you" " and " " to " "ing " ", " "The " " is " "here" "n't " ". " " of" " a " " th" "island" "ould " "ight" " are " "ther " "all" "; " "This" "probably " " in" " it" "ing" " on" "with" "albatross" "look" " to" " for" "door" "'s " "platform" "and" "have" "house" "ter" " like" "You'" "already" " see" " some" "re " "which" "ed " "ough" "very " " can" "tion" "out" "side" " be" "but" "close" "white " "able" "ly " " --" "at " " back" "fish" ; ! 96 optimal abbreviations, thanks heasm Abbreviate "manage to " " from the " "generator" " you can " "albatross" " doesn't " "There is " "probably " " rather " " on the " " towards" " to the " " at the " "platform" "already " " of the " " in the " " a few " " around" ", which" " your " ". You " "ou're " "small " "white " ". The " "don't " "island" " this " " with" "ould " " are " "have " " you " ", and" " some" ", but" " that" "cliff" "This " "house" " and " " the " " like" " what" "thing" " back" "close" "fish" " for" "ight" "ence" " of " "n't " "here" "The " " is " "look" "ing " "door" "You " "tion" " you" " to " ". It" "not " "side" "able" "ough" "ent" " a " "re " "ood" "ind" " be" "rea" "ed " "the" "est" "ly " "ver" "out" " --" "'s " "ing" " it" "see" " on" "and" " in" "all" "ter" "ear" ". " ", " ";"; Constant OPTIONAL_FULL_DIRECTIONS; ! northeast and such Constant MAX_SCORE = 150; !Constant RUNTIME_ERRORS = 2; ! TODO: remove in production, save 1600 bytes!! Constant MAX_FLOATING_OBJECTS = 32; Constant MAX_SCOPE = 56; ! This speeds up the game, but put the "reactive" attribute in the each_turn/react_before/react_after objects Constant OPTIONAL_MANUAL_REACTIVE; ! This makes less code for simple doors Constant OPTIONAL_SIMPLE_DOORS; ! Initial location - needed to be ok for the Gameboy interpreter Constant INITIAL_LOCATION_VALUE=Immaculatebeach; ! You only have two hands + 1 pocket Constant MAX_CARRIED = 3; Constant SACK_OBJECT = backpack; ! Don't define globals before including globals.h, or it wont work on some terps! Include "globals.h"; ! My globals ! This replaces flags because it saves space: if(var) takes 3 bytes, if(FlagIsSet(flag)) takes 9 bytes ! You can do that if you dont have too many variables; Inform uses the 240 global variables anyway, so declaring one doesn't save any space ! Did we go up the island yet? Global F_ACT2_STARTED = 0; ! Did we see Tristam Island yet? Global F_TRISTAM_DISCOVERED = 0; ! Have we eaten fish yet Global F_ATE_SOMETHING = 0; ! Have we slept yet Global F_SLEPT = 0; ! Have we climbed the cliff via the platform yet Global F_CLIMBED_CLIFF = 0; ! Have we scraped a bit and realized it was a staircase Global WE_KNOW_IT_IS_STAIRS=0; ! Have we climbed the steps yet Global F_CLIMBED_STEPS = 0; ! Have we seen the tower through the trees from the ocean Global TOWER_SEEN_THROUGH_TREES = 0; ! The fire has been arranged with dry wood; ready to burn Global FIRE_IS_READY = 0; ! Is the fish elevator up the cliff, or down? Global FISH_ELEVATOR_UP = 0; ! this is faster than figuring out the parent of the parent / visibility ceiling ! Has the albatross already pestered us once and stole our fish? Global ALBATROSS_ALREADY_STOLE=0; ! Have we gathered firewood to cook the fish Global ALREADY_GOT_FIREWOOD=0; ! Have we smashed the woodshop window yet Global F_WOODSHOP_SMASHED = 0; ! Have we smashed the "bits and bobs" shop yet Global F_SHOP_SMASHED = 0; ! Have we smashed the window of the house by the cliff for fun yet Global F_HOUSE_CLIFF_SMASHED = 0; ! Have we taken the pin out of the hinges of the crude door Global F_CRUDE_DOOR_OUT = 0; ! Have we climbed over the fence using the tree Global F_CLIMBED_TREE = 0; ! Have we found the hole in the fence (by looking at it a second time or searching the bush) Global F_FOUND_HOLE_IN_FENCE = 0; ! Have we crawled through the hole in the fence Global F_CRAWLED_IN_HOLE = 0; ! is the fire at the scenic view on Global F_SCENIC_FIRE = 0; ! Have we fixed the ladder Global F_LADDER_FIXED = 0; ! Have we searched the grass and found the guard key Global F_GRASS_SEARCHED = 0; ! is the tank full of melted cooking oil Global F_TANK_FULL = 0; ! Have we started the generators Global F_GENERATORS_ON = 0; ! How hard are the generators working Global generators_load = 100; Constant LOW_POWER 81; ! 10 for jukebox, 5 for pub landlord light, 5 for light in insidehouses, 15 for the fridge ! Have we entered the white mansion Global F_ACT3_STARTED = 0; ! Have we entered the underground lab Global F_ACT4_STARTED = 0; ! Is the elevator down Global F_ELEVATOR_DOWN = 0; ! need to define this here but it's only needed later Global room_shore; Global vecteur_normal; Global sandbankDepth; Constant TRISTAM_SANDBANK_DEPTH 8; Constant FISHES_VECTEUR_NORMAL 2; !Constant F_TRISTAM_NAME_KNOWN = 10; !Constant F_ISLAND_NAME_KNOWN = 11; !Constant F_PULLED_ROPE_TIRED = 15; !Constant F_CLEARED_STEP_TIRED = 16; !Constant F_TOWER_SEEN = 17; !Constant F_CODE_READ = 18; !Constant F_FIXED_PIPE = 19; !Constant F_CLEANED_BUCKET = 20; !Constant F_FIXED_RADIO = 21; !Constant F_FOUND_REPORT_CLEAN = 22; !Constant F_FOUND_REPORT_CRUMPLED = 23; !Constant F_COOKING_OIL = 25; !Constant F_MATCHES_DONE = 26; !Constant F_TRENCHES_SEARCHED = 27; !Constant F_BEHIND_FENCE = 28; !Constant F_CLIMBED_TREE = 29; !Constant F_WORCESTERSHIRE = 30; !Constant F_MARMITE = 31; ! Fix for the gameboy interpreter Constant MSG_PROMPT 1018; Constant MSG_PUSHDIR_DEFAULT "You're not sure what this would accomplish."; Constant MSG_SURVIVAL "This would seriously diminish your chances of survival."; Constant MSG_UNTIE "You cannot untie this."; Constant MSG_PLATFORM_SHORT_DESC "The platform against the cliff looks a bit like a bucket, and a very long rope is tied to its metal handle, up to a pulley mechanism."; Constant MSG_YOU_TIED_THE_ROPE " You tied the other end of the rope to the platform's railing so it would stay up, in case you need to use it again."; Constant MSG_CLIFF_SAFELY "You manage to climb up the cliff safely; you tie the rope to the railing of the platform.^"; Constant MSG_PLATFORM_IS_ALREADY_UP "The platform can't go any higher than this."; Constant MSG_PLATFORM_IS_ALREADY_DOWN "The platform is already as low as it can be."; Constant MSG_BURN_DEFAULT "This dangerous act would achieve little."; Constant MSG_EAT_INEDIBLE 1025; Constant MSG_ALBATROSS_VICTORY_LAP "swoops in and snatches the fish out of your hand. It's too late -- it already gulped the fish down. The albatross lets out a satisfied squawk, and flies around you energetically, like a victory lap of sorts."; Constant MSG_TOO_IMMENSE 1027; Constant MSG_OCEAN_WATER "Ocean water is hardly drinkable."; Constant MSG_FELL_A_TREE "You doubt you could fell a tree with the tools you have."; Constant MSG_NOT_SOMETHING_YOU_CAN_VERB 1030; Constant MSG_FILL_NO_WATER "You're not sure how to accomplish that."; Constant MSG_DONT_GET_WHAT_TO_DO 1032; Constant MSG_TIE_DEFAULT 1033; Constant MSG_INSERT_ITSELF "You can't put something inside itself."; Constant MSG_PUTON_ITSELF "You can't put something on itself."; Constant MSG_PUT_IN_SEA "You'd rather not release your meager possessions into the sea."; Constant MSG_SANDBANK_DESC "A submerged sandbank extending southwest makes it so you can walk further into the ocean without getting too wet."; Constant MSG_COVE_DESC "This small cove is made of a steep beach made of wet sand; the waves are a little more turbulent here, and there seems to be movement deeper in the waters."; Constant MSG_UNTOUCHABLE "This is untouchable."; Constant MSG_NOT_VERY_GOOD_AT_CLIMBING "You're not very good at climbing"; Constant MSG_WRONG_LOCATION "You are in the wrong location to attempt this."; Constant MSG_YOU_DECIDE_CLOSER_LOOK "You decide to go take a closer look at "; Constant MSG_AND_HEAD ", and head "; Constant MSG_LISTEN_HEADPHONES 1034; Constant MSG_BURSTING_WITH_ENERGY " bursting with energy and ready to explore the island."; Constant MSG_BIGOBJECT_PARSING_ERROR "(parsing error)"; Constant MSG_TAKE_NO_CAPACITY 1035; Constant MSG_CANT_LOOK_THROUGH "You cannot look through this."; Constant MSG_UNCOVERING_STAIRS " You reckon you have time, and you don't have to finish today; so you sit down and start clearing the dirt off the steps. There's a few inches of soft mud covering the small steps, but with some patience, and your sturdy fishing knife to carve out some of the mud, you manage to clear enough mud to step on the next step. You continue methodically uncovering them, one by one. On the morning of the second day, you finally reach the "; Constant MSG_CALL_FOR_HELP_REPEAT 1036; Constant MSG_FAR_TOO_LARGE "This is far too large"; Constant MSG_ONLY_WAY_IS_OUT ". The only way is out"; Constant MSG_INCREDIBLY_DESCVILLAGE "Incredibly, there are a dozen buildings here, of various sizes and all fairly recent-looking, the tallest one being the radio tower at the southwest, and the most imposing one being the tall, white house looming in the backdrop, to the east."; Constant MSG_DROP_ROD_ALBATROSS_PERKS_UP "You kneel to carefully drop your fishing rod. The albatross perks up; you look at your rod for just one second, and it "; [ LibraryMessages p_msg p_arg_1 ; ! p_arg_2 not used, it's ok if it's not featured here if it's never called with 3 args anyway ! saves 2 bytes over a switch if (p_msg == MSG_PROMPT) { print ">";rtrue; } if (p_msg == MSG_TAKE_NO_CAPACITY) { print "You are carrying too many things already"; if (backpack in player) {print ", and you can't put any of them in the backpack";} "."; } if (p_msg == MSG_EAT_INEDIBLE) { if (F_ACT2_STARTED) {print "T";} else { print "You're worried about not finding enough food to survive, but t"; } "his is definitely not edible."; } if (p_msg == MSG_TOO_IMMENSE) { print "This is far too immense to be "; rtrue; } if (p_msg == MSG_NOT_SOMETHING_YOU_CAN_VERB) { PrintMsg(MSG_OPEN_YOU_CANT, p_arg_1); rtrue; } ! that's not something you can verbword ! TODO replace this with OPEN_YOU_CANT in the final code to save 10ish bytes if (p_msg == MSG_TIE_DEFAULT or MSG_DONT_GET_WHAT_TO_DO) { "I don't understand what you want to do with ", (the) noun, "."; } #ifndef IS_DEMO; if (p_msg == MSG_LISTEN_HEADPHONES) { if (Wireinalockedlocker in radio) {"You can hear some static in the headphones.";} else {print_ret "T", (string) MSG_NO_NOISE_HEADPHONES; } } if (p_msg == MSG_CALL_FOR_HELP_REPEAT) { print "You push the microphone's button and call for help repeatedly on the frequency "; PrintFreq(); print ", but you get no response"; } #endif; ! switch(p_msg) { ! MSG_PROMPT: print ">"; p_arg_1 = p_arg_2; rtrue; ! MSG_EAT_INEDIBLE: if (F_ACT2_STARTED) {print "T";} else { print "You're worried about not finding enough food to survive, but t"; } "his is definitely not edible."; ! MSG_TOO_IMMENSE: print "This is far too immense to be "; rtrue; ! MSG_NOT_SOMETHING_YOU_CAN_VERB: PrintMsg(MSG_OPEN_YOU_CANT, p_arg_1); rtrue; ! that's not something you can verbword ! TODO replace this with OPEN_YOU_CANT in the final code to save 10ish bytes ! MSG_TIE_DEFAULT, MSG_DONT_GET_WHAT_TO_DO: print_ret "I don't understand what you want to do with ", (the) noun, "."; ! } ]; ! ==================================== ! Rank ! ==================================== [ PrintRank; print ", thus giving you the rank of: "; if(score== 150) "Nuclear Investigator."; if(score>= 100) "Curious Explorer."; if(score>= 50) "Robinson Crusoe."; "Castaway."; ]; ! ===================================== ! Special thing to not count coins in the capacity ! ===================================== #ifndef IS_DEMO; Replace _AtFullCapacity; [ _AtFullCapacity p_s _obj _k; if (p_s == player) { objectloop (_obj in p_s) if (~~(_obj has worn || _obj ofclass Coin)) _k++; } else _k = children(p_s); #IfDef SACK_OBJECT; if (_k < ObjectCapacity(p_s) || (p_s == player && _RoomInSack())) rfalse; #IfNot; if (_k < ObjectCapacity(p_s)) rfalse; #EndIf; ]; #endif; ! ===================================== ! Manage darkness's scope and restore ability to examine in the darkness ! ===================================== Attribute semidark; #Ifdef IS_DEMO; Object odd with semidark_description "", has semidark; #Endif; ! add any object in location that is semidark [InScope x; if(location == thedark && real_location has semidark) objectloop(x in real_location) { if(x has semidark) { PlaceInScope(x); ScopeWithin(x); } } rfalse; ]; [GamePreRoutine; ! Examine normally doesn't work in dark locations. We want it to work ! in semidark locations though. if(location == thedark && action == ##Examine && real_location has semidark) { if(noun provides description) { PrintOrRun(noun, description); rtrue; } else { PrintMsg(MSG_EXAMINE_NOTHING_SPECIAL); rtrue; } } rfalse; ]; ! still list objects (for instance the ones you dropped) if they are semidark [LookRoutine x; if(location == thedark && real_location has semidark) { objectloop(x in real_location) { give x ~workflag; ! game design choice : i want the player's former possessions to still be listed: he put them there, he knows where to find them ish if(x has semidark && x hasnt scenery or concealed or door || x has moved) !if(x has semidark && x hasnt scenery or concealed or door) give x workflag; } if(PrintContents("^You can barely make out ", real_location, true)) " here."; } ]; [DescribeTheDark; if(real_location has semidark) { if(real_location provides semidark_description) { PrintOrRun(real_location, semidark_description); rtrue; } else { PrintOrRun(real_location, description); rtrue; } } "It's too dark to see here."; ]; [ TheDarkShortName ; if (real_location has semidark) { print (name) real_location; rtrue; } rfalse; ! ? I mean it's fine, all my dark locations have semidark ]; Include "puny.h"; ! ============================================================================ ! Extra grammar [ BlowSub ; "You can't usefully blow in ", (the) noun, "."; ]; Verb 'blow' * held -> Blow * 'in'/'into' held -> Blow; [ PlaySub ; PrintMsg(MSG_NOT_SOMETHING_YOU_CAN_VERB, 'play'); ]; Verb 'play' * noun ->Play; [ SwimSub; if (noun) { "You cannot swim in there."; } if (location == OnlyRoomWaistDeep) { "You swim a little bit, but there's no use swimming too far from the shore."; } if (location provides vec_norm) { print "You enter the ocean and swim a bit, trying to see if anything interesting is under the water.^"; PlayerTo(EnterOcean()); rtrue; } ! EnterOcean is defined after the code to navigate the waters (line 650 ish) "You cannot swim here."; ]; ! doesn't work and super flourishy ![ SwimDirSub; ! if (location == OnlyRoomWaistDeep) <>; ! "You aren't in water at the moment."; !]; Verb 'swim' * ->Swim !* noun=ADirection ->SwimDir * 'in' noun ->Swim; [ LookUnderSub ; "You can't really look under that."; ]; Extend 'look' first * 'under' noun ->LookUnder; [ ThrowSub; ; rtrue; ]; Extend only 'throw' first * multiheld ->Throw; Extend 'eat' replace ! instead of 'held' * noun ->Eat; !Verb 'lick' ! why do we need this? lick fish?? !* noun ->Eat; Extend 'climb' * 'on'/'in' noun ->Enter; ! Insert thing in door [ LocUnlocSub ; if (second has locked) { <>; } else { <>; } ]; Extend 'insert' first * noun 'in' door ->LocUnloc; [ Cut1Sub ; if (noun has scenery) { PrintMsg(MSG_NOT_SOMETHING_YOU_CAN_VERB, 'cut'); rtrue;} #ifndef IS_DEMO; if (Fishingknife notin player && Saw notin player) "You don't have anything to cut this with."; #endif; #ifdef IS_DEMO; if (Fishingknife notin player) "You don't have anything to cut this with."; #endif; PrintMsg(MSG_CUT_NO_USE); rtrue; ]; [ Cut2Sub ; if (noun has scenery) { PrintMsg(MSG_NOT_SOMETHING_YOU_CAN_VERB, 'cut'); rtrue;} #ifndef IS_DEMO; if (~~(second == Fishingknife or Saw)) { "This cannot be used to cut anything."; } #endif; #ifdef IS_DEMO; if (~~(second == Fishingknife)) { "This cannot be used to cut anything."; } #endif; PrintMsg(MSG_CUT_NO_USE); rtrue; ]; Extend 'cut' replace * noun -> Cut1 * noun 'with' held -> Cut2 !* noun 'on' held -> Cut2 !* noun 'onto' held -> Cut2 ; Extend 'slice' replace * noun -> Cut1 * noun 'with' held -> Cut2; Verb 'stab' = 'cut'; Verb 'carve' = 'cut'; [ GutSub ; PrintMsg(MSG_NOT_SOMETHING_YOU_CAN_VERB, 'gut'); rtrue; ]; Verb 'gut' * noun ->Gut; [ BaitSub ; if (noun ~= FishingRodReel) { PrintMsg(MSG_NOT_SOMETHING_YOU_CAN_VERB, 'bait'); rtrue; } if (second) { "You cannot bait the hook with this."; } "Please specify what you want to bait the hook with."; ]; Verb 'bait' * noun ->Bait * noun 'with' noun ->Bait; Verb 'gather' = 'take'; [ UntieSub ; print_ret (string) MSG_UNTIE; ]; Verb 'untie' 'detach' * noun -> Untie; ! not very intuitive branches here... [ SleepSub ; if (hammock in location) { if (F_SLEPT == false) { F_SLEPT = true; score = score + 5; print_ret "This net should be sturdy enough -- after all, it is made to catch a lot of fish and not break... You climb inside the hammock, which bends under your weight. The net's knots are digging in your back, but you find a way to be comfortable. You close your eyes and finally get the restful sleep you needed...^^You wake up in the morning,", (string) MSG_BURSTING_WITH_ENERGY; } } else { if (location == OnlyRoomWaistDeep) {"You are unable to sleep in water, since you sleep on your stomach.";} if (location == Deepinthewoods) {"The floor of the forest doesn't seem particularly comfy. Maybe there would be a way to sleep higher up...";} if (location ofclass Shore) { if (location == Edgeofthewoods) { "One look at the critters, and you decide not to sleep on the floor of the forest."; } else {"You'd be awoken by the high tide soaking you wet, judging by the fact that the sand doesn't seem to get dry here.";} } } if (F_ACT3_STARTED == 0) {print_ret "You don't feel sleepy anymore -- you are", (string) MSG_BURSTING_WITH_ENERGY; } else { "You're way too excited for this right now -- the secrets of the white house await you!"; } ]; [ SleepOnSub ; "This is not something you can sleep on."; ]; Verb 'sleep' 'nap' 'rest' * ->Sleep * 'on' noun ->SleepOn; Verb 'shoo' = 'attack'; Extend 'shout' * 'at' noun ->Attack; Verb 'strike' = 'attack'; ! strike match [ BurnSub ; print_ret (string) MSG_BURN_DEFAULT; ]; Verb 'burn' 'light' 'cook' * noun -> Burn * noun 'with' held -> Burn; Verb 'set' ! TODO: set noun ->Set (for the frequency) * 'fire' 'to' noun ->Burn; ! hacky [ ArrangeSub _k; if (noun == firewood) { if (FIRE_IS_READY) {<>;} ! quite proud if (firewood in player) {<>;} ! we want the same message as drop, but not if the hands are full ! keep_silent : silent if everything was good, if not it isn't silent about the reason _k = keep_silent; keep_silent = true; if (TryToTakeNoun() == 0) { ! taking the object was successful - i know i know ! then we're good and we drop it keep_silent = _k; ; } ! else : trytotakenoun will have displayed the reason keep_silent = _k; rtrue; } PrintMsg(MSG_DONT_GET_WHAT_TO_DO); ! complex message, don't change to a print_ret ]; Verb 'arrange' * noun ->Arrange; [ CampfireSub; if (parent(firewood) == player or location && firewood.dampness < 2) {; rtrue;} #ifndef IS_DEMO; if (location == Scenicview) {<>;} #endif; "You first have to find some wood and make it dry enough."; ]; [ HamSub ; if (Fishingnet in player) { if (Trees in location) { ; rtrue; } else {"You need to tie your hammock to something stable.";} } else {"You don't have anything to make a hammock with.";} ]; Constant MSG_NOTHING_FOR_FIRE "You don't have anything to light a fire with."; Verb 'make' 'build' * 'fire'/'campfire' ->Campfire * 'hammock' ->Ham; [ LightFireSub ; #ifndef IS_DEMO; if (noun ~= 0 && ~~(noun == Lighter or matchbook)) { "This cannot be used to light a fire."; } if ((Lighter in player || matchbook in player) && parent(firewood) == location or player) { ; rtrue;} else {"You need to find dry wood first."; } if (Fire in location) { ; rtrue; } #endif; #ifdef IS_DEMO; if (noun ~= 0 && noun ~= matchbook) { "This cannot be used to light a fire."; } if (matchbook in player && parent(firewood) == location or player) { ; rtrue;} else {"You need to find dry wood first."; } #endif; print_ret (string) MSG_NOTHING_FOR_FIRE; ]; ! Burn, Attack: if (parent(firewood) == location or player) {; rtrue;} else {"You'd rather save your matches to start a campfire.";} Extend 'light' * 'fire'/'campfire' ->LightFire * 'fire'/'campfire' 'with' noun ->LightFire; Verb 'start' * 'fire' ->LightFire * noun ->SwitchOn; ! start jukebox, start generators, etc Verb 'smoke' = 'burn'; [ DrySub ; "This doesn't seem like it needs to be dried."; ]; Verb 'dry' * noun ->Dry; Extend 'tie' * noun 'in'/'on'/'onto' noun ->Tie; !Verb 'bind' = 'tie'; Verb 'hang' = 'tie'; [ CountSub ; "You have better things to do than counting this."; ]; Verb 'count' * noun ->Count; ! Fix for ">remove mud : But you're not wearing the mud [NotHeld; if(noun in player || noun == 0) {rfalse;} else {rtrue;} ]; [ TakeWithSub; ! only accessible with befores print_ret "I don't understand how ", (the) second, " would help with ", (the) noun, "."; ]; Extend 'remove' first * noun=NotHeld 'with' noun ->TakeWith; Extend 'take' * worn 'off' ->Disrobe * noun=NotHeld 'with' noun ->TakeWith; Extend 'get' * noun=NotHeld 'with' noun ->TakeWith; Extend 'remove' first * noun=NotHeld -> Take; Extend 'fill' * noun 'with' noun ->Fill; [ LowerSub; PrintMsg(MSG_NOT_SOMETHING_YOU_CAN_VERB, 'lower'); rtrue; ]; Verb 'lower' * noun ->Lower; [ RaiseSub; PrintMsg(MSG_NOT_SOMETHING_YOU_CAN_VERB, 'raise'); rtrue; ]; Verb 'raise' * noun ->Raise; [ FixSub; PrintMSG(MSG_NOT_SOMETHING_YOU_CAN_VERB, 'fix'); ]; Extend only 'fix' replace * noun ->Fix; Verb 'repair' * noun ->Fix; [ FluteSub; if (TinyFlute in player) { ; rtrue; } else { "You shout for the albatross, but it doesn't come."; } ]; [ CallSub; PrintMsg(MSG_DONT_GET_WHAT_TO_DO); ]; [ SOSSub; #ifndef IS_DEMO; if (location == Commsroom) { <>; } if (F_ACT2_STARTED || TOWER_SEEN_THROUGH_TREES) { "The only way to call for help is to get the radio working.";} #endif; "Calling for help is useless, as nobody will hear you."; ]; Verb 'call' * noun ->Call * 'bird'/'albatros' ->Flute * 'help'/'sos' ->SOS * 'for' 'help'/'SOS' ->SOS; Verb 'send' * 'sos' ->SOS * 'a'/'an' 'sos' ->SOS * 'sos'/'help'/'distress' 'call'/'message' ->SOS * 'a'/'an' 'sos'/'help'/'distress' 'call'/'message' ->SOS; [ LisSub; #ifndef IS_DEMO; if (noun == 0 && geiger has on && parent(geiger) == location or player) { <>;} #endif; <>; ]; Extend 'listen' replace * -> Lis * noun -> Lis * 'to' noun -> Lis * 'to' 'the' noun -> Lis; #ifndef IS_DEMO; Verb 'pry' * noun=NotHeld ->Take * noun=NotHeld 'with' noun ->TakeWith; ! Drink water from bottle, drink from bottle Extend 'drink' * 'water' 'from' noun ->Drink * 'from' noun ->Drink; ! Pump [Pump2Sub; if (location == Centralplaza) {<>;} if (parent(Bikepump) == player or location) { <>;} PrintMsg(MSG_PARSER_NOTHING_TO_VERB, 'pump'); ]; [ PumpSub; PrintMsg(MSG_NOT_SOMETHING_YOU_CAN_VERB, 'pump'); ]; Verb 'pump' * noun ->Pump * ->Pump2; [ CrawlSub; if (Holeinthefence in location) { ; rtrue;} print_ret (string) MSG_PUSHDIR_DEFAULT; ]; Verb 'crawl' 'kneel' * ->Crawl * 'in' noun ->Enter; [ GoAroundSub; "Please rephrase using a direction."; ]; [ GoNothingSub; "Please provide the name of a direction or an object."; ]; Extend 'go' * 'in'/'through'/'towards' noun ->Enter * 'around' noun ->GoAround * ->GoNothing; [ BinocSub; if (second ~= Binoculars) { print_ret (string) MSG_CANT_LOOK_THROUGH; } "You doubt the binoculars would reveal any interesting details."; ]; [ Binoc2Sub; if (noun ~= Binoculars) { print_ret (string) MSG_CANT_LOOK_THROUGH; } if ( (location == Topofthetower or BaseOfTower or Communitygarden) || (location == OnlyRoomWaistDeep && vecteur_normal == 1 && sandbankDepth > TRISTAM_SANDBANK_DEPTH)) { <>; } "Nothing here needs to be looked at through binoculars."; ]; Extend 'look' * 'at' noun 'through'/'with' noun ->Binoc * 'through'/'with' noun ->Binoc2; Extend 'examine' * noun 'through'/'with' noun ->Binoc; Verb 'chew' = 'eat'; ! chew gum [ TryLockOrUnlock n; if (noun hasnt lockable) { if (n == 'unlock') { PrintMsg(MSG_UNLOCK_NOT_A_LOCK, n); rtrue;} if (n == 'lock') { PrintMsg(MSG_LOCK_NOT_A_LOCK, 'lock'); rtrue; } } if (n=='lock' && noun has locked) { PrintMsg(MSG_LOCK_ALREADY_LOCKED, n); rtrue; } if (n=='lock' && noun has open) { PrintMsg(MSG_LOCK_CLOSE_FIRST); rtrue; } if (n=='unlock' && noun hasnt locked) { PrintMsg(MSG_UNLOCK_ALREADY_UNLOCKED, n); rtrue; } if (noun == CrudeDoor or OneBigDoor or OneBigLockableDoor or BossRoomDoor or CommsRoomDoor) { print_ret "To ", (verbname) n, " this door, you'll have to specify with which key."; } else { PrintMsg(MSG_UNLOCK_NOT_A_LOCK, n); rtrue; } ]; [ TryUnlockSub; TryLockOrUnlock('unlock'); ];[ TryLockSub; TryLockOrUnlock('lock'); ]; Extend 'unlock' * noun ->TryUnlock; Extend 'lock' * noun ->TryLock; [ PickSub; ! need to have a separate verb so we can detect "pick lock" <>; ]; Extend 'pick' * noun ->Pick; ! NOTE HERE: ! roger firth tells you how to do it for a new verb ! but if you're extending a meta verb, you need to do a "notmeta" token instead [ notMeta; meta = false; return GPR_PREPOSITION; ]; Extend 'restart' replace * ->Restart * notMeta noun ->SwitchOn; ! restart generator Extend only 'unscrew' * noun 'with' noun ->Unlock; [ UnplugSub; if (second == 0 && noun has switchable) { <>; } else { <>; } ]; Verb 'connect' * noun 'to'/'in'/'with'/'on'/'and' noun ->Tie; Verb 'plug' * 'in' noun 'to' noun ->Tie * noun 'to'/'in'/'with'/'on'/'and' noun ->Tie; Verb 'unplug' 'disconnect' * noun ->Unplug * noun 'and' noun ->Unplug; [ MicSub; "Talking into this will not do anything."; ]; Verb 'talk' * 'to' noun ->Tell * 'in' noun ->Mic; [ ShootSub; PrintMSG(MSG_NOT_SOMETHING_YOU_CAN_VERB, 'fire'); ]; Verb 'shoot' 'fire' * noun ->Shoot; #endif; ! IS_DEMO ! In the manual or not? [ CreditsSub ; "[The author would like to thank:^Infocom, creators of the Z-Machine and of so many awesome adventure games that we're still using their tools 40 years after;^Graham Nelson, creator of Inform 6;^Andrew Plotkin, for his hard work and dedication to fixing the Inform 6 compiler's bugs that had prevented z3 releases for years;^Fredrik Ramsberg and Johan Berntsson, for the amazing PunyInform library, and many optimizations and bugfixes;^My testers: Manon Burz-Labrande, CrocMiam, Steve Flintham, Grimmnebulin, Brennen Kinch, Juhana Leinonen, Samuel Verschelde, Mark Walker, Jack Welch;^The players who reported bugs in the initial release: Davide Bucci, Chris Carter, Wade Clarke, Denk, Richard Hawkins, Christopher Merrimer, Brian Rushton, Tiffany Zhao;^All the programmers and maintainers of interpreters, which keep the Z-Machine alive on so many platforms;^Stefan Vogt, for his help setting up ports of this game, and his detailed answers to my technical questions;^And last but not least, my wife and my kids, for their love, support, and patience.]"; ]; Verb 'credits' 'thanks' 'about' 'info' * -> Credits; [ HelpSub ; print "[There is no built-in help in this game. However, some of the later puzzles can be skipped "; if (ALBATROSS_ALREADY_STOLE == 0) {print "using an object you haven't gotten yet."; } else { print "by calling the albatross with the flute; this can only be done once.";} "^Purchasing the game also allows you to download a hint book. If you're still stuck after that, ask for help online.]"; ]; Verb 'help' 'hint' 'hints' * ->Help; ![SpecSub _ks; ! _ks = keep_silent; ! keep_silent = 1; ! ; ! keep_silent = _ks; !]; !Verb 'spec' !* noun ->Spec; #ifndef IS_DEMO; Constant FIRST_FLOATING_ACT2 = 15; ! OneBigLockableDoor is the 15th floating object Constant FIRST_FLOATING_ACT3 = 24; ! the angled pipe by the roof is the 40th floating object Constant FIRST_FLOATING_ACT4 = 29; ! the door of the lieutenant-general's room is the 43th floating object #endif; Global freq = 4020; [ Initialise ; location = Immaculatebeach; lookmode = 2; move matchbook to player; scope_modified = true; ! changes to thedark thedark.description = DescribeTheDark; thedark.short_name = TheDarkShortName; #ifndef IS_DEMO; ! FOR TESTING ACT 2 ONLY ! remove matchbook; ! location=Topofthestairs; ! give Northerncliffs visited; ! FISH_ELEVATOR_UP = 1;f ! move Fishingknife to player; ! move Fishingrod to player; ! move TinyFlute to player; ! F_ACT2_STARTED = 1; ! F_CLIMBED_STEPS = 1; ! F_ATE_SOMETHING = 1; ! F_SLEPT = 1; ! ALBATROSS_ALREADY_STOLE=1; ! FOR TESTING ACT 3 ONLY ! F_ACT3_STARTED = 1; ! move Flatheadscrewdriver to player; ! location=WhiteHouseLobby; ! FOR TESTING ACT 4 ONLY ! F_ACT4_STARTED = 1; ! F_ELEVATOR_DOWN = 1; ! location = Insidetheelevator; #endif; player.description = "You're doing OK, all things considered. Still a bit shaken by the accident, but this island sure is interesting and warrants further exploration. You are fairly confident you will manage to escape, one way or another. You don't really know why -- just a hunch."; ! accented tests !print "Restaurant @<> - @^Ile de Malm@/o^^(@cCa, c'est le menu de tant@^ot, pour @LL36:)^^Rago@^ut et p@^at@'e de t@^ete o@`u la sauce fermi@`ere vient d'Ha@:y-les-Roses, et beurre ma@^itre d'h@^otel^@OEufs @>>die Stra@sse@<<, servis entre le P@`o et A@'yna, re@ccus hier (1 @oeuf @`a la fran@ccaise, a@~nejo de Guadalaj@'ara, et c@aetera)^B@'anh m@`i et ses sp@:atzele en n@oeuds @<<@`a la M@:otley Cr@:ue@>>^B@^uche de No@:el de 15 @oA (@oangstr@:om) de long^^@^Ag@'e de 20 ans et employ@'e par @/Orsted, @!!al jefe se encanta la m@'usica!"; "You lift your eyes up to the island and sigh.^^It was just supposed to be a trip like so many you've flown, taking your small airplane to a remote island in the south Atlantic Ocean to deliver medicine and spare parts. You thought you'd be back by sunset, but a storm like you've never seen before whipped up out of nowhere and battered your airplane. You were losing altitude so fast, you had no choice but to take your parachute and ditch the plane in the drink. You're extremely lucky to have spotted this small island, a tall chunk of rock in the middle of the ocean. It saved you from certain death; but you can't stay on this island forever. You'll have to explore and see what you're working with.^^You look back down and sigh.^^"; ]; ! 250 bytes Constant HDR_GAMEFLAGS $10; Global transcript_mode = false; ! true when game scripting is on [ ScriptOnSub; transcript_mode = ((HDR_GAMEFLAGS-->0) & 1); if (transcript_mode) "Transcripting is already on."; @output_stream 2; if (((HDR_GAMEFLAGS-->0) & 1) == 0) "Attempt to begin transcript failed."; print "Start of a transcript of^"; Banner(); transcript_mode = true; ]; [ ScriptOffSub; transcript_mode = ((HDR_GAMEFLAGS-->0) & 1); if (transcript_mode == false) "Transcripting is already off."; print "^End of transcript.^"; @output_stream -2; if ((HDR_GAMEFLAGS-->0) & 1) "Attempt to end transcript failed."; transcript_mode = false; ]; Verb meta 'script' 'transcript' * -> ScriptOn * 'on' -> ScriptOn * 'off' -> ScriptOff; !#ifndef IS_DEMO; ! get transported in act 2 ![ GicSub ; ! remove matchbook; ! give Northerncliffs visited; ! FISH_ELEVATOR_UP = 1; ! move Fishingknife to player; ! move Fishingrod to player; ! move TinyFlute to player; ! F_ACT2_STARTED = 1; ! F_CLIMBED_STEPS = 1; ! F_ATE_SOMETHING = 1; ! F_SLEPT = 1; ! ALBATROSS_ALREADY_STOLE=1; ! PlayerTo(Topofthestairs); rtrue; !!]; ! get transported in act 3 ![ HouSub i; ! remove matchbook; ! F_GENERATORS_ON = 1; ! for (i=FIRST_FLOATING_ACT3: ii) ~= 0) { give (floating_objects-->i) ~absent; }} ! F_ACT3_STARTED = 1; ! move Flatheadscrewdriver to player; !move Bikepump to player; !move Cricketball to player; ! StartAct3(); ! PlayerTo(WhiteHouseLobby); rtrue; !]; ! get transported in act 4 ![MaSub i ; ! remove matchbook; ! !move Flatheadscrewdriver to player; ! for (i=FIRST_FLOATING_ACT3: ii) ~= 0) { give (floating_objects-->i) ~absent; }} ! StartAct4(); ! F_ELEVATOR_DOWN=1; ! Playerto(Insidetheelevator); rtrue; !]; !Verb 'david' !* ->Gic; !Verb 'houdini' !* ->Hou; !Verb 'copperfield' !* ->Ma; !#endif; !======================================================================= ! Widely-found scenery objects Global WE_PARSED_A_WORD = 0; Global PARSED_SEA = 0; Global PARSED_SKY = 0; Global PARSED_ISLAND = 0; Global PARSED_BEACH = 0; Global PARSED_HORIZON = 0; Global PARSED_TREES = 0; Global PARSED_CLIFFS = 0; ! TODO: cliffs?, Hill? (subsumed in island) [ PrintOffShore ; ! write which way is the coast switch(room_shore) { Immaculatebeach: print "an immaculate beach, north"; Beachnearforest: print "a beach near a clearing, north"; Southwesterncliffs: print "tall cliffs, northeast"; Narrowstrait: print "a narrow strait, east"; Northwesterncliffs: print "tall cliffs, southeast"; Northerncliffs: print "tall cliffs and a wooden dock, south"; Northeasterntip: print "the northeastern tip of the island, southwest"; Cove: print "a small cove, west"; Endofthebeach: print "a boulder on the sandy beach, northwest"; } print " of you."; rtrue; ]; [ ClearParsingFlags ; PARSED_SEA = false; PARSED_SKY = false; PARSED_ISLAND = false; PARSED_BEACH = false; PARSED_HORIZON = false; PARSED_CLIFFS = false; PARSED_TREES = false; ]; Object FarAwayElements with found_in [; rtrue; ], short_name [; if (PARSED_SEA) {print "the Atlantic Ocean"; rtrue;} if (PARSED_SKY) {print "the sun"; rtrue;} if (PARSED_ISLAND) {print "this island"; rtrue;} if (PARSED_BEACH) {print "the beach"; rtrue;} if (PARSED_HORIZON) {print "the horizon"; rtrue;} if (PARSED_TREES) {print "the trees"; rtrue;} if (PARSED_CLIFFS) {print "the cliffs"; rtrue;} print (string) MSG_BIGOBJECT_PARSING_ERROR; rtrue; ], parse_name [ w n ; ! don't clear the parsing flags yet! if you matched a noun and are matching for a second and it's not one of these, you don't want to lose the info on what the first one was WE_PARSED_A_WORD = 0; n=0; w=NextWord(); while(w) { ! if we already parsed a word, WE_PARSED_A_WORD=true; if we already parsed a word for the sea, PARSED_SEA = true ! algorithm: if we match the sea: ! if we hadn't before: ! if another word has already been parsed: confusing (sea & sun ??), return the current n to give up ! if it's the first word we parse: all is good, put the flags up, say we matched something (this will increase n at the end) ! if we had: say we matched something, this will increase n at the end #ifndef IS_DEMO; if (w=='sea' or 'ocean' or 'atlantic' or 'waves' or 'seawater' or 'surface' or 'salt' || (location ~= Narrowstrait && location ~= Centralplaza && w == 'water')) { #endif; #ifdef IS_DEMO; if (w=='sea' or 'ocean' or 'atlantic' or 'waves' or 'seawater' or 'surface' or 'salt' || (location ~= Narrowstrait && w == 'water')) { #endif; if (PARSED_SEA == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags(); WE_PARSED_A_WORD=true; PARSED_SEA = true; } } jump parsedaword1; } if (w=='sun' or 'sky' or 'blue') { if (PARSED_SKY == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags(); WE_PARSED_A_WORD=true; PARSED_SKY = true; } } jump parsedaword1; } #ifndef IS_DEMO; if (w == 'ridge' or 'plateau' || (w=='hill' && location~=Deepinthewoods) || (w=='island' or 'this' && location ~= Inpub && ~~TestScope(TristamIsland) )) { if (PARSED_ISLAND == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags(); WE_PARSED_A_WORD=true; PARSED_ISLAND = true; } } jump parsedaword1; } #endif; #ifdef IS_DEMO; if (w == 'ridge' or 'plateau' || (w=='hill' && location~=Deepinthewoods) || (w=='island' or 'this' && ~~TestScope(TristamIsland) )) { if (PARSED_ISLAND == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags(); WE_PARSED_A_WORD=true; PARSED_ISLAND = true; } } jump parsedaword1; } #endif; if (w=='beach' or 'beaches' or 'sandy' or 'yellow' or 'sand' or 'shore' or 'coast' or 'rocky') { if (PARSED_BEACH == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags(); WE_PARSED_A_WORD=true; PARSED_BEACH = true; } } jump parsedaword1; } if (w=='horizon' or 'far' or 'away' or 'skyline') { if (PARSED_HORIZON == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags(); WE_PARSED_A_WORD=true; PARSED_HORIZON = true; } } jump parsedaword1; } if (location ~= Deepinthewoods && location ~=Edgeofthewoods && (w=='cliff' or 'cliffs' or 'chalk' or 'chalky' or 'white' or 'tall')) { if (PARSED_CLIFFS == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags(); WE_PARSED_A_WORD=true; PARSED_CLIFFS = true; } } jump parsedaword1; } #ifndef IS_DEMO; if (location ~= Aroundthefence && ((w== 'forest' or 'leaf' or 'leaves' or 'bark' or 'woods') || ( (~~(location == Deepinthewoods or Edgeofthewoods or Scenicview)) && (w=='branch' or 'wood' or 'tree' or 'trees')) ) ) { ! 'branches'='branch', 6 letter resolution if (PARSED_TREES == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags(); WE_PARSED_A_WORD=true; PARSED_TREES = true; } } jump parsedaword1; } #endif; #ifdef IS_DEMO; if ( ((w=='tree' or 'trees' or 'forest' or 'leaf' or 'leaves' or 'bark' or 'woods') || (location ~= Deepinthewoods && location ~= Edgeofthewoods && (w=='branch' or 'wood')) ) ) { ! 'branches'='branch', 6 letter resolution if (PARSED_TREES == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags(); WE_PARSED_A_WORD=true; PARSED_TREES = true; } } jump parsedaword1; } #endif; ! if we're here, we didnt match, so we stop return n; .parsedaword1; ! if we're here, we matched, so we keep going n++; w = NextWord(); } return n; ], description [; if (location ofclass Shore || location == OnlyRoomWaistDeep || location ofclass Outside) { if (PARSED_SKY) { if (location == Edgeofthewoods or Deepinthewoods) {"The sun peeks through the trees, but the forest is rather shady and cool.";} else { "The sun shines hard on you; it's a rather hot day."; } } if (PARSED_SEA) { if (location == OnlyRoomWaistDeep && (vecteur_normal %4) == FISHES_VECTEUR_NORMAL) { ; rtrue; } print "The immense Atlantic Ocean surrounds the island; you are probably hundreds of miles away from the closest inhabited coastline."; if (location ofclass Shore) {print " The water is surprisingly not too cold; you could swim easily in it.";} @new_line; @rtrue; } if (PARSED_ISLAND) { if (location == OnlyRoomWaistDeep) { print "From the ocean, you can appreciate the size of the island: rather large, and tall, with a flat top, but you probably only need a couple of days to explore it. You are off shore from "; PrintOffShore(); @new_line; @rtrue; } else { if (location == Deepinthewoods) { <>; } else { "The island you ended up on appears to be a tall chunk of rock that seems to form a plateau at the top. Cliffs surround the island, except on the south side, which has a more gentle slope and is covered by a dense forest."; } } } if (PARSED_BEACH) { if (location ofclass Outside) { "The beaches of this island are just down the cliffs."; } else { if (Rocksandpebbles in location) { <>;} else {"The beach angles slightly downhill towards the sea. It is made of yellow, compact sand; the high tide probably submerges the beach every time.";}} } if (PARSED_HORIZON) { if ((location == BaseOfTower or Communitygarden or Topofthetower) || (location == OnlyRoomWaistDeep && vecteur_normal == 1 && sandbankDepth > TRISTAM_SANDBANK_DEPTH)) { <>; } else { "You squint and try to find something, anything, on the horizon. After a few minutes, you give up."; } } if (PARSED_CLIFFS) { ! TODO: add some act2 in there, maybe ot the same description at the top print "These tall white cliffs appear to be made of chalk; you guess they are probably fifty feet tall. At the top of the cliffs, "; if (location == OnlyRoomWaistDeep && vecteur_normal == 1) { print "dense trees are growing"; if (sandbankDepth) { "; behind them, you can clearly see the top of a steel tower."; } else { if (TOWER_SEEN_THROUGH_TREES) { "; behind them, you spot the tall, metallic mast at the top of the watchtower you spotted earlier."; } else { " -- although you think you can spot something behind them. It looks like... a tall, metallic mast? Could this really be? On this deserted island?"; } } } else { print "you can see a few branches and leaves"; if (TOWER_SEEN_THROUGH_TREES) { ", from the trees growing there; however you cannot see the steel tower from here."; } else { "; some trees must be growing there."; } } } if (PARSED_TREES) { print "A rather dense forest covers the south side of the island; you have to go through it if you want to climb up the hill and see the rest of the island. There's also a few trees above the cliffs, "; if (F_ACT2_STARTED) { "around the village.";} else { "but you don't know what's behind them.";} } } else { if (PARSED_SKY) { "No natural light is filtering through here."; } ! TODO: delete this if you need space "You cannot currently see this as you are inside a building."; } ], before [; Touch,Rub: if (PARSED_SEA) { if (location == OnlyRoomWaistDeep) { "You splash the sea softly with your hands."; } ! TODO: the exclusion is ugly if (location ofclass Shore && location ~= Edgeofthewoods && location ~= Deepinthewoods) { "You get closer to the ocean; a small wave laps at your feet."; } "You cannot touch the ocean right now."; } if (PARSED_ISLAND) { "You are touching the island just by standing on it.";} print_ret (string) MSG_UNTOUCHABLE; Take: PrintMsg(MSG_TOO_IMMENSE); "taken."; Turn, Push, Pull,Search: PrintMsg(MSG_TOO_IMMENSE); print_ret (verbname) verb_word, "ed."; Eat: if (PARSED_TREES) { "You doubt your digestive system could handle that."; } PrintMsg(MSG_NOT_SOMETHING_YOU_CAN_VERB, 'eat'); rtrue; Drink: if (PARSED_SEA) { print_ret (string) MSG_OCEAN_WATER; } rfalse; Enter: if (PARSED_ISLAND) { switch(location) { OnlyRoomWaistDeep: print "You leave the sea and go back to the shore."; PlayerTo(room_shore); rtrue; Deepinthewoods: ; rtrue; ! "climb island" default: "You already are on this island."; } } if (PARSED_BEACH && location == OnlyRoomWaistDeep) { print "You leave the sea and go back to the shore."; PlayerTo(room_shore); rtrue; } if (PARSED_SEA) { ; rtrue;} if (PARSED_TREES && location == Immaculatebeach or Beachnearforest) { <>; } Swim: if (PARSED_SEA) { ; rtrue; } Cut1, Cut2: if (PARSED_TREES) { print_ret (string) MSG_FELL_A_TREE; } Count: if (PARSED_TREES) { "There are 69,105 of them."; } ! climb cliffs - no cliffs visible in the forest anyway Climb: if (PARSED_CLIFFS) { if (location ofclass Shore || location == OnlyRoomWaistDeep) {print_ret (string) MSG_CLIIFS_ARE_TALL;} else { "You already are up the cliffs.";} } LookUnder: if (PARSED_CLIFFS || PARSED_SKY || PARSED_HORIZON) { print "Under ", (the) self, " is the "; if (PARSED_CLIFFS) { "shore."; } else {"ocean.";} } if (PARSED_TREES) { "Under the trees are their roots."; } if (PARSED_ISLAND || PARSED_BEACH) { "There is no shovel big enough for this.";} if (PARSED_SEA) { if (location == OnlyRoomWaistDeep) { if (vecteur_normal %4 == FISHES_VECTEUR_NORMAL) { ; rtrue;} else { "You look for a while, but there doesn't seem to be anything under the surface."; } } else {"You're not close enough to see anything.";} } Receive: if (PARSED_SEA) { if (noun == FishingRodReel or Fishingrod) { ; rtrue; } else { print_ret (string) MSG_PUT_IN_SEA; }} if (PARSED_BEACH) { if (parent(player) ofclass Shore) { <>; } else { "You are not currently on the beach."; }} Exit: if (PARSED_SEA) { if (location == OnlyRoomWaistDeep) { PlayerTo(room_shore); rtrue; }} SleepOn: if (PARSED_ISLAND || PARSED_BEACH) { <>; } ], has concealed proper; Constant MSG_WOULD_SEE_BETTER_ATOP " You would probably see it better atop the steel tower."; ! F_TRISTAM_DISCOVERED = we saw it once, we know it exists ! proper = we know its name (only way: in the pub's poster, which also sets the discovered flag ! F_SAW_TRISTAM_PRECISELY = we saw it through the binoculars Global F_SAW_TRISTAM_PRECISELY=0; Object TristamIsland with short_name [; if (self has proper) { print "Tristam Island"; } else { print "neighbouring island"; } rtrue; ], parse_name [ w n ; n = 0; w = NextWord(); while (w) { ! this is unnecessarily fancy? if ( w=='island' or 'neighbouring' or 'other' || (self has proper && w=='tristam') || (F_SAW_TRISTAM_PRECISELY && (w=='charred' or 'destroy'))) { n++; w=NextWord(); } else {return n;} ! covers "destroyed", clashes with the "destroy" verb if I don't remove it (compiler bug) } return n; ], found_in [; ! can be seen atop the island if you know it's there, if not it's only specific locations if (location ofclass Outside || (location == OnlyRoomWaistDeep && vecteur_normal == 1 && sandbankDepth > TRISTAM_SANDBANK_DEPTH)) { if (location == OnlyRoomWaistDeep or BaseOfTower or Communitygarden or Topofthetower) { rtrue;} else { if (F_TRISTAM_DISCOVERED == 0) { rfalse; } else { rtrue; } } } rfalse; ], description [; if (location ofclass Outside) { if (location == Topofthetower or BaseOfTower or Communitygarden) { print "To the southeast, on the horizon, is a small island."; if (F_TRISTAM_DISCOVERED) { if (self has proper) { print " This is probably Tristam Island, that you saw on the map inside the pub."; } } else { F_TRISTAM_DISCOVERED=true; print " You had no idea there was another island nearby!"; } if (location == Topofthetower) { " The island is shaped a bit like a horseshoe, with a circular lagoon near its western shore. You can pretty much see the whole island from here, and something looks... off. You can't quite tell what, though; it is difficult to make out the details with the naked eye only."; } else { print_ret " Contrary to the island you're on right now, this seems to be a low-lying island; from here, however, you can only see the edge of the island.", (string) MSG_WOULD_SEE_BETTER_ATOP; } } else { ! anything that's on the island but not close to the island if (F_TRISTAM_DISCOVERED) { print "You know that "; if (self has proper) { print "Tristam Island is"; } else { print "there is an island"; } " off nearby, but you can't really see it from where you're standing."; } else { print_ret (string) MSG_PARSER_NOSUCHTHING;} } } else { ! OnlyRoomWaistDeep F_TRISTAM_DISCOVERED=true; MoveFloatingObjects(); "You try to focus on the shape, but it is very faint. It looks like there is something, though; maybe some kind of island."; } ], #ifndef IS_DEMO; before [; Binoc: if (location == Topofthetower) { if (F_SAW_TRISTAM_PRECISELY == 0) { F_SAW_TRISTAM_PRECISELY=1; score = score+5; print "You take a look at the island through your binoculars, and your intuition was right. "; } !if (self has proper) { print "Tristam"; } else { print "The"; } print_ret (The) self, " looks rather inhospitable, covered in rocks and rubble, with patchy vegetation that doesn't look more than two feet tall. But near the shore, and on the sand in the lagoon, you spot a few long black trunks, as if the trees had been destroyed, charred, a long time ago, and hadn't manage to grow back since. Something must have happened on that island, but you can't quite figure out what. Your intuition tells you it's important, though."; } if (location == BaseOfTower or Communitygarden or OnlyRoomWaistDeep) {print_ret "You look at ", (the) noun, " through your binoculars. You can see its shore a bit better; the island seems to be low-lying, with a few bushes and brambles near its beach, but that's about all you can see.", (string) MSG_WOULD_SEE_BETTER_ATOP;} <>; Examine: ; default: print_ret (The) self, " is too far away."; ], #endif; ! IS_DEMO has scenery concealed ; !====================================================== ! Code to move in the water in act I ! Each location will tell you the normal vector; declaring this as a property saves 68 bytes (and we have 2 properties left with Puny anyway) Property vec_norm; ! Directions in a clockwise order ! FAKE_N_OBJ is repeated cause 2 locations have north beaches Array clockwise_dir_array static -> n_to ne_to e_to se_to s_to sw_to w_to nw_to n_to ; ! already defined: room_shore, sandbankDepth, vecteur_normal, and TRISTAM_SANDBANK_DEPTH and FISHES_VECTEUR_NORMAL Constant MSG_WALK_A_LITTLE_THIS_WAY "You walk a little in this direction, "; [ MoveInSea v; ! detect if we're going inland !print "Vecteur normal :", (number) vecteur_normal; print "^"; !print "Vecteur normal - direction :", (number) clockwise_dir_array->vecteur_normal; print "^"; !print "Selected direction: ",(number) selected_direction; print "^"; !print "Room on the shore : ", (name) room_shore; print "^"; v = (vecteur_normal +6)%8; ! Are we going inland? if (selected_direction == clockwise_dir_array->vecteur_normal) { return room_shore; } ! Are we going in the direction between inland and parallel to the coast clockwise? if so, pretend we follow the coast if (selected_direction == clockwise_dir_array->((vecteur_normal+7)%8)) { selected_direction = clockwise_dir_array->v; } !print "Selected direction: ",(number) selected_direction; print "^"; !print "v = ", (number) v; print "^"; ! move along the coast: ! if the room on the shore has that direction (e.g. we're following a parallel line) ! but careful: the room on the shore also provides the direction that goes in the water! you don't want that ! update the room on the shore, and update the normal vector if (room_shore provides selected_direction && selected_direction ~= clockwise_dir_array->((vecteur_normal+4)%8) ) { ! update the normal vector if (selected_direction == clockwise_dir_array->v) { ! we're going clockwise if (room_shore ~= Immaculatebeach) { vecteur_normal = (vecteur_normal + 1) %8; } } else { if (room_shore ~= Beachnearforest) { vecteur_normal = (vecteur_normal + 7) %8; } } ! change the room on the shore room_shore = room_shore.selected_direction; ! message print (string) MSG_WALK_A_LITTLE_THIS_WAY, "following the coast.^"; !print "New room on the shore : ", (name) room_shore; print "^"; !print "Nouveau vecteur normal :", (number) vecteur_normal; ! update objects with found_in, most importantly the fish and the tower (which depend on the normal vector) MoveFloatingObjects(); sandbankDepth=0; ! if we leave the sandbank, then go back to it, we assume we went back closer to the shore ; rtrue; } else { print_ret (string) MSG_WALK_A_LITTLE_THIS_WAY, "but you don't want to go too far from the shore."; } ]; Constant MSG_ALONG_THIS_SANDBANK " along this underwater sandbank."; Object OnlyRoomWaistDeep "In the ocean" with short_name [; if (vecteur_normal == 1) {print "Knee-deep in the ocean"; rtrue;} else {print "Waist-deep in the ocean"; rtrue;}], description [; if (vecteur_normal == 1) { print (string) MSG_SANDBANK_DESC, " Behind you, you can see the cliffs of the southwestern tip of the island."; if (sandbankDepth) { print " Up above the cliffs, behind some trees, you can distinguish the top of a steel tower."; if (sandbankDepth > TRISTAM_SANDBANK_DEPTH) { print " Looking southwest, you think you can see something lying low on the horizon.";} } @new_line; @rtrue; } print "You trudge uncomfortably into the cold water, and try to look around you. The horizon is bare, and the island looms behind you; you can see "; PrintOffShore(); if ( (vecteur_normal%4) == FISHES_VECTEUR_NORMAL) { " You take a closer look at the sea; after a moment, you spot some movement below the surface a few feet away from you. It looks like this is a good area for fishing."; } else { " There doesn't seem to be anything here in the turbid water."; } ], n_to MoveInSea, nw_to MoveInSea, w_to MoveInSea, e_to MoveInSea, se_to MoveInSea, s_to MoveInSea, ne_to [; if (vecteur_normal == 1 && sandbankDepth) { ! north east to the shore, eg "knee deep in the ocean" sandbankDepth--; print_ret "You go back a bit", (string) MSG_ALONG_THIS_SANDBANK; } else { return MoveInSea(); } ], sw_to [; if (vecteur_normal == 1) { ! north east to the shore, eg "knee deep in the ocean" if (sandbankDepth > TRISTAM_SANDBANK_DEPTH+1) { "You try to go further along this direction, but the sea becomes too deep at this point; you swim back to where you can touch the ocean floor.";} else { sandbankDepth++; print_ret "You go a bit further", (string) MSG_ALONG_THIS_SANDBANK; } } else { return MoveInSea(); } ], before [; Drop: print_ret (string) MSG_PUT_IN_SEA; Exit: if (noun == 0) { PlayerTo(room_shore); rtrue; } ], has light; [ EnterOcean ; vecteur_normal = location.vec_norm; room_shore = location; return OnlyRoomWaistDeep; ]; ! already defined: Global TOWER_SEEN_THROUGH_TREES=0; Object Topofthetoweramongthetrees with short_name [; if (TOWER_SEEN_THROUGH_TREES) {print "watchtower";} else { print "metallic mast"; } print " among the trees"; rtrue; ], parse_name [ w n ; n = 0; w = NextWord(); while (w) { ! this is unnecessarily fancy? if ( w=='mast' or 'radio' or 'metal' or 'metallic' or 'steel' or 'among' or 'trees' || ( (sandbankDepth || TOWER_SEEN_THROUGH_TREES) && (w=='tower' or 'watchtower' or 'watch'))) { n++; w=NextWord(); } else {return n;} } return n; ], found_in [; if (location == OnlyRoomWaistDeep && vecteur_normal == 1) { rtrue; } else { rfalse; } ], description [; if (sandbankDepth) { if (TOWER_SEEN_THROUGH_TREES == false) {TOWER_SEEN_THROUGH_TREES=1; print "You can't believe your luck, and you are stunned for a few seconds. But yes, it is a steel tower,"; score = score +1; } else { print "You see a steel tower";} " peeking from behind the trees; it looks like it is a watchtower, with a platform surrounded by a waist-high metal railing at the top. Atop the tower is a mast -- perhaps a radio mast, which would be very interesting to you."; } else { print "You can't really see it clearly from where you are, "; if (TOWER_SEEN_THROUGH_TREES) { "but you know it's a watchtower."; } else {", as the angle isn't great, but there definitely seems like there is something up there."; } } ], before [; Touch, Turn, Push, Pull, Enter, Climb,Take, Cut1, Cut2, Rub, Smell: if (TOWER_SEEN_THROUGH_TREES) { print "The tower"; } else { print "Whatever this is, it"; } " is too far."; ], has scenery concealed; !================================================ ! Fishing-related stuff ! with what? your bare hands? [ YepSub ; ! if fishschool.q > 0, the game just asked us "with what? Your bare hands?" if (fishschool.q > 0) "This isn't that kind of Adventure."; "I don't understand what you are replying ~yes~ to."; ]; Verb 'yes' 'yes!' 'yes?' * ->Yep; ! Fish fish with rod [ FiSub ; if (noun) { "You cannot fish this."; } if (location == OnlyRoomWaistDeep) { if (vecteur_normal % 4 == FISHES_VECTEUR_NORMAL) { ; rtrue; } else { "You don't really see any fish here. Maybe in a different spot."; } } "You'll have better chances catching a large fish if you go into the ocean."; ]; Verb 'fish' * ->Fi * noun ->Fi * noun 'with' held ->Fi; Extend 'go' first * 'fishing'/'fish' ->Fi; [ CastSub ; PrintMsg(MSG_NOT_SOMETHING_YOU_CAN_VERB,'cast'); rtrue; ]; Verb 'cast' * held ->Cast; [ CaSub; if (noun == fishschool) { <>;} else { <>; } ]; Verb 'catch' * 'fish' ->Fi * noun ->Ca; Constant MSG_HOWEVER_NONE_OF_THE_FISH "However, none of the fish seem to be "; [ GoneFishing ; if (_AtFullCapacity(player)) { "You need both hands free to fish with the fishing rod.";} else { ! player has only one object, the fishing rod print "You cast the line towards the fish, and wait patiently. "; ! TODO: the fishing rod reel can only contain 2 things: the flower and the worm; how do we refactor? if (WigglyWorm notin FishingRodReel) { print_ret (string) MSG_HOWEVER_NONE_OF_THE_FISH, "interested in your hook. You probably need to put bait on your hook."; } if (aFlower notin FishingRodReel) { print_ret (string) MSG_HOWEVER_NONE_OF_THE_FISH, "eager to take the bait; you wonder if they even notice it. Perhaps you need to add something colourful onto the hook as a lure that would make them notice you.";} ! All good move aFish to player; remove aFlower; remove WigglyWorm; scope_modified = true; if (ALBATROSS_ALREADY_STOLE == 0) { StartDaemon(Albatros); score = score+5; } print "You're about to give up when suddenly, you feel the line tense up; you got one! You carefully reel it in, and grab the fish firmly by its tail; the fish is grey, about "; print (string) random("five", "six", "four", "seven"); " inches long, and should make a nice meal."; } ]; ! flathead grey mullets? Object fishschool "fish" with name 'fish' 'shadow' 'movement', ! 'shadows' too, cause 6-letter resolution found_in [; if (location == OnlyRoomWaistDeep && (vecteur_normal % 4) == FISHES_VECTEUR_NORMAL) { rtrue; } else { rfalse; }], description [; print "You stand still, and look in the direction you saw the fish. After a few moments, you spot "; print (string) random("a fin poking out of the water","a shadow getting close to the surface","a turbulence at the surface, made by a tail that suddenly changed direction"); "."; ], q 0, each_turn [; if (self.q > 0) self.q--; ], before [; Fi, Attack: if (second) { if (second == Fishingrod or FishingRodReel) { GoneFishing(); rtrue;} else { "This is not how you catch a fish.";} ! fish fish with knife } else { ! "fish" or "fish fish" if (Fishingrod in player) { GoneFishing(); rtrue; } ! small nicety to the player else { if (Fishingnet in player) {; rtrue;} ! you can't operate it by yourself else { self.q = 2; "With what? Your bare hands?"; } } } Take, Push, Pull, Turn: "The fish will likely swim away as soon are you get anywhere close."; ], has static concealed reactive; Object aFish "fish" with name 'fish' 'grey' 'dead' 'meal', description "This is a nice grey fish, freshly caught; it would make a great meal.", before [; Drop: if (Albatros in location) {; rtrue;} else { if (F_ATE_SOMETHING) {remove self; scope_modified = true; "After all, you don't feel too hungry. You release the fish by throwing it as hard as you can in the sea.";} else { if (location == OnlyRoomWaistDeep) { "You really, really need this meal.";} else {"You don't really want to put your dinner on the floor."; } } } PutOn, Insert: if (second has container || second has supporter) { remove aFish; scope_modified = true; ALBATROSS_ALREADY_STOLE=1; print "You try to hide your fish from the albatross, with the hope it will get discouraged. But you make the mistake of looking down to where you were going to hide it -- and the albatross "; print_ret (string) MSG_ALBATROSS_VICTORY_LAP;} Cut1, Cut2, Open, Eat, Burn, Gut: if (firewood in location && FIRE_IS_READY && self in player) { ; rtrue; } ! TODO conditions "It's fresh fish alright, but you don't really want to eat it raw. You should probably make a campfire."; Dry: "You don't need to dry this fish, since you're going to cook it and eat it as soon as possible."; ], has edible; !======================================================================= ! The albatross and its flute ! already defined Global ALBATROSS_ALREADY_STOLE=0; Object Albatros "albatross" with description "A magnificent beast, a huge white bird with a wingspan so big you can't help but feel threatened by it. But so far, it seems pretty staid, respectful even; pushy, but polite. It knows that you know what it wants, and will wait until you're ready to give it up.", article "an", parse_name [ n ; n = 0; !also albatross cause 6-character resolution while (NextWord() == 'albatros' or 'bird' or 'white' or 'large' or 'beast' or 'magnificent' or 'pushy' or 'rude') n++; return n; ], daemon [; if (ALBATROSS_ALREADY_STOLE) { ! he just stole, after drop or whatever; we stop the daemon so this only happens once remove self; move TinyFlute to player; scope_modified = true; print "^The albatross takes flight and disappears somewhere, behind some rocks. You sigh; you're going to have to try to fish again.^^But suddenly, the albatross comes back, and lands near you. In its beak, there is some kind of stick; it throws it your way, and you catch it. You could swear you saw the albatross nod at you before taking flight again -- this time for good."; StopDaemon(Albatros); @new_line; @rtrue; } if (location ~= OnlyRoomWaistDeep) { @new_line; if (parent(self) == nothing) { ! first time we reach the shore move self to location; scope_modified = true; "A shadow passes over you. You look up, and see a huge, white albatross descending towards you. The bird is magnificent, and its enormous wingspan makes it look bigger than you; you recoil a little bit, and instinctively protect your fish. The albatross lands near you, and looks at you intently."; } else { ! albatros has been moved somewhere, so you already reached the shore if (location ~= parent(self)) { ! follow the player move self to location; scope_modified = true; print "The albatross follows you"; print (string) random(" easily, flapping its wings only a couple times to catch up with you", ", letting out a little squawk that sounded almost amused", " like a dog, in no hurry", " confidently"); "."; } else { ! the player didn't move ! saves 56 bytes print "The albatross "; print (string) random("looks at you, then looks at the fish, then back at you", "tries to get close to you, but decides against it at the last second", "squawks at you"); "."; } } } ], before [; Push, Pull, Turn: <>; Search: PrintMsg(MSG_TURN_ANIMATE); rtrue; ], life [; Attack: "You try to shoo away the bird, running towards it while shouting; but it just lands right back behind you, and gives you a quizzical look."; Answer, Tell, Ask, AskTo: "The bird just stares at you."; Show: if (noun == aFish) { "The albatross moves forward, then backs up a bit; it squawks to confirm that's what it'd like to have."; } else { "The albatross seems uninterested."; } ThrowAt, Give: if (noun == aFish) { ALBATROSS_ALREADY_STOLE=1; remove aFish; scope_modified = true; "You raise the fish above your head, and the albatross perks up. You throw the fish in front of you, and the albatross catches it in mid-air. You watch the albatross gulp the fish down quickly; it then lets out a satisfied squawk."; } else { "The albatross seems uninterested."; } ], has animate concealed; Constant MSG_ALBA_SURVEYS ", and it flies above you a few times, surveying the situation. "; [ Albashrug ; if (location ofclass Inside || location ofclass InMansion || location ofclass InsideLab) { print_ret "Nothing happens. Maybe the albatross cannot hear you from inside."; } else { print_ret "After a few seconds, you see the albatross approaching", (string) MSG_ALBA_SURVEYS, "It then lands near you, and looks at you straight in the eye. Its glare is confused, maybe even angry; it tilts his head to the side, seemingly wondering why you called for help and what it is that you're expecting. It finally lets out a frustrated squawk and flies away."; } ]; Global ALBATROSS_ALREADY_HELPED=0; Object TinyFlute "small stick" with description "This is the stick the albatross dropped on you after you gave it the fish. It's a few inches long, and hollow, with a few holes on its side... Oddly enough, it looks like some sort of flute.", parse_name [ n ; n = 0; while (NextWord() == 'stick' or 'flute' or 'small' or 'tiny' or 'holey' or 'wooden' or 'albatros') n++; return n; ], before [; Blow, Play: print "You blow in the small stick"; if (ALBATROSS_ALREADY_HELPED) { " to make the noise again, but this time, the albatross doesn't come back. Maybe it considers that its debt has been repaid already.";} else { print ", which makes a high-pitched noise that you can barely hear. "; #ifdef IS_DEMO; if (location == OnlyRoomWaistDeep) { if (vecteur_normal % 4 == FISHES_VECTEUR_NORMAL && parent(aFish) == nothing) { ALBATROSS_ALREADY_HELPED=true; move aFish to player; remove self; scope_modified = true; "The albatross is flying in circles above you. It gets closer to the surface, and gives you a confused look. You shrug. After a few seconds, it swoops and catches a fish easily; it throws the fish towards you, and you have to let go of the stick to catch it. The albatross flies away."; } } #endif; #ifndef IS_DEMO; ! each line starts with "the albatross", ut you can't write it before cause you need to check the conditions, and if you're not in a position to be helpef, albashrug (which doesn't start with 'the albatross') is run switch(location) { Shop, Woodshop: if (location == Shop) { if (F_SHOP_SMASHED) { Albashrug(); rtrue;} F_SHOP_SMASHED=true; } else { if (F_WOODSHOP_SMASHED) { Albashrug(); rtrue;} F_WOODSHOP_SMASHED=true; } ALBATROSS_ALREADY_HELPED=true; print_ret "The albatross appears a few seconds later", (string) MSG_ALBA_SURVEYS, "You end up losing its trace -- but wait, here it comes, swooping down towards you and... CRASH goes the window of the shop. The albatross emerges from inside the shop, shakes its feathers, and flies out, apparently perfectly fine."; Outsidethepub: if (Sparekeyforthepub notin player) { ALBATROSS_ALREADY_HELPED=true; move Sparekeyforthepub to location; scope_modified = true; "The albatross appears, and lands near you. It considers the pub's door, then suddenly flies away. You don't see it for several minutes; when it finally lands behind you, you see that there is a key right by its webbed feet. The albatross then flies away."; } BaseOfTower: if (F_LADDER_FIXED == 0) { ALBATROSS_ALREADY_HELPED=true; F_LADDER_FIXED =1; "The albatross appears, and perches itself onto the ladder. It looks down at the missing rungs, then takes flight and swoops down into the forest. After a few minutes, the albatross emerges with a rather thick stick wedged awkwardly in its beak. You take the stick, which is weighty and cylindrical, and a few inches long. Could it be... You try to insert it in the ladder -- and it's a perfect fit! You turn around, but the albatross is already gone."; } Scenicview: if (Lighter notin player) { ALBATROSS_ALREADY_HELPED=true; move Lighter to location; scope_modified = true; "The albatross is coming your way. It lands, then looks at the remains of the fire; it flaps its wings right away, apparently knowing exactly what to do. After a few minutes, the albatross comes back, and drops something at your feet: a lighter. The albatross flies away before you even have time to thank it."; } Fencedarea, Field: if (Guardkey notin player) { ALBATROSS_ALREADY_HELPED=true; move Guardkey to location; scope_modified = true; "The albatross is here, and lands on the other side of the fence. It considers the gate in the fence, and takes flight, going high -- maybe to take a good look around. It finally swoops down, then comes back to you with a key in its beak. It drops it at your feet, then flies away quickly."; } Houses: if (F_CRUDE_DOOR_OUT == 0) { ALBATROSS_ALREADY_HELPED=true; F_CRUDE_DOOR_OUT = 1; "The albatross lands softly behind you, making you jump slightly. It considers the crude door, then walks casually towards the hinges. It flaps its wings, then with its strong beak grabs one of the hinges; the pin inside of it is dislodged quickly and falls to the floor. The albatross removes the other pin, and now the hinges aren't holding the door anymore. Amazed and slightly befuddled, you don't even manage to say a proper thank-you before the albatross flies away."; } OnlyRoomWaistDeep: if (vecteur_normal % 4 == FISHES_VECTEUR_NORMAL && parent(aFish) == nothing) { ALBATROSS_ALREADY_HELPED=true; move aFish to player; remove self; scope_modified = true; "The albatross is flying in circles above you. It gets closer to the surface, and gives you a confused look. You shrug. After a few seconds, it swoops and catches a fish easily; it throws the fish towards you, and you have to let go of the stick to catch it. The albatross flies away."; } } #endif; ! we can't put this inside a switch, issue #35 on github ! catch-all Albashrug(); rtrue; } ], has; !======================================================================= ! Act 1 - Lower level ! a few more scenery objects ! TODO: duplicate?? could we do it with the one on the shore? If we need an object near the end, let's do that Object WoodenDock "wooden dock" with found_in [; if (location == OnlyRoomWaistDeep && vecteur_normal == 4) { rtrue; } else {rfalse; } ], name 'pier' 'dock' 'pontoon' 'wooden', description "There is a wooden dock on the beach, though you can't see it very well from here.", before [; Examine: ; default: "You're much too far to interact with the dock."; ], has static concealed; Object Sandbank "submerged sandbank" with found_in [; if (location == OnlyRoomWaistDeep && vecteur_normal == 1) { rtrue; } else {rfalse; } ], parse_name [ n ; n = 0; ! covers 'sandbank' and 'sandbar' while (NextWord() == 'sandba' or 'submerged' or 'underwater' or 'shoal' or 'sand' or 'bank' or 'bar') n++; return n; ], description [; print_ret (string) MSG_SANDBANK_DESC; ], before [; Touch, Climb, Enter: "You already are standing on the sandbank."; Receive: ; rtrue; Take: PrintMsg(MSG_TOO_IMMENSE); "taken."; Turn, Push, Pull: PrintMsg(MSG_TOO_IMMENSE); print_ret (verbname) verb_word, "ed."; ], has scenery concealed; Object CoveObj "small cove" with found_in [; if (location == Cove or Endofthebeach || (location == OnlyRoomWaistDeep && vecteur_normal == 6)) {rtrue; } else {rfalse; } ], name 'cove' 'small' 'bay', description [; print_ret (string) MSG_COVE_DESC; ], before [; Enter, Swim: PlayerTo(EnterOcean()); rtrue; Receive: print_ret (string) MSG_PUT_IN_SEA; Drink: print_ret (string) MSG_OCEAN_WATER; ], has scenery concealed; Object matchbook "matchbook" with name 'match' 'matches' 'matchbook' 'sleeve', invent "a matchbook (in your pocket, containing a few matches)", description "The little sleeve only contains a few matches, and they look a bit wet. It'll have to do...", before [; Drop, Insert, PutOn, LetGo: "These matches are your only chance to make a fire."; Open, Search: ; rtrue; Insert: "Nothing else fits in the matchbook."; Burn, Attack: if (parent(firewood) == location or player) {; rtrue;} else {"You'd rather save your matches to start a campfire.";} Count: "There's about half a dozen of them left."; ], has openable; ! the 'not very good climber' can't be refactored, ugh Constant MSG_CLIIFS_ARE_TALL "The cliffs around the island are very tall, and you're not a very good climber."; Class Shore with u_to [; print_ret (string) MSG_CLIIFS_ARE_TALL; ], has light; Shore Immaculatebeach "Immaculate beach" with description "This is the south side of the island you are now stuck on. The immensity of the Atlantic Ocean makes you feel minuscule, a needle in a haystack, with no chance of being rescued. A steep hill covered by a dense forest stands to the north; climbing it would likely take hours, and you don't really know what you could find there, so you might as well explore your new home. The beach extends to the northeast, where you can see a large boulder, and to the west.", vec_norm 0, n_to "The forest is pretty impenetrable this way.", s_to [; return EnterOcean(); ], ne_to Endofthebeach, w_to Beachnearforest, has ; Object -> Boulder "boulder" with name 'boulder' 'large' 'rock' 'formation', found_in Immaculatebeach Endofthebeach, description [; GoSee(Endofthebeach, "A large rock formation, worn smooth by the tide but not quite detached from the rest of the island, marks the end of the beach. Behind it, the eastern shore of the island mostly consists of jagged rocks and shallow tidal pools."); ], react_before [; if (noun == self && action ~= ##Examine && location ~= Endofthebeach) { print_ret (string) MSG_WRONG_LOCATION; } ], before [; Climb: print_ret (string) MSG_NOT_VERY_GOOD_AT_CLIMBING, " smooth rocks."; Receive, ThrownAt: "If you put something there, you'll never be able to get it back."; ], has static concealed supporter reactive; Shore Beachnearforest "Sandy beach by the forest" with description "The small beach is angled down, with small waves crashing periodically on the shore. You can clearly see the high tide line, delineated by small shrubs that grow close to the sand. Behind these, to the north, is a clearing leading into the forest. The sandy beach extends eastward; to the west, below tall cliffs, it becomes smaller and rockier.", vec_norm 0, n_to Edgeofthewoods, s_to [; return EnterOcean(); ], e_to Immaculatebeach, w_to Southwesterncliffs, has ; Object -> ShrubsBeach "small shrubs" with parse_name [ n ; n = 0; while (NextWord() == 'small' or 'shrub' or 'shrubs' or 'bush' or 'bushes' or 'branch') n++; ! also branches return n; ], description "Some small shrubs with thin branches are growing close to the sand, forming a line that seems to be the high tide line.", before [; Cut1, Cut2, Attack, Take: "These branches seem much too small to make a usable fire."; ], has static concealed; Shore Edgeofthewoods "Edge of the woods" with description "The woods begin here, in this small clearing; the trees, dense and bearing flowers of strikingly vibrant colours, give you a nice respite from the sun beating down on your head. The floor of the forest is rather dense undergrowth, which you imagine teeming with life; you're pretty sure you can see something moving under the large mossy rock here. You can go deeper in the forest by going north, or back to the beach by going to the south.", n_to Deepinthewoods, s_to Beachnearforest, u_to [; ; rtrue; ], before [; Smell: if (noun == 0) "The woods here smell damp, with a hint of a flowery smell."; ], has ; Object -> Clearing "clearing" with name 'clearing' 'undergrowth', description [; ; rtrue; ], before [; Take: PrintMsg(MSG_TOO_IMMENSE); "taken."; Turn, Push, Pull: PrintMsg(MSG_TOO_IMMENSE); print_ret (verbname) verb_word, "ed."; ], has scenery concealed; Object -> MossyRock "mossy rock" with parse_name [ n ; n = 0; while (NextWord() == 'large' or 'mossy' or 'lopsided' or 'rock' or 'flat') n++; ! also branches return n; ], description "A large, lopsided rock with a rather flat top seems to provide darkness and moisture to a whole bunch of critters underneath it.", before [; LookUnder,Search: <>; ], has static concealed; Constant MSG_SHOULD_BE_ENOUGH ", which should be enough."; Global EVER_HOOKED_A_WORM = 0; ! we already put one worm on the hook Object -> Critters "critters" with parse_name [ n ; n = 0; while (NextWord() == 'worm' or 'maggot' or 'worms' or 'critter' or 'bug' or 'bugs' or 'insect') n++; ! also maggots, critters, insects thanks to the 6-char resolution return n; ], description "There seems to be movement under the rock; keeping your distance, you manage to spot a few thick worms.", before [; Eat: "It is a source of protein indeed, but you think you're going to save it for when you get desperate. Really desperate."; Take: if (parent(WigglyWorm) == nothing) { if (_AtFullCapacity(player) == false) { move WigglyWorm to player; scope_modified = true; "You crouch by the rock, and see a few bugs scatter. You manage to grab a wiggly worm between two fingers. You can't really carry anything else with that hand, what with your arm extended all the way away from your body. Yuck."; } } else { print_ret "You already grabbed a worm", (string) MSG_SHOULD_BE_ENOUGH;} ], has concealed pluralname; Object WigglyWorm "worm" with name 'wiggly' 'worm' 'thick' 'bait', description [; if (self in player) {"A thick, wiggly worm that you're carefully holding between two fingers.";} else {"The worm isn't wiggling since you inserted on the hook.";} ], before [; Drop: remove self; scope_modified = true; "You drop the wiggly worm to the floor. It wriggles somewhere and you end up losing sight of it."; Eat: <>; Take: "The worm is fine where it is."; ! only gets used triggered if it's on the hook or on your hand Cut1, Cut2, Attack, Insert, PutOn: if (CommonAncestor(Fishingrod, player) ~= 0 && (second == 0 or FishingRodReel or Fishingrod)) { if (EVER_HOOKED_A_WORM==0) { EVER_HOOKED_A_WORM=true; score = score + 1; } move self to FishingRodReel; scope_modified = true; "The worm will make nice bait for the fish; you stab the worm onto the hook."; } else { if (keep_silent ==0) { print_ret (string) MSG_PUSHDIR_DEFAULT; } rtrue;} ! not sure what this would accomplish ], has animate; Constant MSG_FLOWERS_SHADES " display every shade between dark orange and bright yellow."; Object Trees "sturdy trees" with name 'trees' 'sturdy' 'tree' 'bark', found_in Edgeofthewoods Deepinthewoods, description [; print_ret "The trees here look rather old and sturdy; their small flowers", (string) MSG_FLOWERS_SHADES;], before [; Smell: "You smell the tree's trunk; it smells like wet wood."; Cut1, Cut2: ; rtrue; ! or print_ret (string) MSG_FELL_A_TREE; ? no, "cut trees" should be 'cut branches' Climb, Enter: print_ret (string) MSG_NOT_VERY_GOOD_AT_CLIMBING, " trees. I suppose you'll eventually learn if you spend years trapped here."; Receive: ; rtrue; ], has static concealed transparent; Global EVER_HOOKED_A_FLOWER=0; Object -> flowers "flowers on the trees" with parse_name [ w n ; n = 0; w = NextWord(); while (w) { ! this also covers "flowers" cause 6-character resolution if (w=='orange' or 'yellow' || (parent(aFlower) == nothing && w=='flower')) { n++; w=NextWord(); } else {return n;} } return n; ], description [; print_ret "The small flowers that cover the trees", (string) MSG_FLOWERS_SHADES; ], before [; Smell: "You cut a few flowers off the trees and smell them; their smell is fresh but faint."; Eat: "You have no idea if these flowers are safe to eat or not; you'd rather not eat them."; Cut1, Cut2: <>; Take: if (parent(aFlower) == nothing) { ! has been removed or never there if (_AtFullCapacity(player) == false) { move aFlower to player; scope_modified = true; "You pick a flower from the tree, choosing a particularly bright one."; } else { PrintMsg(MSG_TAKE_NO_CAPACITY); rtrue; } ! need to put this here because aflower is the one we get - otherwise "seems to be part of the tree" } else { print_ret "You already picked a flower", (string) MSG_SHOULD_BE_ENOUGH; } ], has pluralname ; Object aFlower "bright flower" with name 'flower' 'orange' 'bright' 'yellow', description "This small flower, that you got from the trees in the forest, is bright yellow.", before [; Eat: <>; Smell: "The flower has a faint but fresh smell."; ! TODO: refactor with the worm? this is very similar code! Cut1, Cut2, Insert, PutOn, Attack: if (CommonAncestor(Fishingrod, player) ~= 0 && (second == 0 or FishingRodReel or Fishingrod)) { if (EVER_HOOKED_A_FLOWER==0) { EVER_HOOKED_A_FLOWER=true; score = score + 1; } move self to FishingRodReel; scope_modified = true; "You pierce the hook through the flower; its bright colour should hopefully lure fish to take the bait.";} else { if (keep_silent == 0) {"You'd rather keep the flower until you have a better idea."; } rtrue;} Drop: remove self; scope_modified = true; "You drop the flower, and the wind blows it away."; ], has ; ! TODO: gather wood/firewood / break branch / take wood / take branches / cut tree/branches with knife !Global ALREADY_GOT_FIREWOOD=0; Global FIREWOOD_FOR_OIL=0; Object branches "branches of the trees" with name 'branch' 'wood' 'kindle' 'firewood', description [; <>; ], found_in Edgeofthewoods Deepinthewoods, before [; Take, Cut1, Cut2, Attack: if ((ALREADY_GOT_FIREWOOD && F_ACT2_STARTED ==0) || (F_ACT2_STARTED && FIREWOOD_FOR_OIL)) { "You already gathered all the firewood you needed."; } else { if (_AtFullCapacity(player) == false || Fishingknife in player) { ALREADY_GOT_FIREWOOD=1; move firewood to player; scope_modified = true; print "You spend quite a long time trying to find wood that could be used to light a fire. You manage to gather enough wood, but most of it is damp."; if (Fishingknife in player) { move Fishingknife to location; scope_modified = true; print " You put your knife on top of a rock so you can carry all that wood."; } if (F_ACT2_STARTED == 0) { score = score +5;} else {FIREWOOD_FOR_OIL=1; } @new_line; @rtrue; } else { PrintMsg(MSG_TAKE_NO_CAPACITY); rtrue; } } ], has pluralname concealed ; Constant MSG_TRYING_TO_SPACE_STICKS " trying to space the sticks apart so they dry"; ! already defined: Global FIRE_IS_READY = 0; Object firewood "sticks of firewood" with name 'firewood' 'wood' 'kindle' 'sticks', dampness 5, description [; print "The wooden sticks you picked up in the forest to make a fire look "; switch(self.dampness) { 3: print "rather damp"; 2: print "a bit damp"; 1: print "quite a bit drier now"; 0: print "dry"; default: print "very damp"; } "."; ], daemon [; if (self in player) { StopDaemon(self); } else { if(parent(self) == Northerncliffs or Northeasterntip or Northwesterncliffs) { self.dampness = self.dampness-2; } else { if (parent(self) ~= Deepinthewoods && parent(self) ~= Edgeofthewoods) { self.dampness = self.dampness-1; } } if (self.dampness <= 0) { self.dampness=0; StopDaemon(self); } } ], after [; Drop: if (location ~= OnlyRoomWaistDeep) { if (self.dampness < 2) { FIRE_IS_READY=true; "You start arranging the wood to make a fire. You learned how to do it years ago, and the muscle memory is still there. After a few minutes, the wood is ready."; } else { print "You put the wood on the "; if (location == Deepinthewoods or Edgeofthewoods) { print_ret "forest floor,", (string) MSG_TRYING_TO_SPACE_STICKS, "; but there is not much sun or wind here to dry the wood."; } print "beach,", (string) MSG_TRYING_TO_SPACE_STICKS, "."; StartDaemon(self); if (location == Northerncliffs or Northeasterntip or Northwesterncliffs) { " The sun is shining pretty directly on them."; } else { " There is some sun here, but there would be more on the north side of the island."; } } } ], before [; Dry: ; rtrue; Take: if (FIRE_IS_READY) {"This looks fine; in fact you are quite proud of the way you arranged that.";} Burn: if (FIRE_IS_READY == 0) { if (self.dampness < 2) {"You need to arrange the firewood first.";} else { "The wood looks much too damp to burn right now.";} } else { ! we can cook a fish, or the metal pot/bowl if (aFish in player && matchbook in player) { ! second condition is just in case someone wants to eat fish again at act 2 if (Albatros in location) { remove aFish; ALBATROSS_ALREADY_STOLE=1; scope_modified = true; print_ret "You are going to eat this fish, albatross or not. ", (string) MSG_DROP_ROD_ALBATROSS_PERKS_UP, (string) MSG_ALBATROSS_VICTORY_LAP; } else { ! need fish, matchbook, and fishingknife ; it's a bit fiddly but the knife is useless otherwise if (Fishingknife notin player) {"You're about to cook the fish when you realize you don't have anything to gut it with.";} ! this test is not needed: we can only make one fire with this firewood (see response to "take branches") ! if (matchbook notin player) {"Unfortunately, you realize that you used the last of your matches.";} FIRE_IS_READY=0; F_ATE_SOMETHING=true; remove self; remove matchbook; remove aFish; scope_modified = true; score = score + 5; "You take your matchbook out of your pocket, and take a deep breath. The matches are wet, and you try them one by one... until, by chance, the last one catches fire! You very cautiously start the fire, and you stoke the flames for several minutes, until you have a good fire going. You gut the fish using the knife, and use a long branch to cook the fish above the flame. The process takes a while, and your stomach gurgles, but when you finally cut the fish and start eating it, it tastes like the best fish you have ever had."; } } #ifndef IS_DEMO; if (parent(aPot) == player or location || parent(Metalbowl) == player or location) { if ((parent(aPot) == player or location && child(aPot) ~= 0) || (parent(Metalbowl) == player or location && child(Metalbowl) ~=0)) { if (parent(Lighter) == location or player or backpack) { if ((parent(aPot) == player or location && Cookingoil in aPot) || (parent(Metalbowl) == player or location && Cookingoil in Metalbowl)) { remove self; MeltOil(parent(Cookingoil)); scope_modified = true; rtrue; } } else { print_ret (string) MSG_NOTHING_FOR_FIRE;} } } #endif; "The wood is ready, but you have nothing to cook on it."; } #ifndef IS_DEMO; Receive: if (noun == aPot or Metalbowl) { if (Cookingoil in noun) { ; rtrue; } else { "You could certainly put that dish on top of the fire to cook something, but what?"; } } #endif; Cut1, Cut2, Attack: ; rtrue; ], has pluralname ; Constant MSG_EASY_TO_GO_UP "The hill is steep, but now that you have cleared the steps, it is very easy to go up."; Constant MSG_THERE_MAY_BE_STAIRS ". There might be a staircase embedded into the hill, but clearing the way won't be an easy task."; Constant MSG_HILL_GETS_V_STEEP "he hill gets very steep, "; Shore Deepinthewoods "Deep in the woods" with description [; if (F_CLIMBED_STEPS == 0) { print "You are unable to get much further here; in front of you, t", (string) MSG_HILL_GETS_V_STEEP, "covered in grass and mud"; if (WE_KNOW_IT_IS_STAIRS == 0) { print ", and these white stones embedded into it have very sharp edges that look like they could hurt."; } else { print_ret (string) MSG_THERE_MAY_BE_STAIRS; } } else { print (string) MSG_EASY_TO_GO_UP; } " The forest is dense around you, but you can always go back to the clearing to the south."; ], s_to Edgeofthewoods, u_to [; ; rtrue; ], has ; Object -> Hill "hill" with name 'mudslide' 'grass' 'hill', description [; if (F_CLIMBED_STEPS == 0) { print "T", (string) MSG_HILL_GETS_V_STEEP, "and you doubt you could climb it"; if (WE_KNOW_IT_IS_STAIRS == 0) { "; the wet grass and patches of mud would certainly make you slip onto these sharp white stones that you can see, almost perfectly spaced, all the way up to the hill."; } else { print_ret " like that", (string) MSG_THERE_MAY_BE_STAIRS; } } else { print_ret (string) MSG_EASY_TO_GO_UP; } ], before [; Enter, Climb: ; rtrue; ], has scenery concealed; Object hammock "hammock" with name 'hammock' 'net' 'fishing', description "This is now your hammock, and it looks as comfortable as they get.", before [; Enter, Climb, SleepOn: ; rtrue; Cut1, Cut2: "This net is now your bed; you do not want to cut it."; Take, Push, Pull, Turn, Untie: "It's perfect the way it is."; ], has static ; [ StairsDetected; if (WE_KNOW_IT_IS_STAIRS == 0) { WE_KNOW_IT_IS_STAIRS=1; score = score+1; } ]; Object HiddenStairs with short_name [; if (WE_KNOW_IT_IS_STAIRS) { print "hidden staircase"; rtrue; } else { print "white stones"; rtrue; } ], found_in Deepinthewoods Topofthestairs, parse_name [w n; n = 0; w = NextWord(); while (w) { if (w == 'sharp' or 'white' or 'edges' or 'rocks' or 'rock' or 'stone' or 'stones' or 'slab' or 'step' or 'slabs' or 'steps' or 'pyramidal' or 'mud' or 'earth' || (WE_KNOW_IT_IS_STAIRS && (w == 'hidden' or 'staircase' or 'stairs')) ) { n++; w=NextWord(); } else {return n;} } return n; ], description [; if (WE_KNOW_IT_IS_STAIRS) { if (F_CLIMBED_STEPS) {"It took you two days of labor to remove enough of the mud covering the steps that you could use the stairs. Now, you can go up and down as you wish."; } else {"The white stones, with their unnatural edges, are almost certainly a staircase that's been covered in mud over the years. You will have to carve yourself a path here.";} } else {StairsDetected(); "You contemplate one of the white stones poking out of the mud, and suddenly its shape, an almost perfect pyramid, seems unnatural, almost too sharp. Almost... carved? Like the edge of a carved slab of rock... And looking up, seeing all these edges appear at a regular interval... Could these be... stairs? My, yes! It looks like there is a staircase here, covered by years and years of rain and mud.";} ], before [; Enter, Climb: if(F_CLIMBED_STEPS) { print "You climb "; if (location == Deepinthewoods) { print "up"; } else { print "down"; } print " the long flight of stairs, and reach the "; if (location == Deepinthewoods) { print "village"; } else { print "forest"; } print " after a few minutes.^"; if (location == Deepinthewoods) { PlayerTo(Topofthestairs); } else { PlayerTo(Deepinthewoods);} rtrue; } else { if (WE_KNOW_IT_IS_STAIRS) { "The steps, if it is indeed a full staircase going up and down the hill, are covered in several inches of mud.";} else { "The mud looks very slippery, and those steps look like they could break your wrist while falling."; } } Pull, Push, Take, Rub, Remove, Cut1, Cut2, TakeWith: if (F_CLIMBED_STEPS == 0) { if (second) { if (second ~= Fishingknife) { "This is not the right tool for getting the mud off.";}} if (F_ATE_SOMETHING && F_SLEPT) { if (Fishingknife in player) { if (location == Topofthestairs) { F_CLIMBED_STEPS=true; print "This is a daunting task, but it would be more convenient in the long run than the platform.", (string) MSG_UNCOVERING_STAIRS, "bottom.^"; PlayerTo(Deepinthewoods); rtrue; } else { print "You look up, and the tall hill seems daunting; but looking closely, you see some steps poking out of the mud, all the way up.", (string) MSG_UNCOVERING_STAIRS, "top; you let out a victory shout, rub your hands on your trousers to get some of the mud off, and finally climb the last step."; StairsDetected(); F_CLIMBED_STEPS=true; StartAct2(); PlayerTo(Topofthestairs); rtrue; } } else { "Clearing this with your bare hands wouldn't work very well; you need some kind of tool to scrape at the mud."; } } else { StairsDetected(); print "You clear off some of the mud near one of the white rocks, revealing that the rock has indeed been carved in straight lines, in a rectangular shape. You sigh contemplating the size of the task at hand; you're much too "; if (F_SLEPT==0) { print "tired"; if (F_ATE_SOMETHING == 0) {print " and "; }} if (F_ATE_SOMETHING == false) {print "hungry";} " to undertake such a task right now."; } } else { <>; } ], has pluralname scenery concealed; Shore Southwesterncliffs "Southwestern cliffs" with description "You are at the bottom of tall and almost vertical cliffs, standing on a small flat stretch of sand and rocks that you can barely call a beach. East of you is a sandy beach; to the northwest, you can see a small strait.", vec_norm 1, e_to Beachnearforest, sw_to [; sandbankDepth=0; return EnterOcean();], ! reinitialise the sandbankdepth, it might not be 0 (if you went nw from far away from the sandbank for instance) nw_to Narrowstrait, has ; Shore Narrowstrait "Narrow strait" with description "Here, the cliffs form an almost circular shape, holding a small pool of water that probably gets replenished with every high tide. It empties via a shallow channel of water that cuts the beach in two and runs off into the sea; interestingly, looking at the direction the channel goes made you notice some movement further in the water. The cliffs continue to the north and to the southeast.", vec_norm 2, n_to Northwesterncliffs, se_to Southwesterncliffs, w_to [; return EnterOcean(); ], e_to [; <>; ], has ; Object -> Strait "strait" with parse_name [ n ; n = 0; while (NextWord() == 'strait' or 'channel' or 'water' or 'narrow' or 'mouth' or 'tidal' or 'saltwater' or 'pool') n++; return n; ], found_in Narrowstrait Northwesterncliffs Southwesterncliffs, description [; GoSee(Narrowstrait, "There is a small circular break in the cliffs here, holding a pool of water, that is connected to the sea by a shallow channel; the pool probably fills with every high tide, then the water progressively runs off via the channel."); ], react_before [; if (noun == self && action ~= ##Examine && location ~= Narrowstrait) { print_ret (string) MSG_WRONG_LOCATION; } ], before [; Enter, Search, Swim: "You enter the tidal pool and wade in it for a few minutes, but you can't spot anything out of the ordinary here."; Receive: "You don't see why putting anything in this tidal pool would help."; Drink: print_ret (string) MSG_OCEAN_WATER; ], has scenery concealed container open reactive; Shore Northwesterncliffs "Northwestern cliffs" with description "A small beach runs along the cliffs to the northwest of the island. South of you is a narrow strait, and the beach continues to the northeast.", vec_norm 3, s_to Narrowstrait, ne_to Northerncliffs, nw_to [; return EnterOcean(); ], has ; Constant MSG_MOORED_TO_WOODEN_DOCK " moored to a long wooden dock. "; Shore Northerncliffs "Northern cliffs" with description [; print "A tall cliff made of chalk runs along the northern edge of the island; down below, where you are standing, is a small beach littered with rocks and pebbles. "; if (self has visited) { print "Here, a small fishing boat is", (string) MSG_MOORED_TO_WOODEN_DOCK; } else { print "And then, you spot an incredible sight: a small fishing boat,", (string) MSG_MOORED_TO_WOODEN_DOCK, "Unbelievable! A trace of human life on this island! And then you spot something else. ";} if (player in Fishelevator) { print "You have climbed on a platform that is "; } else { print "A rickety-looking platform is "; } if (FISH_ELEVATOR_UP) {print "high up";} else {print "resting on the beach"; } print ", right against the side of the cliff; "; if (F_CLIMBED_CLIFF == 0) {print "it looks like ";} "it rises all the way up to the top of the cliff with a rope-and-pulley mechanism. The beach continues southwest and east."; ], vec_norm 4, n_to [; return EnterOcean(); ], e_to Northeasterntip, sw_to Northwesterncliffs, u_to [; if (parent(player) == Fishelevator) { <>; } else { "The obvious way would be by getting on the platform and pulling the rope.";} ], before [; default: if (parent(player) == Fishelevator && noun ~= FarAwayElements && parent(noun) == Northerncliffs or Boat && action ~= ##Examine && ~~(noun == 0 or Rope or Fishelevator) ) { print_ret (The) noun, " ", (isorare) noun, " out of reach.";} ], has ; Object -> Pier "wooden dock" with name 'pier' 'dock' 'pontoon' 'wooden', description "There is a wooden dock here, about twenty feet long; the wood looks old and wet, but it is still in very good shape. A small fishing boat is moored here.", before [; LookUnder, Search, Enter: "You walk along the dock, looking under it to see if you can spot anything interesting, but there's nothing."; ], has static concealed; Object -> Boat "boat" with parse_name [ n ; n = 0; while (NextWord() == 'boat' or 'moored' or 'wooden' or 'fishing' or 'rowboat' or 'stern') n++; return n; ], describe [; rtrue; ], description [; print "A small fishing boat is moored here; unfortunately, there is a crack in the hull that lets water come in the boat, making it unusable. A wide compartment made of wood is at the stern of the boat. "; ; rtrue; ], before [; LookUnder: "You kneel on the dock and look in the water, under the boat's hull. You can't spot anything, except seaweed."; Enter: "That boat doesn't look like it'll sail again."; Open, Search: PerformAction(action, Compartment); rtrue; ! redirect open and search to the compartment Untie: "That would be unkind to that poor little boat."; ], ! Take: something better than "that's fixed in place"? has static enterable container open transparent; Object -> -> Compartment "compartment" with name 'compartment' 'trunk' 'container' 'case', description [; print "The compartment "; if (self has open) { if (PrintContents("contains ", self) == 0) { print "is empty"; } } else { print "is closed";} "."; ], after [; Open: print "You run your fingers around the compartment, and manage to find a way to pop it open."; if (PrintContents(" Inside, you find ", self)) "."; @new_line; @rtrue; Search: ; rtrue; ], has static openable container; Object -> -> -> Fishingrod "fishing rod" with name 'fishing' 'rod' 'pole' 'reel', description [; print "This fishing rod is about four to five feet long, and it is in suprisingly good condition. Its reel still turns rather well, and the hook and the line are on there as well -- which is good, as you're not sure you would have known how to attach them there. It will be perfect for casting bait. "; ; rtrue; ], before [; Cut1, Cut2, Attack: print_ret (string) MSG_SURVIVAL; ! why is it "fishing rod: You kneel blabla"? punybug? Drop: if (Albatros in location && location ~= OnlyRoomWaistDeep) {remove aFish; scope_modified = true; ALBATROSS_ALREADY_STOLE=1; print_ret (string) MSG_DROP_ROD_ALBATROSS_PERKS_UP, (string) MSG_ALBATROSS_VICTORY_LAP;} ThrowAt: ; rtrue; ! throw line at fish Cast: ; rtrue; ! receive -> le receive du hook? ], has open transparent; ! unnecessary flourish? Object -> -> -> -> FishingRodReel "hook on the fishing rod" with name 'line' 'hook', description [; print "There is "; if (PrintContents("", FishingRodReel) == 0) {print "nothing";} " on the hook."; ], before [; Take, Remove, Untie, Attack: "This is attached to the fishing rod, and you don't particularly want to remove it from there -- you're not sure you'd know how to put it back together."; ! TODO: stab/kill worm on hook / rig worm on hook / add worm to hook Receive: if (~~(noun == WigglyWorm or aFlower)) {print_ret "You cannot put this on ", (the) self, ".";} ThrowAt: ; ! throw hook at fish Cast: ; rtrue; Bait: if (second) { ; rtrue; } ], has concealed; Object -> -> -> Fishingnet "fishing net" with parse_name [ n ; n = 0; ! also covers weights thanks to 6-char resolution while (NextWord() == 'fishing' or 'net' or 'floats' or 'weight' or 'float' or 'rectangular' or 'knots') n++; return n; ], description "This fishing net is very long, of a rectangular shape, with floats on one side and weights on the other; you doubt you could use it by yourself. You're guessing it is meant to be held vertically in the sea by at least two people. However, you might be able to find another use for it; the rope it's made of is strong, and there are very few holes in it that would compromise its structural integrity.", before [; Cut1, Cut2, Attack, Untie: print_ret (string) MSG_SURVIVAL; ! nicety to the player: "tie net" or "hang net" in the forest works, but not "tie net to worm" Tie: if (second == Trees || (second == 0 && location == Edgeofthewoods or Deepinthewoods)) { remove self; move hammock to location; scope_modified = true; "You take the large fishing net and start making it a hammock. By chance, there are two solid-looking trees that are spaced just right. You open the fishing net, and tie the ends around the trees as solidly as you can. The result looks like a perfect hammock."; } Throw, Cast: if (location == OnlyRoomWaistDeep) { "You struggle with the net for a while, but it's too heavy, and too hard to use alone."; } else { "This fishing net is probably meant to be used in the sea.";} ! throw net Receive: "This fishing net is not a great way to carry things."; ], has ; Object -> -> -> Fishingknife "fishing knife" with parse_name [ n ; n = 0; while (NextWord() == 'fishing' or 'knife' or 'gutting' or 'blade' or 'curved' or 'handle' or 'wooden') n++; return n; ], description "This is probably a knife to gut fish; it has a slightly curved, six inch blade, and a wide wooden handle.", has ; Global ATE_SEAWEED = 0; Object -> Seaweed "seaweed" with name 'seaweed' 'algae' 'nori' 'sushi', description "Some seaweed has grown under the boat's hull, which hasn't been scraped for years.", before [; Dry, Take, Eat: if (ATE_SEAWEED == 0) { ATE_SEAWEED=true; score = score + 1; print "You've heard before that seaweed is full of vitamins. You don't really want to eat it sopping wet, so you spread it on the wooden dock, letting the sun dry it. You wait quite a while, until the seaweed is much more edible. You eat it; it tastes very salty"; if (F_ATE_SOMETHING == 0) {", its texture reminds you of overcooked spaghetti, but your stomach is so happy you moan in contentment.";} else {".";} } else { "You've already had some; it's tasty, but not very filling. Better find another source of food."; } ], has concealed edible; ! already declared: Global FISH_ELEVATOR_UP = 0; ! this is faster than figuring out the parent of the parent / visibility ceiling Object -> Fishelevator "platform against the cliff" with parse_name [ n ; n = 0; ! also covers "elevated platform" because of the 6-char resolution while (NextWord() == 'arch' or 'arc' or 'rickety' or 'metal' or 'bar' or 'thick' or 'bucket' or 'winch' or 'platform' or 'elevator') n++; return n; ], found_in Northerncliffs Outsidethestorehouse, description [; switch(parent(player)) { Northerncliffs: print "Your eyes follow the very long rope running alongside the cliff. It is tied to a sort of arch, a thick curved metal bar fused to both sides of a rudimentary platform; the platform is currently "; if (FISH_ELEVATOR_UP) { print "up by the plateau"; } else { print "on the beach"; } print ". The rope then runs up to a pulley mechanism that is installed at the top of the cliff, then back down; "; if (FISH_ELEVATOR_UP) { print "you tied the other end of the rope to the platform railing so the platform would stay up"; } else { print "that end of the rope lies on the beach"; } print ". The bucket-like platform looks large enough to carry a fisherman and perhaps a large haul of fish, all the way up the cliff."; Fishelevator, Outsidethestorehouse: print (string) MSG_PLATFORM_SHORT_DESC; if (FISH_ELEVATOR_UP) {print (string) MSG_YOU_TIED_THE_ROPE; } else { print " The other end of the rope is lying on the beach."; } } if (PrintContents("^^On the platform, you can see ", self)) { print "."; } @new_line; @rtrue; ], before [; Go: if (selected_direction == out_to) { ; return 3;} if (selected_direction == u_to or d_to) { if (selected_direction == d_to) { if (FISH_ELEVATOR_UP) {FISH_ELEVATOR_UP=false; print "You untie the rope from the platform, making sure you are still holding it firmly. You then progressively release the rope, which makes the platform go down the cliff. You reach the beach down below after a few minutes; good, your hands were starting to hurt. You exit the platform.^"; PlayerTo(Northerncliffs); } else { print (string) MSG_PLATFORM_IS_ALREADY_DOWN; @new_line;} } if (selected_direction == u_to) { if (FISH_ELEVATOR_UP) { print (string) MSG_PLATFORM_IS_ALREADY_UP; @new_line; } else { print "You start pulling on the rope, and the platform slowly ascends; it takes a lot of effort to pull your own weight up. "; if (F_CLIMBED_CLIFF == 0){ if (F_ATE_SOMETHING && F_SLEPT) { ! victory print "However, you feel well-rested, and the effort isn't unsurmountable. The lip of the cliff is getting closer, which only strengthens your resolve. ", (string) MSG_CLIFF_SAFELY; StartAct2(); F_CLIMBED_CLIFF=true; } else { print "You start feeling weak after a few feet, and you decide to slowly, carefully, let the rope go, instead of going for broke and risking plumetting to your death. You should try this again when you feel more rested"; if (F_ATE_SOMETHING == false) {print " and have more energy -- eating a good meal would be a good start"; } print ".^"; } } else { print (string) MSG_CLIFF_SAFELY; } if (F_CLIMBED_CLIFF) { FISH_ELEVATOR_UP=1; PlayerTo(Outsidethestorehouse); } } } return 3; } Sleep: "This platform is much too small to sleep in."; Receive, Enter: if ((FISH_ELEVATOR_UP && location ~= Outsidethestorehouse) || (FISH_ELEVATOR_UP == 0 && location ~= Northerncliffs)) { "You cannot do this here; the platform is not at the right height."; } Lower: if (FISH_ELEVATOR_UP) { <>; } else { print_ret (string) MSG_PLATFORM_IS_ALREADY_DOWN; } Raise: <>; Push, Pull, Turn: PrintMsg(MSG_TURN_DEFAULT); rtrue; ], after [; Enter: "You enter the platform, minding your head."; ], has concealed enterable supporter container open transparent static; ! TODO: if we tried to climb tired, give self general? or count how many times? Object Rope "rope" with name 'rope' 'ropes' 'pulley' 'mechanism', ! also covers 'pulleys' because of 6-char resolution; thanks to this I save a parse_name for 5 items, which saves 42 bytes found_in Fishelevator Northerncliffs Outsidethestorehouse, description [; <>; ], before [; Take,Cut1, Cut2: "You might be able to recover the rope this way, but it would be smarter to leave it like that and use it to climb up and down the cliffs."; Untie: switch (parent(player)) { Outsidethestorehouse: "The rope is tied securely to the platform; you only want to untie it if you are in the platform, going down."; Northerncliffs: <>; ! the new line is written by the routine up there Fishelevator: if (FISH_ELEVATOR_UP) { ; rtrue; } else { <>; } } Enter, Climb: "Climbing up and down the rope sounds like a lot of effort; the platform seems like a surer way."; Pull: if (FISH_ELEVATOR_UP) { print_ret (string) MSG_PLATFORM_IS_ALREADY_UP;} if (parent(player) == Fishelevator) { ; rtrue; ! the new line is written by the routine up there } else { if (parent(player) == Northerncliffs) { "You pull on the rope and, with some effort, manage to raise the platform by a few feet. You don't see the point of going any higher; you carefully let the rope go until the platform is once again on the ground."; } else { ! parent(player) = Outsidethestorehouse "You can't quite reach the other side of the rope; without taking advantage of the pulley, you cannot lift the platform."; } } ! TODO: if need something amusing, each new try gives you an increasingly funny response (eventually you're so weak that you hallucinate you won) ], has concealed static; Object Rocksandpebbles "pebbles on the shore" with name 'rocks' 'pebble' 'rock', ! also covers 'pebbles' thanks to the 6-char resolution found_in [; if (location == Northerncliffs or Southwesterncliffs or Northeasterntip or Northwesterncliffs or Narrowstrait) { rtrue;}], description "The shore here is a small band of sand dotted with white rocks and pebbles that probably fell from the cliffs.", before [; Take: print "You pick up a rather flat pebble and throw it towards the ocean; it ricochets "; print (string) random("two", "three", "five", "six", "seven"); " times on the surface of the sea."; ! TODO: throw ], has concealed pluralname; Shore Northeasterntip "Northeastern tip" with description "You reach what appears to be the end of the beach on this side of the island. The steep terrain to the southwest is impenetrable, but you could walk in shallow waters and follow the coast towards the southeast, where the island retreats and forms a small cove. You could also follow the beach by going west.", vec_norm 5, ne_to [; return EnterOcean(); ], w_to Northerncliffs, se_to Cove, has ; Shore Cove "Cove" with description [; print_ret (string) MSG_COVE_DESC, " The part of the island that rises behind you is a steep hill covered in trees, curving up to what seems to be a plateau; this is probably not a good approach for the climb. From here, you can follow the coast by walking in shallow waters, towards the northwest or the south."; ], vec_norm 6, s_to Endofthebeach, e_to [; return EnterOcean(); ], nw_to Northeasterntip, has ; Shore Endofthebeach "End of the beach" with description "The beach on the south end of the island stops here; behind the large boulder, the coast turns into steep rocks that form a small cove to the north. The rest of the beach extends southwest.", vec_norm 7, n_to Cove, se_to [; return EnterOcean(); ], sw_to Immaculatebeach, has ; ! TODO: jagged rocks, tidal pools, strait, cove (create flags for their discovery) #ifndef IS_DEMO; !====================================================== ! Some constants Constant MSG_DESC_PLAZA "This area looks like the centre of the village, with paths going many directions from the small fountain in the middle. Some buildings are north, close to the edge of the cliff, and south, near a path that runs along the edge of the plateau, overlooking the forest. You can also go east to an imposing fence around the white house, or west to the island's pub. Finally, you spot some diesel generators to the northeast, close to the fence."; Constant MSG_ACTUALLY_NO_POWER " Actually, it's probably that"; Constant MSG_NO_ELEC_ON_ISLAND " there is no electricity on the island."; Constant MSG_GENERATORS_MODIFIED "The generators seem to have been modified to all get their fuel from a central tank, also painted green."; Constant MSG_GENERATORS_SEEN_BETTER_DAYS "They have seen better days: the paint on the flywheel is chipped, and the crank shows some corrosion."; Constant MSG_DESC_FENCE "The chain link fence goes all around a field on which stands a white mansion. This, of course, makes you want to enter it and find out what is so important in it that it needed to be protected from everyone else on this island. But the fence is close to ten feet tall, and topped with barbed wire."; Constant MSG_EDGE_OF_PLATEAU "This is the edge of the plateau, where the forest starts; the trees are rather tall, and their branches grow above the fence."; Constant MSG_NOT_HUNGRY_RN "You're not hungry right now, since you ate that fish not so long ago"; Constant MSG_BREAKABLE_SMALL_GLASS " made of breakable glass and cannot contain that much; you'd rather not bother."; Constant MSG_THEY_TOOK_THE_BOOZE " It looks like the inhabitants of the island thought it was necessary to bring all the alcohol with them."; Constant MSG_KITCHEN_BEHIND_BAR "The door frame behind the bar leads further in, into the pub's kitchen."; Constant MSG_TOWER_FACES_SOUTHEAST "facing southeast, towards a small island you can barely distinguish on the horizon."; Constant MSG_STOVETOP_ON "You turn on the stovetop, and it seems to work fine. However, you're not hungry yet, and whatever energy is still in the generators would be better used to find and use the radio to send a distress call. You turn it back off."; Constant MSG_STOVETOP_OFF "You try to push or turn the knobs, but nothing happens. Then you remember"; Constant MSG_WOOD_DRY_ENOUGH "The logs look dry enough to be set alight."; Constant MSG_ALREADY_FIXED_LADDER "You've already fixed the ladder."; Constant MSG_THE_LADDER "The wooden ladder to climb up the tower is "; Constant MSG_HINGES_ARE_SMALL "The hinges are small, and you can't quite get at the pin with your fingers; you might need some kind of flat tool for this job."; Constant MSG_THE_BROKEN_LADDER " for the broken ladder at the radio tower"; Constant MSG_SCIFI_BOOK "science-fiction book"; Constant MSG_TURNOFF_LIGHT_STOREHOUSE "You need the light -- you wouldn't want to trip on something on your way out."; ! factoring code for coins Class Coin with description [; print_ret "A ", (name) self, ", minted in ", self.age, ".";], before [; Take: move self to player; scope_modified = true; "Taken."; ! we always take them, they don't cost anything in the inventory (_AtFullCapacity ignores them) Insert: if (second == backpack) { if (keep_silent ==0) { "These would only get lost at the bottom of your backpack.";} rtrue;} ], invent [; if (inventory_stage == 2) {rtrue; } ], has ; !====================================================================== ! One big door for most locations that need one !Class MyDoor "door" ! with describe [; rtrue; ], ! parse_name [; return ParseDoorName(self); ], !has door static absent; ! will be activated as we go ! State of the guard door Global F_GUARDDOOR_UNLOCKED = 0; Global F_GUARDDOOR_OPEN = 0; ! State of the pub door Global F_PUBDOOR_UNLOCKED = 0; Global F_PUBDOOR_OPEN = 0; [ FlagToHas ob flagunlocked flagopen ; if (flagunlocked) { give ob ~locked;} else { give ob locked;} if (flagopen) { give ob open; } else { give ob ~open;} ]; [ ParseDoorName obj w n; n = 0; w = NextWord(); while (w) { if (w == 'door' || (w=='gate' && location == Fencedarea or Field) || ((location == Commsroom or LobbyReception) && (w=='comms' or 'commun' or 'room')) || ((location == Infrontofthebosssroomdoor or Bossroom) && (w=='office' or 'major' or 'sign')) || (obj has open && w == 'open') || (obj hasnt open && w == 'closed') || (obj has locked && w == 'locked') || (obj hasnt locked && w=='unlock')) { n++; w=NextWord(); } else {return n;} } ! the w=='unlock' should be "unlocked" but then we run into an I6 compiler bug recently fixed return n; ]; [ DescribeADoor n; print "This door is "; !if (n has lockable) { if (n hasnt locked) { print "un";} print "locked and "; !} if (n has open) { print "open";} else { print "closed";} "."; ]; ! TODO: we can lock and unlock the shop and woodshop and stuff when they don't have keys?!! that doesn't make sense!! Object OneBigLockableDoor "door" with parse_name [; return ParseDoorName(self); ], ! can't put "concealed" on the door otherwise it's a secret door; so in order for it to not show in the list of objects, we need to give it an empty describe routine describe [; rtrue; ], description [; DescribeADoor(self); rtrue; ], found_in [; switch(real_location) { ! we also update whether it's locked or not Fencedarea: FlagToHas(self, F_GUARDDOOR_UNLOCKED, F_GUARDDOOR_OPEN); rtrue; Field: FlagToHas(self, F_GUARDDOOR_UNLOCKED, F_GUARDDOOR_OPEN); rtrue; Inpub: FlagToHas(self, F_PUBDOOR_UNLOCKED, F_PUBDOOR_OPEN); rtrue; Outsidethepub: FlagToHas(self, F_PUBDOOR_UNLOCKED, F_PUBDOOR_OPEN); rtrue; } rfalse; ], ! this is to translate the "go in" where "in" is a door into a "go location" door_to [; switch(real_location) { Field: return Fencedarea; Fencedarea: return Field; Inpub: return Outsidethepub; Outsidethepub: return Inpub; } ], ! this is to change "enter door" to "go a direction" door_dir [; if (real_location == Field) return w_to; if (real_location == Fencedarea) return e_to; if (real_location == Inpub) return out_to; else return in_to; ], with_key [; switch(real_location) { InPub, Outsidethepub: return Sparekeyforthepub; Field, Fencedarea: return Guardkey; } rfalse; ! should it be return nothing? ], after [; ! after the actions that change the state of the door, update the flags Open, Close, Lock, Unlock: switch(real_location) { Field, Fencedarea: if (OneBigLockableDoor has open) { F_GUARDDOOR_OPEN =1; } else { F_GUARDDOOR_OPEN=0;} if (OneBigLockableDoor hasnt locked) { F_GUARDDOOR_UNLOCKED = 1; } else { F_GUARDDOOR_UNLOCKED=0;} Inpub, Outsidethepub: if (OneBigLockableDoor has open) { F_PUBDOOR_OPEN =1; } else { F_PUBDOOR_OPEN=0;} if (OneBigLockableDoor hasnt locked) { F_PUBDOOR_UNLOCKED = 1; } else { F_PUBDOOR_UNLOCKED=0;} } ], has static door lockable openable absent semidark; ! will be ~absent in StartAct2 ; can be seen in the dark ! State of the woodshop door Global F_WOODSHOP_UNLOCKED = 0; Global F_WOODSHOP_OPEN = 0; ! State of the door of the bits and bobs shop Global F_SHOP_UNLOCKED = 0; Global F_SHOP_OPEN = 0; ! TODO: "The key fits; you unlock the door with the key." the first time you unlock the fence / pub ? ! This is for doors that don't have keys; they can be unlocked from inside, but never locked Object OneBigDoor "door" with parse_name [; return ParseDoorName(self); ], ! can't put "concealed" on the door otherwise it's a secret door; so in order for it to not show in the list of objects, we need to give it an empty describe routine describe [; rtrue; ], description [; DescribeADoor(self); rtrue; ], ! TODO: short_name ? (door of the pub, etc) found_in [; switch(real_location) { ! we also update whether it's locked or not Publandlordshouse: if (Insidethepublandlordshouse has visited) { give self open; } else { give self ~open; } give self ~locked; rtrue; Insidethepublandlordshouse: give self open; give self ~locked; rtrue; StorehouseFront: give self ~locked; give self open; rtrue; Outsidethestorehouse: give self ~locked; give self open; rtrue; Woodshop: FlagToHas(self, F_WOODSHOP_UNLOCKED, F_WOODSHOP_OPEN); rtrue; Insidethewoodshop: FlagToHas(self, F_WOODSHOP_UNLOCKED, F_WOODSHOP_OPEN); rtrue; Shop: FlagToHas(self, F_SHOP_UNLOCKED, F_SHOP_OPEN); rtrue; Inshop: FlagToHas(self, F_SHOP_UNLOCKED, F_SHOP_OPEN); rtrue; } rfalse; ], ! this is to translate the "go in" where "in" is a door into a "go location" door_to [; switch(real_location) { Publandlordshouse: return Insidethepublandlordshouse; Insidethepublandlordshouse: return Publandlordshouse; StorehouseFront: return Outsidethestorehouse; Outsidethestorehouse: return StorehouseFront; Woodshop: return Insidethewoodshop; Insidethewoodshop: return Woodshop; Shop: return Inshop; Inshop: return Shop; } ], ! this is to change "enter door" to "go a direction" door_dir [; if (real_location == Insidethepublandlordshouse or StorehouseFront or Inshop or Insidethewoodshop) return out_to; else return in_to; ], with_key [; rfalse; ! should it be return nothing? ], before [; !Close: if (location == Insidethepublandlordshouse && ~~_LookForLightInObj(location, location)) { "Closing the door would make you see even less.";} Close: if (real_location == Insidethepublandlordshouse or StorehouseFront) { "Closing the door would only make you see even less.";} Open: if (real_location == Publandlordshouse) { print "Surprisingly, the door hadn't been locked before the occupants of the house fled the island. You open the door and enter the house.^"; give self open; ; rtrue; } TryUnlock: if (real_location == Insidethewoodshop or Inshop) { if (self has locked) { give self ~locked; "You unlock the door from the inside."; }} ], after [; ! after the actions that change the state of the door, update the flags Open, Close, Lock, Unlock, TryUnlock: switch(real_location) { Woodshop, Insidethewoodshop: if (OneBigDoor has open) { F_WOODSHOP_OPEN =1; } else { F_WOODSHOP_OPEN=0;} if (OneBigDoor hasnt locked) { F_WOODSHOP_UNLOCKED = 1; } else { F_WOODSHOP_UNLOCKED=0;} Shop, Inshop: if (OneBigDoor has open) { F_SHOP_OPEN =1; } else { F_SHOP_OPEN=0;} if (OneBigDoor hasnt locked) { F_SHOP_UNLOCKED = 1; } else { F_SHOP_UNLOCKED=0;} Inpub, Outsidethepub: if (OneBigDoor has open) { F_PUBDOOR_OPEN =1; } else { F_PUBDOOR_OPEN=0;} if (OneBigDoor hasnt locked) { F_PUBDOOR_UNLOCKED = 1; } else { F_PUBDOOR_UNLOCKED=0;} } ], has static door lockable openable absent semidark; ! will be ~absent in StartAct2; can be seen in the dark !====================================================================== ! One big house for most locations that have one #endif; ! Helper to deal with the different types for n_to [ CompareDirAndLoc d loc ; if (location.d ofclass Object && location.d == loc) { rtrue; } if (location.d ofclass Routine && location.d() == loc) { rtrue; } rfalse; ]; ! Routine with the following behavior: ! - if player in loc, print str (the description of the thing) ! - if player isn't in loc, determine its position w.r.t. it: ! if going out takes you to loc, you're InPub/Insidethewoodshop/Insidethepublandlordshouse etc: just look around you ! if any of the directions from the player's location takes you to loc, make the player go to loc (he obviously wants to explore) ! if not, print a generic message [ GoSee loc str i; ! if player in loc, print str (the description of the thing) if (real_location == loc) { print_ret (string) str; } ! if going out takes you to loc, you're InPub/Insidethewoodshop/Insidethepublandlordshouse etc: just look around you if (CompareDirAndLoc(out_to, loc)) { <>; } ! if any of the directions from the player's location takes you to loc, make the player go to loc (he obviously wants to explore) for (i=1: i<9: i++) { if (CompareDirAndLoc(direction_properties_array->i, loc)) { print (string) MSG_YOU_DECIDE_CLOSER_LOOK; print (the) self; print (string) MSG_AND_HEAD; print (string) direction_name_array-->i; print ".^"; ; rtrue; } } ! We're nowhere near this print_ret (string) MSG_PARSER_NOSUCHTHING; ]; #ifndef IS_DEMO; ! TODO: add the overgrown garden here, putting special messages for in_to and out_to in the location and be careful about open and stuff? Global PARSED_VILLAGE = 0; Global PARSED_WHITE_HOUSE = 0; Global PARSED_STEEL_TOWER = 0; Global PARSED_PUB = 0; Global PARSED_PLAZA = 0; Global PARSED_STOREHOUSE = 0; Global PARSED_WOODSHOP = 0; Global PARSED_SHOP = 0; Global PARSED_PUBLANDLORDHOUSE = 0; Global PARSED_HOUSE = 0; [ ClearParsingFlags3 ; PARSED_VILLAGE = 0; PARSED_WHITE_HOUSE = 0; PARSED_STEEL_TOWER = 0; PARSED_PUB = 0; PARSED_PLAZA = 0; PARSED_STOREHOUSE = 0; PARSED_WOODSHOP = 0; PARSED_SHOP = 0; PARSED_PUBLANDLORDHOUSE = 0; PARSED_HOUSE = 0; ]; Object OneBigHouse with found_in [; if (location ofclass Outside || location ofclass Inside) {rtrue;} else {rfalse; } ], short_name [; if (PARSED_VILLAGE) { print "village"; rtrue; } if (PARSED_WHITE_HOUSE) { print "white house"; rtrue; } if (PARSED_STEEL_TOWER) { print "steel tower"; rtrue; } if (PARSED_PUB) { print "pub"; rtrue; } if (PARSED_PLAZA) { print "centre of the village"; rtrue; } if (PARSED_STOREHOUSE) { print "storehouse"; rtrue; } if (PARSED_SHOP) { print "shop"; rtrue; } if (PARSED_WOODSHOP) { print "woodshop"; rtrue; } if (PARSED_PUBLANDLORDHOUSE) { print "pub landlord's house"; rtrue; } if (PARSED_HOUSE) { print "house"; rtrue; } print (string) MSG_BIGOBJECT_PARSING_ERROR; rtrue; ], parse_name [ w n ; ! don't clear the parsing flags yet! if you matched a noun and are matching for a second and it's not one of these, you don't want to lose the info on what the first one was WE_PARSED_A_WORD = 0; n=0; w=NextWord(); while(w) { ! if we already parsed a word, WE_PARSED_A_WORD=true; if we already parsed a word for the sea, PARSED_SEA = true ! algorithm: if we match the sea: ! if we hadn't before: ! if another word has already been parsed: confusing (sea & sun ??), return the current n to give up ! if it's the first word we parse: all is good, put the flags up, say we matched something (this will increase n at the end) ! if we had: say we matched something, this will increase n at the end ! HOUSE if ( w=='house' or 'houses' or 'building') { ! covers also "buildings" if (WE_PARSED_A_WORD) { ! if we started parsing something that isn't a house, problem; if not, leave be if (PARSED_HOUSE == 0 && PARSED_PUBLANDLORDHOUSE == 0 && PARSED_WHITE_HOUSE == 0) { return n; } } else { ! if we just started parsing, it's ambiguous: give flags to everyone ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_HOUSE = true; PARSED_PUBLANDLORDHOUSE = true; PARSED_WHITE_HOUSE = true; } jump parsedaword3; } ! SHOP if ( w=='shop') { ! if we know we're parsing the shop or the woodshop, no problem (continue, it'll work); if we're parsing something else, problem if (WE_PARSED_A_WORD) { if (PARSED_SHOP == 0 && PARSED_WOODSHOP == 0) { return n; } else { jump parsedaword3; } } else { ! if it's the first word, they must mean the "shop of imports", not the "shop of woods" ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_SHOP = true; jump parsedaword3; } } ! VILLAGE ! "centre of the village" vs "village" if ( w=='village') { ! if it's not the first one, it's for the centre of the village if (WE_PARSED_A_WORD) { if (PARSED_PLAZA == 0) { return n; } else { jump parsedaword3; } } else { ! if it's the first word, they must mean the "village", not the "village centre" ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_VILLAGE = true; jump parsedaword3; } } ! STORE ! "shop" or "store house" if (w=='store') { ! if the next word is 'house', it's for the store house, if not it's for the shop if (NextWord() == 'house') { ! if we weren't talking about the storehouse previously if (WE_PARSED_A_WORD && PARSED_STOREHOUSE == 0) { return n; } else { if (WE_PARSED_A_WORD == 0) { ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_STOREHOUSE=true;} n++; ! because we actually have 2 good words } } else { ! if we weren't talking about the store previously if (WE_PARSED_A_WORD && PARSED_SHOP == 0) { return n; } else { if (WE_PARSED_A_WORD == 0) { ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_SHOP=true;} --wn; } } jump parsedaword3; } ! PUB ! "pub" vs "pub landlord's house" if (w=='pub') { ! if the next word is 'landlord', it's for the pub landlord's house, if not it's for the pub if (NextWord() == 'landlord') { ! if we weren't talking about the storehouse previously if (WE_PARSED_A_WORD && PARSED_PUBLANDLORDHOUSE == 0) { return n; } else { if (WE_PARSED_A_WORD == 0) { ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_PUBLANDLORDHOUSE=true;} n++; ! because we actually have 2 good words PARSED_WHITE_HOUSE = 0; PARSED_HOUSE = 0; ! now we know which house they meant } } else { ! if we weren't talking about the pub previously if (WE_PARSED_A_WORD && PARSED_PUB == 0) { return n; } else { if (WE_PARSED_A_WORD == 0) { ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_PUB=true;} w=--wn; } } jump parsedaword3; } ! UNAMBIGUOUS if ( w=='village' or 'hamlet') { if (PARSED_VILLAGE == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_VILLAGE = true; } } jump parsedaword3; } if ( w == 'white' or 'mansion' or 'wooden' or 'tall') { ! or looming? if (PARSED_WHITE_HOUSE == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_WHITE_HOUSE = true; } } PARSED_PUBLANDLORDHOUSE = false; PARSED_HOUSE = false; ! normally only one flag is up at a time, but "x house" is unclear and we dealt with it with multiple flags jump parsedaword3; } if ( w=='black' or 'steel' or 'radio' or 'watch' or 'watchtower' or 'tower' or 'mast' or 'metallic' or 'tall' || (location == BaseOfTower or Topofthetower && w=='platform' or 'railing' or 'barrier' or 'top' or 'of')) { if (PARSED_STEEL_TOWER == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_STEEL_TOWER = true; } } jump parsedaword3; } if ( w=='ship' or 'anchor' or 'sign') { if (PARSED_PUB == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_PUB = true; } } jump parsedaword3; } if ( w =='plaza' or 'square' or 'main' or 'central' or 'center' or 'centre') { ! TODO: centre of (the) village if (PARSED_PLAZA == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_PLAZA = true; } } jump parsedaword3; } if ( w =='storehouse' or 'hangar' or 'storage' or 'warehouse') { ! TODO: store house ? if (PARSED_STOREHOUSE == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_STOREHOUSE = true; } } jump parsedaword3; } if ( w =='harry' or 'earthly' or 'pleasures' or 'import' or 'wares' or 'goods' or 'small') { ! also covers "harry's" if (PARSED_SHOP == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_SHOP = true; } } jump parsedaword3; } if ( w =='woodshop' or 'workshop') { ! TODO: wood shop ? if (PARSED_WOODSHOP == false) { if (WE_PARSED_A_WORD) { return n; } else { ClearParsingFlags3(); WE_PARSED_A_WORD=true; PARSED_WOODSHOP = true; } } jump parsedaword3; } ! if we're here, we didnt match, so we stop return n; .parsedaword3; ! if we're here, we matched, so we keep going n++; w = NextWord(); } !print "My flags:", PARSED_HOUSE, PARSED_WHITE_HOUSE, PARSED_PUBLANDLORDHOUSE,"^"; !print "n =", n; return n; ], description [; ! generic "house", "houses" if (PARSED_HOUSE) { ! the test is needed because typing "house" opens up possibilities PARSED_HOUSE = 1; PARSED_WHITE_HOUSE = 0; PARSED_PUBLANDLORDHOUSE = 0; switch(location) { WhiteHousePorch, Field, Aroundthefence, Fencedarea, Dieselgenerators: PARSED_HOUSE = 0; PARSED_WHITE_HOUSE = 1; PARSED_PUBLANDLORDHOUSE = 0; ! they meant the white house; let subsequent code deal with it Publandlordshouse, BaseOfTower, Communitygarden, Outsidethepub: PARSED_HOUSE = 0; PARSED_WHITE_HOUSE = 0; PARSED_PUBLANDLORDHOUSE = 1; ! they meant the pub landlord's house; let subsequent code deal with it Houses: "Those small one-storey houses aren't much to look at; they are made of concrete and their roof is made of the corrugated tin you see everywhere else in the island. One of them stands out, as its door seems to have been replaced by a much cruder wooden door, and its hinges are on the exterior of the house. You wonder if that door was made on the island."; Houses2: print "This is a small house, very similar to the other buildings here, with its concrete walls and corrugated tin roof. Near the front door, a window is facing the sea"; if (F_HOUSE_CLIFF_SMASHED) { print ", but it is now broken"; } "."; } } if (PARSED_STEEL_TOWER && (location == BaseOfTower or Topofthetower)) { if (location == Topofthetower) { <>; } print "The steel tower is rather tall, about twenty feet tall. It is "; print (string) MSG_TOWER_FACES_SOUTHEAST, " The tower apparently also doubles as a radio tower, judging by the tall mast at its top. You can climb a ladder to get to the top of the tower"; if (F_LADDER_FIXED == 0) { print " -- as soon as you have fixed it, that is"; } "."; } if (PARSED_WHITE_HOUSE && (location == Field or WhiteHousePorch or Aroundthefence or Fencedarea or Dieselgenerators)) { "The white mansion is two stories tall; it is the most imposing building of the island, and the only one made of wood, it seems. The front door is not boarded, but the windows are. The fact that access to this house was restricted makes you all the more eager to discover its secrets."; } if (PARSED_PUB) { GoSee(Outsidethepub, "This is the pub of the island, the ~Ship and Anchor~. This means the people who lived here were British; after all, wherever there's Brits near the sea, there's a pub named ~Ship and Anchor~."); rtrue; } if (PARSED_PLAZA) { GoSee(Centralplaza, MSG_DESC_PLAZA); rtrue; } if (PARSED_STOREHOUSE) { GoSee(Outsidethestorehouse, "The island's storehouse, surprisingly not that empty; the people leaving the island probably didn't have the space, or the time, to take all of it."); rtrue; } if (PARSED_WOODSHOP) { GoSee(Woodshop, "You peek through the window. Inside the woodshop is a table, presumably the last project of the resident woodworker before fleeing the island."); rtrue; } if (PARSED_SHOP) { GoSee(Shop, "You peek through the window and see a few things on display in the shelves, such as cigarettes and comic books."); rtrue; } if (PARSED_PUBLANDLORDHOUSE) { GoSee(Publandlordshouse, "The pub landlord's house is near the pub, which is probably for the best."); rtrue;} ! "village" and catchall print_ret (string) MSG_INCREDIBLY_DESCVILLAGE, " Building that kind of community ex nihilo must have been quite the undertaking. Who would build this in the middle of the ocean? And why?"; ], react_before [f ; if (noun == self && action ~= ##Examine && action ~= ##Enter) { ! we can't do anything else but examine or enter for an object not in location switch(location) { Houses: if (PARSED_HOUSE == 0) { f=1;} Houses2: if (PARSED_HOUSE == 0) { f=1; } WhiteHousePorch: if (PARSED_WHITE_HOUSE == 0) { f=1; } Outsidethepub: if (PARSED_PUB == 0) { f=1;} Outsidethestorehouse: if (PARSED_STOREHOUSE == 0) { f=1; } Shop: if (PARSED_SHOP == 0) { f=1; } Woodshop: if (PARSED_WOODSHOP == 0) { f=1; } Publandlordshouse: if (PARSED_PUBLANDLORDHOUSE == 0) { f=1; } BaseOfTower, Topofthetower: if (PARSED_STEEL_TOWER == 0) { f=1; } default: f=1; } if (f==1) { print_ret (string) MSG_WRONG_LOCATION; } } ], before [; Touch: "You don't really see the point."; Take: PrintMsg(MSG_TOO_IMMENSE); "taken."; Turn, Push, Pull: PrintMsg(MSG_TOO_IMMENSE); print_ret (verbname) verb_word, "ed."; Climb: if (PARSED_STEEL_TOWER && location == BaseOfTower) { <>; } rfalse; Open, Close, Lock, Unlock: if (OneBigDoor in location) { PerformAction(action, OneBigDoor); rtrue; } if (OneBigLockableDoor in location) { PerformAction(action, OneBigLockableDoor); rtrue; } if (CrudeDoor in location) { PerformAction(action, CrudeDoor); rtrue; } rfalse; Enter: if (PARSED_STEEL_TOWER) { <>; } else { <>; } Exit: if (PARSED_STEEL_TOWER) {<>; } else { <>; } Insert: "You should probably go inside to do this."; Search: if (PARSED_HOUSE && location == Houses2) { "You look inside the house; it doesn't look too messy, but there doesn't seem to be much of interest there either."; } <>; ! faire plutôt un MSG_SHOULD_ENTER ? Fix: if (PARSED_STEEL_TOWER && location == BaseOfTower) { <>; } Receive: if (PARSED_STEEL_TOWER && location == BaseOfTower) { <>; } ], has scenery concealed absent reactive; ! will be ~absent in StartAct2 #endif; !======================================================================= ! Act 2 - Upper level [ StartAct2 i; if (F_ACT2_STARTED == false) { F_ACT2_STARTED = true; score = score +5; #ifndef IS_DEMO; for (i = FIRST_FLOATING_ACT2: ii) ~absent; #endif; print "^^The top of the hill is rather flat, forming a vast plateau. You look around you, and your heart fills with joy. ", (string) MSG_INCREDIBLY_DESCVILLAGE, " It all seems surreal, but there it is: the island was inhabited by several dozen people, at some point. Now, everyone seems to have gone, but there is probably a lot of things lying around that could be useful -- not to mention, the radio might still be in working condition, and you might be able to figure out how to use it to call for help. Your chances of survival have drastically gone up!^^"; } #ifdef IS_DEMO; print "^^===========================^This is the end of the free demo of ~Tristam Island~!^^I hope you enjoyed it, and that you want to check out the full game. It is 2-3 times bigger than this demo, and you can buy it for $3.99 at hlabrande.itch.io/tristam-island.^^Let me know if you have any comments or bug reports, your opinion is appreciated! You can reach me on Twitter, or use the email address on my website (both of which can be found on hlabrande.itch.io). Thank you!^^^"; deadflag=2; @new_line; @rtrue; #Endif; ]; ! Things so the compiler doesn't complain #ifdef IS_DEMO; Class Inside has light; Class Outside has light; Class InMansion has light; Class InsideLab has light; Object Topofthestairs; Object Outsidethestorehouse; Object backpack; Object BaseOfTower; Object Topofthetower; Object Communitygarden; #endif; ! the rest of the game #ifndef IS_DEMO; Class Inside with before [; Exit: if (noun == 0) { <>; } ], has light; Class Outside has light; Object Insidethepublandlordshouse "Inside the house" with short_name [; print "Inside the "; if (location == self) { print "pub landlord's ";} print "house"; @rtrue; ], semidark_description [; print_ret "Even with the door open, you cannot see much inside this house; only dark shapes that you are unable to identify", (string) MSG_ONLY_WAY_IS_OUT, "."; ], description [; print_ret "This is a very small house, more like a cottage really. The posters on the wall give a clue about who lived in that house: given that they're all Guinness or Watney's posters, and given the aprons hanging on the hooks by the door, you're quite sure this is the pub landlord's house. There is no kitchen, just a living room and a small bathroom, and there are few pieces of furniture: a bed, a table and four chairs. You also spot a safe by the foot of the bed",(string) MSG_ONLY_WAY_IS_OUT, ".";], out_to OneBigDoor, !Publandlordshouse, before [; Exit: if (noun == 0) { <>; } ], has semidark; Constant MSG_YOU_FEEL_THE_WALL "You feel the wall"; Object -> LightSwitchPubL "light switch" with name 'light' 'switch' 'wall', description "There is a light switch on the wall, by the door.", before [; Touch,Rub: print_ret (string) MSG_YOU_FEEL_THE_WALL, " around the door, and your fingers encounter what seems to be a light switch."; SwitchOn: if (self has light) { "The light is already on."; } else { if (F_GENERATORS_ON) { give self light; score = score-1; generators_load = generators_load+5; print "You turn the light on."; <>; } else { print_ret (string) MSG_YOU_FEEL_THE_WALL, " and find the light switch. You flick it, but nothing happens.";} } SwitchOff: if (self has light) { give self ~light; score = score+1; generators_load = generators_load-5; "You turn off the light; might as well preserve energy.";} else { "The light is already off."; } ], has static concealed switchable semidark; Object -> PubLBathroom "pub landlord's house" with parse_name [ n ; n = 0; while (NextWord() == 'bathroom' or 'washroom' or 'room' or 'cottage' or 'bed' or 'table' or 'chair' or 'chairs' or 'living' or 'sink' or 'toilet') n++; return n; ], description [; <>; ], before [; Enter, Search: "The cottage is so small, you can see everything there is to see from the bed in the corner. You pace the room but can't find anything else."; SleepOn: <>; ], has static concealed; Object -> Guinnessposters "beer posters" with parse_name [ n ; n = 0; while (NextWord() == 'poster' or 'guinness' or 'watneys' or 'beer' or 'ale' or 'stout' or 'murals' or 'canvas' or 'ad' or 'slogan' or 'toucan' or 'man' or 'gentleman' or 'golfer' or 'golfing') n++; return n; ], description "You have never heard of Watneys, but you have definitely heard of, and drank, Guinness. These are vintage posters, with a graphic style that you associate with the 1940s or 1950s. The Watneys poster shows a golfing gentleman with the slogan ~What we want is Watney's Pale Ale~; the Guinness one is more fun, featuring a toucan balancing pints of Guinness on its beak, with the slogan ~Guinness is good for you~.", has static concealed; ! will be ~absent in StartAct2 Object -> Apron "apron" with name 'apron' 'aprons' 'hook' 'jacket', ! covers jackets description "Near the door are a row of hooks, with several white aprons and black jackets. You're guessing a pub landlord needs several of them, as they would get dirty quite frequently.", before [; Wear, Take: print "You pick a"; print (string) random("n apron", " jacket"); print " from the hooks and wear it, then walk around with a grin on your face. ~"; print (string) random("Last call! Last call, gentlemen!","All hail to the ale!","Hey you! Don't get too rowdy or I'll show you the door!","No, mate, you've had enough already! Go home!"); print "~, you "; print (string) random("proclaim loudly", "bellow", "bark"); ", then giggle as you put the outfit back on the hook."; Smell: "You close your eyes and smell the aprons. You smell a faint smell of beer and smoke, and you suddenly feel like you're in an old pub, with music and people around you. Or maybe it's just your imagination."; ], has concealed ; ! will be ~absent in StartAct2 Object -> Safeopen "short safe" with name 'short' 'cube' 'safe' 'door', description [; print "A short, cube-shaped safe is by the foot of the bed; its door is "; if (self has open) {"open."; } else { "shut.";} ], before [; Turn, Open: if (self has open) { rfalse; } if (parent(Sparekeyforthepub) == nothing) { move Sparekeyforthepub to self; give Sparekeyforthepub ~moved; give self open; scope_modified = true; "You pull on the safe door -- to your surprise, it opens, just like that! The safe appears to contain a key."; } ], has static openable container concealed ; ! will be ~absent in StartAct2 Object Sparekeyforthepub "spare key for the pub" with parse_name [ w n i ; n = 0; w = NextWord(); i=0; while (w) { if (w == 'pub' or 'landlord') { i++; w=NextWord(); } ! it's an adjective, only add it if there's other things else { if (w == 'spare' or 'key') { n=n+1+i; i=0; w=NextWord(); } else {return n;} } } return n; ], ! TODO check "spare key for/of the pub" description "This key was in the safe of the pub landlord's house; it's a spare key for the pub.", before [; Take: if (self hasnt moved && _AtFullCapacity(player) == false) { score = score+5; } rfalse; ], has; Inside Insidehouses "Small house by the northern cliffs" with description [; print "The light of the "; if (F_GENERATORS_ON == 0 || Lighton2 hasnt on) { print "sun"; } else { print "light bulb"; } print_ret " illuminates the inside of the small house. It's rather minimalist in there: there is a small sink, an empty pantry, a few lights and a few chairs", (string) MSG_ONLY_WAY_IS_OUT, "."; ], out_to Houses2, has ; Object -> Lighton2 "light" with name 'light' 'switch' 'lights' 'bulb', description [; if (F_GENERATORS_ON == 0) { print "The light is off."; print (string) MSG_ACTUALLY_NO_POWER, (string) MSG_NO_ELEC_ON_ISLAND; @new_line; return 2;} ! else don't return anything, the state of the light will be displayed by examine anyway ], before [; SwitchOn: if (F_GENERATORS_ON == 0) {print "The light switch doesn't work."; print_ret (string) MSG_ACTUALLY_NO_POWER, (string) MSG_NO_ELEC_ON_ISLAND; } else {if (self hasnt on) {"You don't see why; there's enough sunlight to see here.";}} SwitchOff: if (F_GENERATORS_ON == 0) { <>;} else {if (self has on) {score = score + 1; generators_load = generators_load-5; give self ~on; "You turn off the light; the sun's light is still enough for you to see inside, so might as well conserve energy.";}} ], has static concealed switchable on; Constant MSG_FIGURE_OUT_NEXT_MOVE " to figure out what your next move should be."; Object -> ChairsHouse2 "chairs" with description "These chairs are made of wood, and don't look like they came out of a factory; someone made these by hand.", name 'chair' 'chairs' 'seat' 'furniture', before [; Enter: print_ret "You sit on a chair for a few minutes, and rest your legs while your mind tries", (string) MSG_FIGURE_OUT_NEXT_MOVE; Take: "They are too bulky."; ], has supporter concealed; Object -> FurnitureHouse2 "furniture" with description [; <>; ], name 'pantry' 'sink' 'stuff' 'shelves', before [; "There really isn't much worth searching or taking in there."; ], has static concealed; [ DescribeCounter ; print "There's not much left on the shelves and the counter"; PrintContents(", but you see ", Counter); print "."; @rtrue; ]; Inside Inshop "Inside Harry's shop" with description [; print "This is ~Harry's Earthly Pleasures~, a shop that has all sorts of goods that were probably imported from the land, for people here to buy with whatever disposable income they had. "; DescribeCounter(); print_ret " Some of this might be useful, but this is overall a bit disappointing", (string) MSG_OUT_DOOR_OR_WINDOW; ], out_to OneBigDoor, !Shop, has ; Object -> Counter "counter" with name 'counter' 'shelf' 'shelves', description [; DescribeCounter(); @new_line; rtrue; ], has static concealed supporter; Object -> -> Binoculars "binoculars" with name 'binoculars', description "These binoculars look like they are in great condition.", has pluralname; ! wrigley's spearmint, made in wembley http://letslookagain.com/2015/09/by-gum-wrigleys-in-the-uk/ Object -> -> Packofgum "pack of gum" with parse_name [ n ; n = 0; ! also covers "wrigley's" while (NextWord() == 'pack' or 'package' or 'gum' or 'chewing' or 'wrigley' or 'spearmint' or 'candy') n++; return n; ], description "This is a pack of Wrigley's Spearmint Chewing Gum. It's probably not very fresh, but it's worth a shot.", before [; Eat: print "You chew on one of the gums. "; print_ret (string) random("You taste the juice of real mint leaves.", "The flavor lasts.", "It feels healthful, refreshing, delicious."); ], has ; Object -> -> Lighter "lighter" with name 'lighter', description "This is a small lighter. You flick it, and it seems to still work well. Handy.", has ; ! TODO: "x cigarettes" from outside Object -> -> Cigarettes "pack of cigarettes" with name 'cigarette' 'pack' 'packs' 'smokes', description "There are two packs of cigarettes here, untouched.", before [; Remove,Take,Burn: "Now would be a bad time to start smoking; you'd be addicted to nicotine just as you finish smoking the second pack."; ], has ; ! Have we looked at the comic book? Global F_EXAMINED_COMIC = 0; ! TODO: "x comic books" from outside Object -> -> Comicbooks "comic book" with name 'comic' 'book' 'comics' 'books', description [; F_EXAMINED_COMIC = 1; "This is ~The Fantastic Four~, from 1 Nov 1961. It must be the first issue, as it proclaims ~Featuring The Thing! Mr Fantastic! Human Torch! Invisible Girl! Together for the first time in one mighty magazine!~. Some green mutant is emerging from a street, while the four heroes talk to each other in various poses."; ], before [; Open, Search: "You flip through the pages, and read distractedly. The heroes save the day at the end. You never really were into superheroes anyway."; Remove,Take: "Why bother? You don't really see the value of it. In fact, it's probably worthless."; ], has ; Coin -> -> Sixpence "rusty sixpence" with name 'sixpence' 'coin' 'rusty', age 1960, !initial "There's a rusty sixpence on the counter.", has ; ! for the inside of shops Constant MSG_OUT_DOOR_OR_WINDOW ". You can go out through the door, or through the window, since it is broken."; Inside Insidethewoodshop "Inside the woodshop" with description [; print "It looks like the island had its own woodworker, who was making or fixing furniture and wooden objects for the island. A smart strategy; there is, after all, a pretty extensive forest on the island. There is a sturdy-looking table in the middle of the workshop"; if (Rung hasnt moved || Saw hasnt moved) {print ", as well as";} if (Rung hasnt moved) { print " a few cylindrical wood pieces, all of the same length, and"; } if (Saw hasnt moved) { print " a saw on the floor"; } print_ret (string) MSG_OUT_DOOR_OR_WINDOW; ], out_to OneBigDoor, !Woodshop, has ; Object -> TableWoodshop "wooden table" with name 'wooden' 'circular' 'table' 'project', description [; print "This is a pretty nice circular table, and it only needs to be sanded to be done."; if (Inpub has visited) { print " Actually, it reminds you of the tables in the pub; either a rowdy drinker broke a table, or there wasn't quite enough room for everyone."; } @new_line; @rtrue; ], before [; Take: print_ret (string) MSG_FAR_TOO_LARGE, "."; ], has concealed; Object -> Saw "hand wood saw" with parse_name [ w n i ; n = 0; w = NextWord(); i=0; while (w) { if (w == 'hand' or 'wood') { i++; w=NextWord(); } ! it's an adjective, only add it if there's other things else { if (w == 'saw') { n=n+1+i; i=0; w=NextWord(); } else {return n;} } } return n; ], description "This is a hand saw, useful for cutting wood, and not much else.", has concealed; Coin -> Shilling3 "shiny shilling" with name 'shilling' 'coin' 'shiny', age 1960; ! have we looked at our cylinders Global F_RUNG_EXAMINED = 0; Object -> Rung with parse_name [ w n ; n = 0; w = NextWord(); while (w) { if (w == 'cylind' or 'wood' or 'wooden' or 'pegs' or 'pieces' or 'rung' or 'rungs' || (location ~= BaseOfTower && w=='ladder')) { n++; w=NextWord(); } else {return n;} } return n; ], short_name [; if (F_RUNG_EXAMINED) { print "ladder rungs"; } else { print "wooden cylinders"; } rtrue; ], description [; print "There are three cylinders of exactly the same shape and length. "; if (F_RUNG_EXAMINED == 0) { print "You wonder what the use for these could be"; if (BaseOfTower has visited) {F_RUNG_EXAMINED=1; print_ret ", and then it comes to you: these are replacement rungs", (string) MSG_THE_BROKEN_LADDER, "!"; } else { "."; } } else { print_ret "These would be perfect", (string) MSG_THE_BROKEN_LADDER, ".";} ], has concealed pluralname; Object Inpub "Pub" with description [; print "The pub is rather large, with a dozen different tables, and plenty of chairs; a solitary pint glass is on a table. The bar is opposite of the door; the shelves behind it appear empty, as if all the alcohol had been taken. "; print_ret (string) MSG_KITCHEN_BEHIND_BAR, " On one wall are hung a map, and a notice board with a signup sheet; there is a vintage-looking jukebox on the opposite wall."; ], semidark_description "The pub is mostly engulfed in darkness, although a little light is filtering through the windows. You can spot the bar and a few chairs, but that's about it. You can go out by the door.", in_to Pubkitchen, out_to OneBigLockableDoor, !Outsidethepub, before [; Exit: if (noun == 0) { <>; } ], has semidark; Object -> Tables "tables and chairs" with name 'tables' 'table' 'chair' 'chairs', description [; print "There appears to be quite a few tables and chairs "; if (location == thedark) { print "in the darkness"; } else { print "here"; } ". Given the number of buildings you've seen around here, this might have been enough to fit the whole village."; ], before [; Take: "That's much too heavy. Besides, what would you do with it?"; Enter: if (location == thedark) { <>; } "You sit at a table for a little bit, thinking about what your next move should be. You quickly feel jittery and stand up."; ], has concealed pluralname semidark; Object -> Bar "bar" with parse_name [ n ; n = 0; while (NextWord() == 'bar' or 'counter' or 'dust' or 'shelves' or 'alcohol' or 'whiskey' or 'whisky' or 'beer' or 'ale' or 'stout') n++; return n; ], description [; print "The bar is, of course, opposite the door. "; if (location == thedark) {"You can't see it very well."; } else {print "The bar is a bit dusty, after all these years. The shelves behind it, as well as under it, are completely empty."; print_ret (string) MSG_THEY_TOOK_THE_BOOZE;}], before [; Touch,Rub: if (location == thedark) { <>; } else { "It does feel a little sticky... Yuck."; } Push, Pull, Turn: if (location == thedark) { "You'd rather not; you'd probably trip on something on the way."; } Drink: print "There is nothing to drink in the whole pub."; print_ret (string) MSG_THEY_TOOK_THE_BOOZE; ], has static concealed semidark; Object -> Kitchen "kitchen" with name 'door' 'frame' 'kitchen', ! pub's kitchen? behind bar? Should we worry? description [; print_ret (string) MSG_KITCHEN_BEHIND_BAR; ], before [; Enter: <>; ], has enterable concealed static; ! Have we looked at it? (useful for the end) Global F_EXAMINED_SIGNUP = 0; Object -> Bulletinboard "notice board" with parse_name [ n ; n = 0; while (NextWord() == 'notice' or 'bulletin' or 'pin' or 'board' or 'signup' or 'sheet' or 'names' or 'rows' or 'paper') n++; return n; ], description [; F_EXAMINED_SIGNUP=1; "The notice board hung to the wall is made of cork, and has a single sheet pinned to it. The title typed at the top reads ~COMMUNITY GARDEN SHIFTS~, and the rows below are for the month of February: Thursday the 1st, Friday the 2nd, Saturday the 3rd, etc. One or two people have signed up every day, until February 18th, at which point only one person signed up, then nobody else for the rest of the month. Strange."; ], has static concealed; Object -> Pint "empty pint" with name 'empty' 'pint' 'glass' 'beer', description "A single pint is on a table, empty and forgotten.", before [; Drink,Smell: "It is absolutely empty, and it doesn't even smell like anything anymore."; Attack: "Breaking the glass here would make it dangerous to walk around here."; Take: print "It is"; print_ret (string) MSG_BREAKABLE_SMALL_GLASS; ], has concealed; Constant MSG_CHARRED_DESTROYED_ISLAND " the charred, destroyed, mysterious island you saw through your binoculars"; ! Is this the first time we look at the map in the pub? Global F_FIRST_LOOK_AT_MAP = 0; Object -> MapOfIslands "map of islands" with parse_name [ n ; n = 0; while (NextWord() == 'poster' or 'map' or 'island' or 'tristam' or 'this' or 'neighbouring' or 'kingsley') n++; return n; ], description [; give TristamIsland proper; ! we now know the name of the neighbouring island (this is the only way) print "The map on the wall displays two islands. The largest one is called Kingsley Island; to the southwest is Tristam Island"; if (F_SAW_TRISTAM_PRECISELY && F_FIRST_LOOK_AT_MAP) {print ",", (string) MSG_CHARRED_DESTROYED_ISLAND; } print ". "; if (F_FIRST_LOOK_AT_MAP == 0) { score = score + 2; F_FIRST_LOOK_AT_MAP=1; print "You contemplate the geography for a few seconds, then it strikes you: the large island is the one you are on right now! No doubt about it: the plateau, the forest, the cliffs, the roughly circular shape... So now, you know that you are stuck on Kingsley Island. "; if (F_SAW_TRISTAM_PRECISELY == 0) { print "What's new to you is that "; if (F_TRISTAM_DISCOVERED == 0) { print "there is an island to the southwest,"; } else { print "the island you saw to the southwest is"; } print " named Tristam Island. "; } else { print "And Tristam Island must be", (string) MSG_CHARRED_DESTROYED_ISLAND, ". "; } } F_TRISTAM_DISCOVERED=true; if (F_SAW_TRISTAM_PRECISELY == 0) {"You wonder what's on that island.";} else {"You wonder if you can find out what happened there."; } ], has static concealed; ! money in the UK: https://www.bullionbypost.co.uk/index/collectible-coins/pre-decimal-currency/ ! http://www.bal-ami.com/view-details/343/Junior.htm ! Give the hint to the player that they should play songs Global F_JUKEBOX_HINT_GIVEN = 0; ! Have we looked at it (useful for the end) Global F_EXAMINED_SONGLIST = 0; Object -> Jukebox "jukebox" with parse_name [ n ; n = 0; while (NextWord() == 'jukebox' or 'junior' or 'bal' or 'ami' or 'cabinet' or 'small' or 'window' or 'decal' or 'speaker' or 'coin' or 'slot' or 'acceptor') n++; return n; ], description [; print "This small jukebox is strategically placed in the middle of the room, against a wall. A list of twenty songs is displayed at the top of the cabinet; the buttons next to each of them "; if (F_GENERATORS_ON && self has on) { print "glow invitingly"; } else { print "are off"; } print ". The main window in the middle of the cabinet "; if (F_GENERATORS_ON && self has on) { print "emits a bright yellow light, and displays the plate and record-changing mechanism"; } else { print "is dark"; } print "; a decal on the window identifies the machine as a BAL-AMi Junior. A note taped below the window, next to the coin slot, reads ~One Song - 6p - 3 Songs - 1s~."; @new_line; return 2; ! so it doesn't print "the jukebox is on" automatically ], before [; Receive: if (F_GENERATORS_ON == 0 || self hasnt on) {<>; } if (noun == Sixpence or Sixpence2 or Sixpence3 or Sixpence4) { F_JUKEBOX_HINT_GIVEN = 1;F_EXAMINED_SONGLIST=1; remove noun; scope_modified = true; score = score+1; print "You insert a sixpence in the coin slot and look at the song list. You pick"; RandomSong(); print ", and "; print (string) random("listen to it", "start dancing", "sit down to listen to it", "sway your hips back and forth"); " until it's over.";} if (noun == Shilling1 or Shilling2 or Shilling3) { F_JUKEBOX_HINT_GIVEN = 1;F_EXAMINED_SONGLIST=1; remove noun; scope_modified = true; score=score+1; print "You insert your shilling in the slot and pick three songs at random:"; RandomSong(); print ","; RandomSong(); print ", and"; RandomSong(); ". You kind of forget where you are for the next five minutes; it feels good to lose yourself in the music for a bit."; } "You cannot insert this in the coin slot."; Listen: print "The jukebox is"; if (F_GENERATORS_ON && self has on) { "n't playing any music; the only noise you can hear is a soft hum."; } else {" off, and doesn't make any noise."; } ! TODO: open coin slot ! TODO: play jukebox SwitchOn: if (F_GENERATORS_ON == 0) {print_ret "There is no obvious button to do this; the problem seems to be that", (string) MSG_NO_ELEC_ON_ISLAND; } else { if (self hasnt on) {give self on; generators_load = generators_load+10; score = score-1; "You plug the jukebox back in, hoping to listen to more songs."; }} SwitchOff: if (F_GENERATORS_ON == 0) { "That's already off."; } if (self has on) { if (F_JUKEBOX_HINT_GIVEN == 0) { F_JUKEBOX_HINT_GIVEN = 1; "You go to unplug the jukebox, but stop at the last moment. Wouldn't a little bit of music be nice, first? You're feeling rather alone, and it would be good for your spirits."; } else { ! this time it's for good give self ~on; generators_load = generators_load-10; score = score+1; "You unplug the jukebox, to avoid wasting energy."; } } ], has static container openable open switchable on concealed; ! saves 70 bytes over a switch Array songtitles static --> "I've Told Every Little Star" "Three Steps to Heaven" "Poetry in Motion" "Blue Moon" "Jambalaya (On The Bayou)" "Runaway" "Angel Baby" "Johnny Remember Me" "Telstar" "Nut Rocker" "Apache" "Does Your Chewing Gum Lose Its Flavor" "Why" "Lovesick Blues" "Little Sister" "You don't know" "I love you" "Rock A Hula" "Walking Back to Happiness" "The Young Ones"; Array songauthors static --> "Linda Scott" "Eddie Cochran" "Johnny Tillotson" "The Marcels" "Fats Domino" "Del Shannon" "Rosie and the Originals" "John Leyton" "The Tornados" "B. Bumble & The Stingers" "The Shadows" "Lonnie Donegan" "Anthony Newley" "Frank Ifield" "Elvis Presley" "Helen Shapiro" "Cliff Richard and The Shadows"; [ RandomSong _i; print " ~"; ! saves 4 bytes _i=random(20)-1; print (string) songtitles-->(_i); print "~, by "; if (_i > 16) { _i = _i-3;} ! hack to have a shorter authors table - saves 44 bytes print (string) songauthors-->(_i); rtrue; ]; Object -> -> Songs "list of songs" with parse_name [ n ; n = 0; while (NextWord() == 'songs' or 'song' or 'list' or 'track' or 'record' or 'button') n++; return n; ], description [ ; F_EXAMINED_SONGLIST=1; print "You glance at the songs displayed at the top of the jukebox. You don't know any of them, but"; RandomSong(); print ", "; print (string) random("catches your eye", "sounds good to you", "sounds vaguely familiar", "sounds interesting"); ".";], before [ o; ! listen to song Listen: if (F_GENERATORS_ON == 0 || Jukebox hasnt on) {"The only song a switched-off jukebox can play is ~4'33~ by John Cage, and you've already heard it before.";} objectloop(o in player) { if (o ofclass Coin) { ; rtrue; } } "You do not have any coins to put in the jukebox."; ], has static concealed; Constant MSG_KITCHEN_BACK_OF_PUB "The kitchen at the back of the pub is "; Constant MSG_POTS_AND_PANS_STORED "he pots and pans are stored"; Constant MSG_BACK_TO_THE_PUB ", back to the pub."; Object Pubkitchen "Kitchen" with description [; print_ret (string) MSG_KITCHEN_BACK_OF_PUB, "small but functional. The countertop is bare, and a bit stained; t", (string) MSG_POTS_AND_PANS_STORED, " on shelves below. There are a few appliances here, such as a fridge, a stovetop, and a deep fryer", (string) MSG_ONLY_WAY_IS_OUT, (string) MSG_BACK_TO_THE_PUB; ], semidark_description [; print_ret (string) MSG_KITCHEN_BACK_OF_PUB, "dark; you see a few vague shapes, but not much more", (string) MSG_ONLY_WAY_IS_OUT, (string) MSG_BACK_TO_THE_PUB; ], out_to Inpub, has semidark; Object -> Countertops "countertop" with parse_name [ n ; ! also does countertops n = 0; while (NextWord() == 'counter' or 'bench' or 'work' or 'top' or 'worktop' or 'benchtop' or 'wooden' or 'stains' or 'stained' or 'dust') n++; return n; ], description [; print_ret "There isn't anything on the wooden countertop but a few circular stains -- probably from setting a hot pot or pan on the surface -- and a bit of dust. Under the countertop is where t", (string) MSG_POTS_AND_PANS_STORED, ".";], before [; LookUnder: <>; ], has concealed static; Object -> PotsPans "pots and pans" with !parse_name [ w n ; ! pub's kitchen? Should we worry? ! n = 0; w = NextWord(); ! while (w) { ! if (w == 'pots' or 'pans' or 'pan' || ( (parent(aPot) == nothing) && w == 'pot')) { n++; w=NextWord(); } else {return n;} ! } ! return n; !], name 'pots' 'pot' 'pan' 'pans', description [; print_ret "T", (string) MSG_POTS_AND_PANS_STORED, " under the wooden countertop in the kitchen. They look ancient (or, shall we say, they have a vintage design), and are made of stainless steel -- unless it's aluminium? You're not sure.";], before [; Take: if (parent(aPot) == nothing) { if (_AtFullCapacity(player)==false) { move aPot to player; scope_modified = true; "After thinking it over, you decide to take a pot -- the pans are too shallow to be useful for anything else than cooking, and it's not really time for you to make food yet."; }} else { "Since you're the only one on this island, you're going to have to do all the dishes; the thought of dirtying another pot sounds awful to you."; } ], has pluralname concealed; Constant MSG_NO_NEED_FRIDGE "No need to run a old fridge for no reason when you need to conserve energy."; [ DescFridgeFactoring ; print " makes a low hum as it tries to refrigerate "; if (Fridge has open) {print "more air, as it escapes out of the door.";} else { print "after all these years.";} rtrue; ]; Object -> Fridge "fridge" with name 'fridge' 'refrigerator' 'tall' 'old', description [; print "This tall, old fridge is empty, and was left open for years. "; if (F_GENERATORS_ON == 0) { if (Fridge has on) {print "It is plugged in, but"; } else { print "It"; } print_ret " isn't making any noise; probably because", (string) MSG_NO_ELEC_ON_ISLAND; } else { if (Fridge has on) { ! plugged in print "It is plugged in, and"; DescFridgeFactoring(); ". Of course, it's no use, as it doesn't contain anything."; } else { "You unplugged it to preserve energy."; } } ], ! TODO: change depending on whether it's plugged in before [; Listen: if (F_GENERATORS_ON && self has on) { print "The refrigerator"; DescFridgeFactoring(); } Receive: "You don't really need to refrigerate this."; SwitchOff: if (self has on) {score = score + 1; give self ~on; generators_load = generators_load-15; print_ret "You find the plug for the fridge at the back and unplug it. ", (string) MSG_NO_NEED_FRIDGE; } else {"The fridge is already unplugged."; } SwitchOn: if (self has on) { "The fridge is already running"; } else { print_ret (string) MSG_NO_NEED_FRIDGE; } ], has openable open on concealed switchable static; Object -> StovetopPubK "stovetop" with parse_name [ n ; n = 0; while (NextWord() == 'stovetop' or 'burner' or 'electric' or 'stove' or 'button' or 'knob' or 'knobs' or 'grease' or 'stains' or 'stain') n++; return n; ], description "The pub's electric stovetop has four big burners, controlled by knobs. They really could have used a more thorough cleaning; there is brown grease and red stains between the burners.", before [; SwitchOn, Push, Turn: if (F_GENERATORS_ON == 0) {print_ret (string) MSG_STOVETOP_OFF, (string) MSG_NO_ELEC_ON_ISLAND; } else {print_ret (string) MSG_STOVETOP_ON; } ], has static concealed supporter; Constant MSG_WRONG_TOOL_OIL "This doesn't seem like the right tool to get the oil from the deep fryer."; Object -> Deepfryer "deep fryer" with parse_name [ n ; n = 0; while (NextWord() == 'deep' or 'fryer' or 'cooking' or 'oil' or 'congealed' or 'solid' or 'solidified' or 'white' or 'fat') n++; return n; ], description "You're guessing this deep fryer was installed because any British pub has to have fish and chips on the menu. Whatever cooking oil was used has completely congealed, and now forms a huge block of white fat in the deep fryer.", before [; Take: "You try to grab the cooking oil out of the deep fryer with your bare hands, but it's really stuck in there."; TakeWith: if (second == Fishingknife) { <>; } else { print_ret (string) MSG_WRONG_TOOL_OIL; } Cut1: if (Fishingknife in player) { <>;} else { "You'd like to carve some oil out, but with what?"; } Cut2: if (second ~= Fishingknife) { print_ret (string) MSG_WRONG_TOOL_OIL;} if (F_TANK_FULL == 0 && parent(CookingOil) == nothing) { move Cookingoil to player; move Fishingknife to Pubkitchen; scope_modified = true; "You take your fishing knife and start cutting off a block of congealed oil. It takes a while, and your knife gets very messy, but eventually you manage to carve out a block that's about half of what was there. You put your fishing knife down to grab the block of oil in your hands."; } else { "You already took some oil out, and it's probably enough. If you run out, you know where to find more."; } Search: <>; ], has static concealed; Object Cookingoil "block of solidified oil" with parse_name [ n ; n = 0; while (NextWord() == 'greasy' or 'slippery' or 'block' or 'of' or 'slab' or 'cooking' or 'oil' or 'congealed' or 'solidified' or 'solid' or 'white' or 'fat') n++; return n; ], description "This is old cooking oil, that solidified after being left out here for who knows how long. It's roughly a cube of one foot by one foot by one foot. It's pretty slippery and greasy.", before [ p; Insert: if (second == backpack) { if (keep_silent == 0) {"You don't want to put this oily mess in your backpack.";} rtrue;} if (second == aPot or Metalbowl) {move self to second; scope_modified = true; print_ret "You put the oil in ", (the) second, "; it is easier and less messy to carry this way."; } Burn: if (location == Scenicview || firewood in location) { if (parent(self) == aPot or Metalbowl) { p=parent(self); if (location == Scenicview) {;} else {;} rtrue; } else { "Putting the block in the fire would just melt it, with no hope of recovering the oil."; } } "You need to start a fire to melt the block of oil."; ], after [; Drop: "Dropped. It's not like you wanted to use it for cooking, so it's fine on the floor.";], has ; ! TODO (in AMUSING): > slide oil / pour oil / slip on oil : The oil isn't hot enough to be liquid. Besides, may I remind you that you're lost at sea; this is no time to build a slip and slide. Object CookingoilMelted "liquid cooking oil" with name 'cooking' 'oil' 'liquid' 'melted', description [; print_ret (The) parent(self), " is now full of liquid cooking oil; there's a few quarts here."; ], before [p; Insert: p = parent(self); ; rtrue; ], has pluralname; Object aPot "pot" with name 'pot' 'stainless' 'steel' 'aluminium', description [; if (CookingoilMelted in self) { <>; } "This is a pot you took from the pub's kitchen. It's made of metal, and pretty sturdy."; ], before [; Burn: if (location == Scenicview && F_SCENIC_FIRE) {<>; } if (firewood in location) {<>; } !if (Cookingoil in self) { <>; } "You do not have a fire ready."; ], capacity 1, has container open transparent; Constant MSG_THINGS_LEFT_ON_SHELF "here are quite a few things left on the shelves"; Constant MSG_THROUGH_THE_DOOR_EAST " through the door at the east."; Object StorehouseFront "Storehouse - Front" with description [; print_ret "T", (string) MSG_THINGS_LEFT_ON_SHELF, "; one seems to be for random tools and hardware, and another one, in the corner, is for food -- breakfast food, apparently. You can go west, around the shelves and further in the storehouse, or leave", (string) MSG_THROUGH_THE_DOOR_EAST; ], semidark_description [; print_ret "The storehouse doesn't have any windows, so it's quite dark in here; but with the door open, you can see enough to notice that t", (string) MSG_THINGS_LEFT_ON_SHELF, ". You can't really go further in the storehouse, as it is too dark, but you can go out", (string) MSG_THROUGH_THE_DOOR_EAST;], w_to [; if (location == thedark) {"You'd rather not go further without a source of light.";} else { return StorehouseBack; }], in_to [; return self.w_to(); ], e_to OneBigDoor, !Outsidethestorehouse out_to OneBigDoor, !Outsidethestorehouse, before [; SwitchOff,Drop,Insert,PutOn: if (noun == Torch) { print_ret (string) MSG_TURNOFF_LIGHT_STOREHOUSE; } ], has semidark; Object -> Hardware "hardware" with description "On the shelves by the door are spanners and wrenches of different sizes, some batteries, some spare lightbulbs, and a few wires.", parse_name [ n ; n = 0; while (NextWord() == 'tools' or 'spanners' or 'batteries' or 'lightbulbs' or 'spare' or 'wires' or 'hardware' or 'wrenches') n++; return n; ], before [; Take, Insert: "You don't have the need for any of them right now, but you know where they are if you need them."; ], ! TODO: replace batteries? has pluralname concealed; ! will be ~absent in StartAct2 Object -> BreakfastFood "breakfast food" with description [; print "You'll need more than the food on this shelf to survive, but what's on display here might still be very useful to you. The bag of coffee might still be good, but you're not sure about these teabags. The jam is probably bad, as well as the margarine; but those cans of beans are almost definitely still edible. "; print_ret (string) MSG_NOT_HUNGRY_RN, ", but it's nice to know your menu choices have slightly expanded."; ], parse_name [ n ; n = 0; while (NextWord() == 'breakfast' or 'supplies' or 'food' or 'brunch' or 'coffee' or 'bag' or 'tea' or 'teabag' or 'jam' or 'jar' or 'jars' or 'margarine' or 'container' or 'beans' or 'bean') n++; return n; ], before [; Take, Open, Eat, Insert: print_ret (string) MSG_NOT_HUNGRY_RN, "."; ], has pluralname concealed; ! will be ~absent in StartAct2 Object StorehouseShelves "shelves" with parse_name [ w n i ; n = 0; w = NextWord(); i=0; while (w) { if (w == 'storehouse' or 'storage') { i++; w=NextWord(); } ! it's an adjective, only add it if there's other things else { if (w == 'shelves' or 'shelf') { n=n+1+i; i=0; w=NextWord(); } else {return n;} } } return n; ], description [; if (real_location == Outsidethestorehouse) { print (string) MSG_YOU_DECIDE_CLOSER_LOOK, "the storehouse"; print (string) MSG_AND_HEAD, "inside.^"; ; rtrue; } else { print "You step aside so the sun lights the shelves a bit better. There are a few tools, a little bit of hardware, and "; if (parent(Torch) == nothing) { score = score + 5; print "-- ah! A torch! "; if (_AtFullCapacity(player) == false) { move Torch to player; scope_modified = true; "You grab it, wondering if it still works, and if there are any batteries inside."; } else { move Torch to real_location; scope_modified = true; "Good to know it's here, but you don't have room for it right now."; } } else { "a few spare lightbulbs."; } } ], found_in StorehouseFront Outsidethestorehouse, react_before [; if (noun == self && action ~= ##Examine && real_location ~= StorehouseFront) { print_ret (string) MSG_WRONG_LOCATION; } ], before [; GoAround: if (real_location == StorehouseFront) { ; rtrue; } ! TODO: unnecessary flourish? rework description instead? Search: <>; ], has static concealed semidark absent reactive; ! will be ~absent in StartAct2 ! TODO: should this be a transparent container and have hardware and breakfast food? would this make for fewer moving objects? Constant MSG_YOU_TURN_OFF_TORCH "You turn off the torch"; Object Torch "torch" with parse_name [ n w ; n = 0; w=NextWord(); while(w) { if (w=='light' && ~~(real_location == Insidethepublandlordshouse or Insidehouses)) { n++; w=NextWord(); } else { if (w=='torch' or 'flashlight' or 'stick') { n++; w=NextWord(); } else { return n; } } } return n; ], description [; print "An old torch, with a cylindrical stick-like body; this is also where you insert the batteries."; @new_line; return 0; ], before [; Open: "The torch opens, and there's a battery inside. You put it back together; it is much more useful this way."; Insert: if (second == backpack) { if (self has light) { give self ~light; print (string) MSG_YOU_TURN_OFF_TORCH, " and put it";} else {print "You put the torch";} move self to backpack; scope_modified = true; " in the backpack."; } else { if (second has container) {"You'd rather keep it in your hand.";} } ], after [; SwitchOn: give self light; rfalse; SwitchOff: give self ~light; print_ret (string) MSG_YOU_TURN_OFF_TORCH, " so as to preserve the battery."; ], has openable switchable semidark; ! can be seen in the dark, otherwise the players are stuck ! the torch should always be on here Inside StorehouseBack "Storehouse - Back" with description "The light of your torch shows more shelves, with a few cans of food -- mostly fish and Spam -- and a couple of bottles of condiments here. Further in the storehouse, there seems to be a dark room, which you enter by going west through a door frame; you can also go back out to the front of the storehouse, towards the east.", before [; SwitchOff,Drop,Insert,PutOn: if (noun == Torch) { print_ret (string) MSG_TURNOFF_LIGHT_STOREHOUSE; } ], w_to Canningworkbench, in_to Canningworkbench, e_to StorehouseFront, out_to StorehouseFront, has ; ! This backpack is very cool Object -> backpack "backpack" with parse_name [ n ; n = 0; while (NextWord() == 'sack' or 'satchel' or 'backpack' or 'bag' or 'rucksack' or 'khaki' or 'green' or 'military') n++; return n; ], initial "A backpack is here, slouched against the wall by the door frame.", description "This khaki backpack isn't broken or torn; it's just been forgotten, left slumped against a wall at the back of the storehouse. This is great for you, and will increase your carrying capacity.", before [; Drop, Disrobe: "No way; this backpack is extremely useful to you."; Search, Open: print "The backpack "; if (PrintContents("contains ", self) == 0) { print "is empty"; } "."; Take, Wear: if (self hasnt moved) { score = score + 5; } move self to player; give self worn; scope_modified = true; "You take the backpack and wear it on your shoulders."; Receive: if (noun == aPot or Metalbowl && CookingoilMelted in noun) { if (keep_silent == 0) {"This would only result in a soggy mess."; } rtrue;} if (noun == aFish) { if (keep_silent ==0) { "This would surely give the backpack a horrible smell."; } rtrue;} if (noun == WigglyWorm) { if (keep_silent ==0) { "The poor guy would probably get crushed in there."; } rtrue;} if (noun == Fishingrod) { if (keep_silent ==0) { print_ret (string) MSG_FAR_TOO_LARGE, " to fit in the backpack."; } rtrue; } Close: "You'd rather leave it open."; ], has container openable open clothing; Object -> DoorFrame "door frame" with name 'door' 'frame' 'dark' 'room', description "You light up the room with your torch, and can't really figure out what the room was used for. You'll have to go take a closer look.", before [; Enter: <>; ], has enterable static concealed; Object -> Food "food" with parse_name [ n ; n = 0; ! covers "bottles" while (NextWord() == 'food' or 'shelves' or 'cans' or 'shelf' or 'can' or 'jar' or 'jars' or 'kilner' or 'canning' or 'bottle' or 'condiment' or 'sauce' or 'sauces' or 'worcestershire' or 'marmite' or 'spam' or 'canned' or 'fish' or 'grey' or 'mullet' or 'various' or 'bluefish') n++; return n; ], description "These shelves haven't been completely emptied, as there are a few cans, jars and bottles left. The bottles are mostly Worcestershire and Marmite -- which confirms that the island was inhabited by British people. The cans are cans of SPAM spiced ham, with the iconic label; as for the jars, they look like regular canning jars, probably Kilner jars, and they contain a grey and silver mixture. Coming closer, you see there are labels: ~Grey mullet~, ~Bluefish~, and the appetizing-sounding ~Various~. This probably means the people living on the island fished extensively, and canned whatever fish they could spare in order to have some on hand at any time. This is very good news for you; the cans will last a while and save you some trouble.", before [; Take, Eat, Drink: print_ret (string) MSG_NOT_HUNGRY_RN, "."; ], has concealed pluralname; ! the torch should always be on here Inside Canningworkbench "Canning workbench" with description [; print "It t"; if (self has visited) { print "ook"; } else {print "akes"; } print " you a few minutes to realize what this room was used for, but you realize this was a canning workbench, which presumably was used to can fish, and maybe other things. There is a workbench in the middle of the room"; if (Metalbowl hasnt moved) { print ", on top of which is resting a metal bowl"; } print_ret ". A low sink is to the side of the room, next to a stovetop, on top of which is a pressure canner; the rest is empty counter space, and a few empty Kilner jars", (string) MSG_ONLY_WAY_IS_OUT, "."; ], before [; SwitchOff,Drop,Insert,PutOn: if (noun == Torch) { print_ret (string) MSG_TURNOFF_LIGHT_STOREHOUSE; } ], e_to StorehouseBack, out_to StorehouseBack, has ; Object -> Metalbowl "metal bowl" with name 'metal' 'bowl' 'stainless' 'steel', description [; if (CookingoilMelted in self) { <>; } print "This metal bowl was probably used to gut fish; it looks like stainless steel, and cleaned up very nicely."; if (PrintContents(" The bowl contains ", self)) {print ".";} @new_line; @rtrue; ], before [; Smell: "This bowl doesn't even smell like fish anymore, which is pretty incredible."; Burn: if (location == Scenicview && F_SCENIC_FIRE) {<>; } if (firewood in location) { <>; } !if (Cookingoil in self) { <>; } "You do not have a fire ready."; ], capacity 1, has concealed container open transparent; Object -> Kilnerjars "Kilner jars" with parse_name [ n ; n = 0; while (NextWord() == 'kilner' or 'canning' or 'jars' or 'jar' or 'mason' or 'lid' or 'lids') n++; return n; ], description "A dozen clean, empty Kilner jars are resting on the counters; their lids are somewhere around there, too. These would presumably have been used to can more fish.", before [; Take, Insert, Receive: print_ret "They are", (string) MSG_BREAKABLE_SMALL_GLASS; ], has concealed; Object -> Workbench "canning equipment" with parse_name [ n ; n = 0; while (NextWord() == 'workbench' or 'stovetop' or 'top' or 'work' or 'worktop' or 'sink' or 'pressure' or 'canner' or 'cooker' or 'knob' or 'knobs') n++; return n; ], ! todo: sink c'est vraiment pas pareil que le reste, "switch on sink" et il te répond quelque chose sur le stovetop... description "There is everything you need here to can fish: a workbench, as high as your waist, to cut the fish; a sink, to clean it; a stovetop, to boil water; and a pressure canner, to put the jars in for sterilization.", before [; Take: "You don't really need any of this canning equipment right now. It's good to know it's there, but you might never end up needing it."; SwitchOn, Push, Turn: if (F_GENERATORS_ON == 0) {print_ret (string) MSG_STOVETOP_OFF, (string) MSG_NO_ELEC_ON_ISLAND;} else { print_ret (string) MSG_STOVETOP_ON; } SwitchOff: "The stovetop is already off."; ], has concealed supporter; Outside Outsidethestorehouse "Outside the storehouse" with description [; print "You are near the edge of the cliff. There is a "; if (FISH_ELEVATOR_UP) { print "platform here, hanging via a rope-and-pulley mechanism above a beach"; } else {print "rope-and-pulley mechanism here, attached to a platform that is currently on the beach below";} "; this was probably used for fishing. The building here, towards the west, is larger than most other ones in the village, and doesn't have any windows; it looks like the island's storehouse. Its door was left open, and you can see there still are a few things inside on its shelves. South is an overgrown garden, and southeast is the island's pub. You can also go east to a house by the cliffs."; ], s_to Communitygarden, e_to Houses2, se_to Outsidethepub, w_to OneBigDoor, !StorehouseFront, in_to OneBigDoor, !StorehouseFront, d_to [; if (parent(player) == Fishelevator) { <>; } else { "The obvious way would be by getting in the platform and untying the rope."; }], has ; Outside Outsidethepub "Outside the pub" with description ! todo: a better name? trinity? tristam & flotsam? twin isles? something sciencey? "The building in front of you has a sign displaying ~SHIP AND ANCHOR~ -- a great name for a pub on this island, really. From the outside, it doesn't really look like your classic English pub: no thatched roof here, just the same greenish corrugated tin roof you see everywhere on this island. But the building doesn't look in bad shape. Behind it, to the west, is a small garden; paths lead northwest and southwest to other buildings, or east towards the town centre.", n_to Houses2, e_to Centralplaza, w_to Communitygarden, sw_to Publandlordshouse, nw_to Outsidethestorehouse, in_to OneBigLockableDoor, has ; Outside Communitygarden "Overgrown garden" with description "This seems to have been, a long time ago, some sort of vegetable patch. About a dozen shallow trenches have been dug here; they are now covered in weeds and tall grass. You're guessing the people living here were trying to grow a few vegetables, to supplement a diet that mostly consisted of fish from the sea and canned food from the island's storehouse, which you can see to the north. You are behind the island's pub, which is east of you; there is also a house to the south.", n_to Outsidethestorehouse, s_to Publandlordshouse, e_to Outsidethepub, has ; ! TODO: implement "x garden" from other locations Object -> Garden "overgrown garden" with parse_name [ n ; n = 0; while (NextWord() == 'brambles' or 'bushes' or 'weeds' or 'shallow' or 'trench' or 'tall' or 'grass' or 'rows' or 'garden' or 'patch' or 'victory' or 'thick' or 'vegeta') n++; ! covers "vegetation" and "vegetable" return n; ], description "The trenches that were dug by the inhabitants of the island have been invaded by weeds and grass; the outline of the vegetable patch is only vaguely discernible under the thick vegetation.", before [; Search, Dig: print "You take a look at the trenches, hoping to find something interesting"; if (Sixpence4 in self) { move Sixpence4 to player; scope_modified = true; ". After a few minutes, you spot a coin; it's a sixpence, that you pick up."; } else {", but there doesn't seem to be anything else."; } Cut, Cut2, Take: "You probably will want to clear that patch and try to revive it if you have to stay here for months, or years. But you haven't resigned yourself to that fate yet; let's first explore options to escape the island sooner than later."; ], has concealed static; Coin -> -> Sixpence4 "shiny sixpence" with name 'sixpence' 'coin' 'shiny', age 1956; Outside Publandlordshouse "Small house behind the pub" with description "This is the last house of the village on this side of the island; it is rather small, compared to the other ones on the island, but looks exactly the same as the other buildings here. It is fairly close to the steel tower, which is southwest, and behind the pub, which is northeast. North is an overgrown garden, and east are a few more houses.", n_to Communitygarden, e_to Houses, ne_to Outsidethepub, sw_to BaseOfTower, in_to OneBigDoor, ! Insidethepublandlordshouse has ; Outside BaseOfTower "Base of tower" with description [; F_TRISTAM_DISCOVERED=1; ! we're talking about the island in the description ! this flag will be up if you finish the game, since you need the screwdriver up the tower to enter the white house print "A steel tower rises overhead, black against the sunny sky. This is an observation tower, ", (string) MSG_TOWER_FACES_SOUTHEAST; print " The metallic mast at the top of the tower means it doubles as a radio tower, though you don't know where the controls are."; if (F_LADDER_FIXED == 0) { print " The ladder is missing a few rungs, which makes you unable to climb it -- for now."; } " You can go back to the little house to the northeast."; ], ne_to Publandlordshouse, u_to [; <>; ], has ; ! F_LADDER_FIXED already declared Object -> Ladder "ladder" with parse_name [ w n ; n = 0; w = NextWord(); while (w) { if (w == 'ladder' or 'wooden' or 'hole' || (parent(Rung) == nothing && w =='rung' or 'rungs')) { n++; w=NextWord(); } else {return n;} } return n; ], description [; if (F_LADDER_FIXED == 0) {<>; } else {print_ret (string) MSG_THE_LADDER, "now fixed; you can climb it safely.";} ], found_in BaseOfTower Topofthetower, before [; Climb, Enter: if (F_LADDER_FIXED == 0) { print_ret (string) MSG_THE_LADDER, "missing a few rungs, including the ones closest to the ground. You don't think you could manage to climb without fixing it first."; } else { if (location == BaseOfTower) { print "You climb up the ladder and reach the top of the tower.^"; Playerto(Topofthetower); rtrue; } else { print "You safely climb down the ladder and reach the base of the tower.^"; Playerto(BaseOfTower); rtrue; } } ! TODO: "climb up/down ladder" Receive: if (noun == Rung) { ! F_LADDER_FIXED has to be 0, because Rung disappears after score = score+5; F_LADDER_FIXED = 1; remove Rung; scope_modified = true; "You insert the rungs you found in the woodshop into the ladder holes; you have to find the right angle to get them in, but they fit perfectly. The ladder is now fixed and ready to use."; } else { if (F_LADDER_FIXED) { print_ret (string) MSG_ALREADY_FIXED_LADDER; } else { "This will not work to fix the ladder.";} } Fix: if (F_LADDER_FIXED) { print_ret (string) MSG_ALREADY_FIXED_LADDER; } else { if (CommonAncestor(Rung, player) ~= 0) {<>; } else { "You don't exactly know how to fix this."; } } ], has static concealed absent; ! will be ~absent in StartAct2 Coin -> Sixpence2 "dirty sixpence" with name 'sixpence' 'coin' 'dirty', age 1959, before [; Rub: "No matter how hard you scrub, it is still dirty."; ], has; Outside Topofthetower "Top of the tower" with description "The platform at the top of the tower is rather small. A low barrier runs around the platform, giving a very wide field of vision. From here, about twenty feet off the ground, you can see the village very well, as well as the white house behind the fence. The view of the sea is incredible; you can see further away, including the small island towards the southeast. You can climb back down the ladder.", d_to BaseOfTower, before [; Jump: "You would surely break your legs, or worse; you're not that desperate yet."; ], has ; Object -> AllTheBuildings "village" with parse_name [ n ; n = 0; ! "commun" = community while (NextWord() == 'houses' or 'storehouse' or 'pump' or 'fountain' or 'fence' or 'guard' or 'shack' or 'guardhouse' or 'garden' or 'commun' or 'pub' or 'shop' or 'woodshop' or 'white' or 'house' or 'field') n++; return n; ], description "Yep, you can see that part of the village too, from way up here.", before [; Touch, Take, Eat, Turn, Push, Pull,Rub: "You cannot do anything from this high."; ], has scenery concealed; Object -> Flatheadscrewdriver "flathead screwdriver" with name 'flathead' 'standard' 'rusty' 'screwdriver', initial "Someone dropped a screwdriver here.", description "This seems like a standard, slightly rusty flathead screwdriver; its head is rather small.", has ; ! did we drink from the fountain Global F_FOUNTAIN_DRANK = 0; Outside Centralplaza "Centre of the village" with description MSG_DESC_PLAZA, n_to Shop, s_to Houses, e_to Fencedarea, w_to Outsidethepub, ne_to Dieselgenerators, before [; Fill: if (F_FOUNTAIN_DRANK ==0) {"You're not even sure the fountain is still working."; } else { "Judging by the speed at which it comes out of the fountain, it's best to preserve it."; } ], has ; Object -> Fountain "fountain" with parse_name [ n ; n = 0; while (NextWord() == 'fountain' or 'tub' or 'metal' or 'pump' or 'water' or 'freshwater') n++; return n; ], description [; print "The village fountain is really just a small pump that can pour water over a metal tub."; if (PrintContents(" Inside the metal tub is ", self)) {print ".";} @new_line; @rtrue; ], before [; ! TODO: operate pump Push, Drink, SwitchOn, Pump: if (F_FOUNTAIN_DRANK == 0) { F_FOUNTAIN_DRANK=1; score = score+1; "Amazingly, the fountain still works, although slowly, and the water that falls in the tub is very clear. Tasting it reveals it's freshwater, which is a big relief; you may not have to collect rainwater to survive here after all."; } else {"You drink some of the water from the pump and instantly feel refreshed."; } ! put water in bowl Insert: <>; ], has static concealed container open transparent; Coin -> -> Sixpence3 "damaged sixpence" with name 'sixpence' 'coin' 'damaged', age 1959; Outside Houses "Houses by the town centre" with description [; print "A few houses are arranged in a row that forms a path going north, to a sort of plaza at the centre of the village, and south, to the edge of the plateau. The houses look similar, except the door to one of them looks different from the others"; if (F_CRUDE_DOOR_OUT == 0) { print " -- much cruder, as if it had been replaced."; } else { print "; you managed to remove it from its frame.";} " You can cut across the grass to the west, to another house, or to the east, towards a fence."; ], n_to Centralplaza, s_to Topofthestairs, e_to Aroundthefence, w_to Publandlordshouse, ne_to Fencedarea, in_to [; if (F_CRUDE_DOOR_OUT) { return Innerdyhouse; } else { "All of these doors are closed and locked."; } ], has ; Object -> CrudeDoor "crude door" with parse_name [ n ; n = 0; while (NextWord() == 'crude' or 'cruder' or 'different' or 'hinge' or 'pin' or 'wooden' or 'door' or 'hinges' or 'exterior' or 'outside' or 'unique') n++; return n; ], description [; if (F_CRUDE_DOOR_OUT == 0) { "This door looks rather unique, as if it had been hacked together using only the resources of the island; the other doors look like standard doors that must have been made in a factory and imported here. Interestingly, the hinges are positioned on the exterior of the house here."; } else { "You succeeded in taking the pin out of the hinges; the door is now out of the way, against the wall.";} ], before [; Open: if (F_CRUDE_DOOR_OUT==1) {; rtrue; } else { ; rtrue; } Close: if (F_CRUDE_DOOR_OUT==1) { "Since the door is out of the way, you don't need to do this anymore."; } Lock, Unlock: if (F_CRUDE_DOOR_OUT==1) {; rtrue; } else { if (second == Flatheadscrewdriver) { ; rtrue; } ! "unscrew door with screwdriver" is good enough "You don't have the key to any of these doors. But maybe there's another way to open the crude door."; } Attack: "These doors are quite sturdy -- even the crude wooden door, which doesn't budge."; Receive: if (F_CRUDE_DOOR_OUT == 0) { ; rtrue; } Take, TakeWith: if (F_CRUDE_DOOR_OUT == 0) { if (second) { if (second == Fishingknife) {"You try to remove the pin with the fishing knife, but you keep cutting your fingers while trying to grab the pin. This might not be the right tool for the job.";} if (second == Flatheadscrewdriver) { <>; } } print_ret (string) MSG_HINGES_ARE_SMALL; } else { ; rtrue; } Turn: if (parent(Flatheadscrewdriver) == player or backpack or location) { if (F_CRUDE_DOOR_OUT == 0) { F_CRUDE_DOOR_OUT=1; score = score+2; "After a few tries, you manage to wedge the screwdriver between the pin and the top hinge; after that, it's only a matter of lifting the pin out. You do the same for the two other hinges; the door then wobbles free. You catch it before it falls to the floor, then prop it up against the side of the house."; } else { ; rtrue; } } else { print_ret (string) MSG_HINGES_ARE_SMALL; } ! TODO: take door down with screwdriver / wedge/insert screwdriver under pin/hinges / remove|lift pin out of hinge ], has static openable lockable locked concealed; Inside Innerdyhouse "Inside a house" with description [; print "This is a small house, with only the bare necessities: a bed, a small nightstand, a few chairs, and a bathroom. Life here was decidedly rather spartan"; if (SFbookwiththecode in Nighhtable) { print ". There is a book on the nightstand"; } print_ret (string) MSG_ONLY_WAY_IS_OUT, "."; ], out_to Houses, before [; Sleep: "It's still a bit early in the day to sleep."; ], has ; Object -> Nerdyfurniture "furniture" with name 'furniture' 'bed' 'chairs' 'bathroom', description [; print "There really isn't much here for furniture; you're guessing life here was pretty regimented, and that food was only cooked and eaten at "; if (Inpub has visited) {"the pub.";} else {"some sort of cafeteria.";} ], before [; Take: "You don't have the need for any of these."; SleepOn: <>; ], has concealed ; Object -> Nighhtable "nightstand" with name 'nightstand' 'night' 'table' 'bedside', description [; print "A lovely wooden nightstand."; if (SFbookwiththecode hasnt moved) { print " There is a book on it.";} @new_line; @rtrue; ], before [; Take: "You don't see why you'd need to take that."; ], has supporter concealed ; Object -> -> SFbookwiththecode "science-fiction book" with parse_name [ n ; n = 0; while (NextWord() == 'scifi' or 'sci' or 'fi' or 'book' or 'kensington' or 'garden' or 'brian' or 'moriarty') n++; return n; ], description [; print "Judging by the cover, this looks like a ", (string) MSG_SCIFI_BOOK, ". "; if (LibraryMansion has visited) { print "The only other place where you've seen books -- ", (string) MSG_SCIFI_BOOK, "s, too -- on this island is the library in the white house. Perhaps it came from there?"; } else { print "It's the only book you've seen so far on the island; you hope there is more, or you'll be reading this one for years..."; } " The title is ~Kensington Gardens~, by Brian Moriarty. Never heard of it.";], before [; Open, Search: "You flip through the book; it seems to be about nuclear apocalypse, and one person's quest to prevent it. At the very last page, four digits are written: 5-2-1-8. You wonder what these are for."; ! TODO: score here? no? ], has ; Coin -> Shilling2 "rusty shilling" with name 'shilling' 'coin' 'rusty', age 1957; ! TODO: can clean the steps starting from the top? Outside Topofthestairs "Top of the stairs" with description [ i; ! testing code !for(i=0:ii) ~absent; WE_KNOW_IT_IS_STAIRS=1; "You are standing near the south edge of the plateau. You can see the village from here; north of you is a row of houses. A long flight of stairs leads down to the forest by the beach.";], n_to Houses, d_to [; ; rtrue; ], has ; ! TODO: will someone want to do "x platform", should we add a GoSee in platform so it works? Outside Houses2 "House by the cliff" with description [; print "You are following a wide path along the northern cliff of the island; west is the island's storehouse, and east is a small shop, while going south, behind the house, leads to the island's pub. There is a small house here; the door "; if (InsideHouses has visited) { print "is"; } else { print "might be";} " unlocked."; ], s_to Outsidethepub, e_to Shop, w_to Outsidethestorehouse, in_to Insidehouses, has ; Outside Shop "Small shop" with description [; print "This is a small shop, with a wide window allowing you to peek inside the shop. The window has been "; if (F_SHOP_SMASHED == 0) {print "painted with a crude logo, displaying ~Harry's Earthly Pleasures~."; } else { print "shattered, unfortunately."; } " Judging by what you see through it, that shop has wares that were probably imported from the land -- hence the play on words. The cliffs advance to form a small tip to the north of here; you can also go east, towards a woodshop, or west, towards a small house."; ], ! TODO: too risqué ? n_to Scenicview, s_to Centralplaza, e_to Woodshop, w_to Houses2, in_to OneBigDoor, !Inshop, has ; ! Have we smashed the woodshop window yet !Global F_WOODSHOP_SMASHED = 0; ! Have we smashed the "bits and bobs" shop yet !Global F_SHOP_SMASHED = 0; ! Have we smashed the window of the house by the cliff for fun yet !Global F_HOUSE_CLIFF_SMASHED = 0; Constant MSG_SHATTERS "shatters in a terrible noise."; Constant MSG_CANT_GO_THROUGH_WINDOW "You cannot go out through a solid window."; Object ThreeWindows "window" with found_in [; if (location == Shop or Woodshop or Houses2 or Inshop or Insidethewoodshop or Insidehouses) { rtrue; } else { rfalse; } ], description [; if (location == Houses2) { PARSED_HOUSE = 1; <>; } else { location.description(); rtrue; } ], name 'window', ! TODO: parse_name "broken window" et "logo" pour harry? before [; Climb, Enter: if ( (location == Houses2 or Insidehouses && F_HOUSE_CLIFF_SMASHED) || (location == Shop or Inshop && F_SHOP_SMASHED) || (location == Woodshop or Insidethewoodshop && F_WOODSHOP_SMASHED)) { print "You cautiously climb "; if (location == Houses2 or Shop or Woodshop) { print "in"; } else {print "out"; } print "side through the shattered window.^"; switch(location) { Houses2: PlayerTo(Insidehouses); rtrue; InsideHouses: PlayerTo(Houses2); rtrue; Shop: PlayerTo(Inshop); rtrue; Inshop: PlayerTo(Shop); rtrue; Woodshop: PlayerTo(Insidethewoodshop); rtrue; Insidethewoodshop: PlayerTo(Woodshop); rtrue; } } else { print_ret (string) MSG_CANT_GO_THROUGH_WINDOW;} Exit: if (location == Insidehouses) { if (F_HOUSE_CLIFF_SMASHED) { <>; } else { print_ret (string) MSG_CANT_GO_THROUGH_WINDOW; } } if (location == Inshop or Insidethewoodshop) { <>; } Attack: if (ALargeRock in player) { ; rtrue; } else { "You could, but you can't really see a rock large enough to smash the window."; } Receive,ThrownAt: if (noun == ALargeRock) { if ( (location == Houses2 or Insidehouses && F_HOUSE_CLIFF_SMASHED) || (location == Shop or Inshop && F_SHOP_SMASHED) || (location == Woodshop or Insidethewoodshop && F_WOODSHOP_SMASHED)) { "This window is already as broken as can be."; } ! if we're here, there's a window to break print "You lift the rock above your head, then throw it against the window, as hard as you can. The window "; if (location == Houses2 or Insidehouses) { if (location == Houses2) { move ALargeRock to Insidehouses;} else { move ALargeRock to Houses2; } scope_modified = true; F_HOUSE_CLIFF_SMASHED = 1; print_ret (string) MSG_SHATTERS; } if (location == Shop) { move ALargeRock to Inshop; scope_modified = true; F_SHOP_SMASHED = 1; score = score + 2; } if (location == Woodshop) { move ALargeRock to Insidethewoodshop; scope_modified = true; F_WOODSHOP_SMASHED = 1; score = score + 2; } print_ret "of the shop ", (string) MSG_SHATTERS, " It makes you feel bad for a second, before you remember how dire your situation is."; } ], has concealed static absent; ! will be ~absent in StartAct2 Outside Scenicview "Scenic view" with description [; print "Atop the cliffs is a small grassy area that looks rather pleasant. From here, the immensity of the ocean is on full display, and it feels like a nice area for a rest. Apparently, you're not the only one to have had this idea: a few rocks have been placed here, in a circle, and you can see the "; if (F_SCENIC_FIRE == 0) { print "remnants of a "; } "fire in the centre of the circle. Looks like this was a popular picnic area. You can go back towards the small shop to the south."; ], s_to Shop, has ; [ MeltOil nou ; remove Cookingoil; move CookingoilMelted to nou; scope_modified = true; print_ret "You carefully place ", (the) nou, " containing the oil above the fire. Standing this close to the fire is a bit nerve-wracking, and your hands are getting warm, but the oil is melting rather fast. You take a few breaks to rest your arms and your hands, but after a few minutes, ", (the) nou, " is full of liquid cooking oil."; ]; Constant MSG_LOGS_ON_FIRE "The logs are currently on fire."; Object -> Fire "burnt fire" with parse_name [ n ; n = 0; while (NextWord() == 'fire' or 'logs' or 'wood' or 'burnt' or 'chunks' or 'chunk' or 'spent' or 'remnants' or 'log' or 'campfire') n++; return n; ], description [; if (F_SCENIC_FIRE == 0) {print "No fire has been lit here for a very long time. A few large rocks are arranged in a circle, and a few chunks of wood are in the middle. ", (string) MSG_WOOD_DRY_ENOUGH; } else {print "The fire is burning rather well, and there's enough logs that it will last a while."; } " Next to the fire, there is an empty can of Spam."; ], before [; Remove, Take: if (F_SCENIC_FIRE) { print_ret (string) MSG_LOGS_ON_FIRE;} else { print_ret (string) MSG_WOOD_DRY_ENOUGH, " You can't think of a better spot for them; you'll leave them here so you can start a fire if needed.";} Burn: if (F_SCENIC_FIRE) { print_ret (string) MSG_LOGS_ON_FIRE; } else { if (Lighter in player) { F_SCENIC_FIRE=1; print_ret (string) MSG_WOOD_DRY_ENOUGH, " You use your lighter to burn some of the smaller bits of wood first, then keep working on it until the logs are on fire."; } else { print_ret (string) MSG_NOTHING_FOR_FIRE; } } Receive: if (F_SCENIC_FIRE == 0) { "The fire isn't lit.";} else { if (noun == aPot or Metalbowl) { if (Cookingoil in noun) { MeltOil(noun); rtrue; } else { "You could certainly put that dish on top of the fire to cook something, but what?"; } } else { "You do not want to burn this."; } } Push, Pull, Rub, Touch: if (F_SCENIC_FIRE) { print_ret (string) MSG_LOGS_ON_FIRE; } ], has concealed supporter; Object -> RocksInACircle "rocks" with parse_name [ n ; n = 0; while (NextWord() == 'rocks' or 'rock' or 'stone' or 'stones' or 'circle') n++; return n; ], description [; <>; ], before [; Take: if (parent(ALargeRock) == nothing) { if (_AtFullCapacity(player) == false) { move ALargeRock to player; scope_modified = true; "You take one of the large rocks in the circle."; }} else { "The rock you already took is enough for your purposes."; } ], has concealed; Object -> Emptyspamcan "empty Spam can" with name 'empty' 'spam' 'can', description "A can of Spam, that canned spiced ham that really doesn't taste very good. A wartime delicacy, as Thatcher famously said -- the British army sure ate their share during the war. But you're guessing that if you're on an island in the middle of nowhere, trying to feed dozens of people for months on end, you don't have many options, and you have to resort to it. The menu here probably resembled the one in that Monty Python sketch -- maybe there were fewer Vikings around, though.", before [; Take: "You'd rather not -- it's garbage, at this point."; Receive: "You'd rather not put anything in a can of spam that's been open for that long."; Close: "The lid is missing."; Search: "The spam can is basically empty."; ], has concealed open container; Object ALargeRock "large rock" with name 'large' 'rock' 'stone' 'big', description "This rock is rather large and heavy; you can carry it for a while, maybe even throw it.", before [; Insert: if (second == backpack) { if (keep_silent == 0) {"You'd rather not fill your backpack with rocks; surviving is alreay hard enough as it is.";} rtrue;} else {"That big rock won't fit.";} ! the keep_silent is important for when shuffling objects in the backpack to make room ThrowAt: if (second == OneBigHouse && location == Shop or Woodshop or Houses2) { <>; }; ], after [; Drop: "You drop the large rock, minding your toes."; ], has ; Outside Woodshop "Woodshop" with description [; print "From what you can see inside the large"; if (F_WOODSHOP_SMASHED) { print ", broken"; } " window at the front of the building, this is some kind of woodshop. Presumably, someone here was in charge of making or fixing all sorts of furniture and wooden objects for the whole island; you can see a sturdy-looking table in the middle of the workshop. Another shop is next to this one, to the west; behind the woodshop, you can see diesel generators, to the south, near the fence."; ], s_to Dieselgenerators, w_to Shop, in_to OneBigDoor, !Insidethewoodshop, has ; Object Fence "fence" with found_in [; if (location == Fencedarea or Field or Dieselgenerators or Aroundthefence or Woodshop or Centralplaza or Houses) {rtrue;} else {rfalse; } ], parse_name [ n ; n = 0; while (NextWord() == 'fence' or 'barbed' or 'wire' or 'chainlink' or 'tall') n++; return n; ], description [; ! A simple GoSee doesn't work because the fence is in several locations ! Make everyone go to Fencedarea, except the Woodshop isn't connected to that location so we have a special case ! Additionally the description has to change depending on whether we found the hole or not if (location == Woodshop) { print (string) MSG_YOU_DECIDE_CLOSER_LOOK, "the fence"; print (string) MSG_AND_HEAD, "south.^"; ; rtrue; } if (location == Dieselgenerators) { print (string) MSG_DESC_FENCE; if (F_FOUND_HOLE_IN_FENCE) { print " However, here, there seems to be a hole behind the bushes."; } @new_line; @rtrue; } if (location == Field) { ! we're already in, so it's easier to find the hole if (F_FOUND_HOLE_IN_FENCE == 0) { F_FOUND_HOLE_IN_FENCE=1; MoveFloatingObjects(); print_ret (string) MSG_DESC_FENCE, " However, looking closer at the fence by the bushes, you spot a hole in the fence near the ground."; } else { print_ret (string) MSG_DESC_FENCE, " There seems to be a hole in the fence here."; } } !default case GoSee(Fencedarea, MSG_DESC_FENCE); rtrue; ], before [; Climb: print_ret (string) MSG_NOT_VERY_GOOD_AT_CLIMBING, ", and the barbed wire at the top of the fence would prevent you from going over."; Enter: if (Holeinthefence in location) {; rtrue;} else {; rtrue; } Cut1, Cut2: "The wire seems very strong, possibly too strong to be cut without anything but a pair of wire cutters."; ], has static concealed absent; ! will be ~absent in StartAct2 Outside Dieselgenerators "Power generators of the island" with description [; print "A dirt path leads to an small area off to the side, behind some shrubs and close to the fence closing off the white house. Here, three green machines stand tall; it looks like they used to be the island's main power source."; if (F_GENERATORS_ON == 0) {" The power generators are all connected to a central tank, which would get filled, presumably with diesel, to keep the lights on -- and hopefully power the radio tower. Restarting them would give you a good chance of being able to call for help."; } else { print " You have filled the central tank with cooking oil -- call it biodiesel -- and now the generators are running and making a "; if (generators_load < LOW_POWER) { print "low hum"; } else {print "loud noise"; } print " that indicates the power is on. You're hoping the generators will last until you find a way to call for help."; } " To the north, near the cliffs, is the island's woodshop; you can follow the fence towards the main door to the south, or go to the centre of the village, southwest of you."; ], before [; Listen: if (F_GENERATORS_ON == 0) {print_ret (string) MSG_LISTEN_DEFAULT, " After all, the generators are off.";} else { print "The generators are currently running, and are making a "; if (generators_load < LOW_POWER) { print "low hum, which you hope means it doesn't consume too much oil at the time"; } else {print "loud noise; you worry they are going through the oil a bit too fast";} ". You do need power on to use the radio, after all."; } ], n_to Woodshop, s_to Fencedarea, sw_to Centralplaza, has ; ! TODO: implement "x diesel generators" from the plaza (Centralplaza Fencedarea Woodshop) Object -> Generators "diesel generators" with description [; print "Three imposing green diesel generators made of metal are here; the sticker, which is almost peeled off, says ~Lister Diesel Power Generator - 12 hp~. ", (string) MSG_GENERATORS_MODIFIED, " ", (string) MSG_GENERATORS_SEEN_BETTER_DAYS; if (F_GENERATORS_ON == 0) { " Hopefully you can get them to run for a few hours, so you can find the island's radio and send a call for help.";} else {<>;} ], parse_name [ n ; n = 0; ! also covers 'generators' and 'machines' while (NextWord() == 'generator' or 'machine' or 'diesel' or 'green' or 'lister' or 'sticker' or 'flywheel' or 'paint' or 'power' or 'electricity') n++; return n; ], before [; SwitchOn: <>; SwitchOff: if (F_GENERATORS_ON) { "You're not sure how to do that, and you need the electricity to be on for the island's radio to work."; } ], has switchable pluralname scenery concealed; ! is the tank full of melted cooking oil !Global F_TANK_FULL = 0; Object -> Tank "fuel tank" with description [; print (string) MSG_GENERATORS_MODIFIED; print " The tank is very large, "; if (F_TANK_FULL == 0) { "and can probably store enough fuel for days. The problem is, you have no idea where to find any diesel, if there is even any left on the island. You might need to get creative."; } else { "much larger than whatever oil you poured in there; you hope this will be enough."; } ], name 'fuel' 'diesel' 'tank' 'central', before [; Receive: if (F_TANK_FULL) { "The tank already contains oil."; } if (noun == Cookingoil || ( (noun == aPot or Metalbowl) && Cookingoil in noun) ) { "Using the cooking oil as fuel is a good idea, but the generators run on liquid fuel, not solid.";} if (noun == CookingoilMelted || ( (noun == aPot or Metalbowl) && CookingoilMelted in noun)) { print "Slowly, carefully, you lift ", (the) parent(CookingoilMelted); remove CookingoilMelted; scope_modified = true; F_TANK_FULL=1; " full of cooking oil, and pour the oil inside the tank."; } "You'd rather keep the tank clean."; Enter: "You wouldn't fit through the hole."; Fill: if (F_TANK_FULL || parent(CookingoilMelted) == player or backpack) { <>; } else {"You need to find fuel to fill the tanks with.";} ], after [; Open: print "The lid on top of the tank is heavy, but you manage to push it to the side enough to see what's inside. "; if (F_TANK_FULL == 0) { "The tank looks empty."; } else { "There is still some of your oil left in the tank."; } ], has openable container static concealed; Object -> Crank "crank" with description [; print "The crank is connected to a heavy flywheel. You don't know too much about generators, but it looks like turning the crank starts the flywheel, which starts the whole generator and the fuel injection system. ", (string) MSG_GENERATORS_SEEN_BETTER_DAYS; @new_line; @rtrue;], name 'crank' 'rusty' 'corroded' 'heavy', before [; Turn, Push, Pull: if (F_GENERATORS_ON==1) { "The generators are running pretty smoothly; they don't look like they need any help."; } print "The wheels are very heavy, and it's quite the effort to start turning the crank. You turn it for a few rotations, "; if (F_TANK_FULL == 0 ) { "but nothing happens; even after you flip the small lever on the generator, which in theory should start injecting the fuel, still nothing."; } else {score = score+5; F_GENERATORS_ON=1; give LightSwitchPubL light; give Generators on; "and flip the small lever on the generator to start injecting the fuel. The generator starts shuddering, and lets out a thunderous sound. It works! After all these years, it still works! You can barely conceal your excitement: now you have a chance at calling for help and being rescued! You turn on a second generator in the same way, to make sure all the electrical devices on the island are brought back to life.";} ], has static concealed; ! Have we already looked at the bush once Global F_BUSH_LOOKED_ONCE = 0; Object -> Bush "bushes" with name 'bush' 'bushes' 'shrub' 'shrubs', description [; if (F_BUSH_LOOKED_ONCE == 1 && F_FOUND_HOLE_IN_FENCE == 0) { F_FOUND_HOLE_IN_FENCE=1; MoveFloatingObjects(); print_ret (string) MSG_YOU_DECIDE_CLOSER_LOOK, "the bushes and search them. They are quite dense, and rather prickly, so you proceed with caution; but eventually, you manage to spot a hole in the fence, near the ground."; } else { if (F_BUSH_LOOKED_ONCE == 0) { F_BUSH_LOOKED_ONCE=1; } print "Around the generators, and close to the fence, there are a few bushes and shrubs. They are quite dense, "; if (F_FOUND_HOLE_IN_FENCE == 0) { print "and you can't really see at a first glance if there is anything hiding under or behind them. You might have to take a closer look."; } else { print "but you were able to spot a hole in the fence behind them."; } @new_line; @rtrue; } ], before [; Search: <>; Cut1, Cut2: "The branches of the bush are prickly and thick; you manage to cut one of them after a few minutes and a couple of cuts to your fingers. You decide to give up; there's got to be a better way."; Enter: if (F_FOUND_HOLE_IN_FENCE) { <>; } else { F_BUSH_LOOKED_ONCE=1; <>; } ], has static concealed absent; ! will be ~absent in StartAct2 Object Holeinthefence "hole in the fence" with name 'hole' 'opening' 'in' 'fence', description "There is a hole in the fence here, near the ground and big enough for someone to crawl through. You doubt the hole was made by an animal; someone probably made the hole so they could enter the white house without being seen. Interesting!", before [; Enter: if (location == Dieselgenerators) { if (F_CRAWLED_IN_HOLE == 0) { F_CRAWLED_IN_HOLE=1; if (F_CLIMBED_TREE==0) { score = score+5; } print "The hole is very close to the dense bushes, and going through them isn't easy. You cut your hands on the prickly branches, and even your temple when you try to crouch in the bush. In the end, the best way is to crawl backwards into the bushes, and fumble while trying to find the hole in the fence";} else { print "You crawl backwards into the bushes";} print ": at least your shoes clear the way, and you don't get pricked as much. It's quite the ordeal, and you still manage to get cut a couple more times, but you finally manage to get to the other side, and into the fenced area.^"; PlayerTo(Field); rtrue; } else { ! from the field F_CRAWLED_IN_HOLE=1; print "The key for the fence door is probably somewhere in here, but for this time you're crawling through the hole in the fence. Crawling backwards prevents you from being pricked too much, but there's got to be a better way.^"; PlayerTo(Dieselgenerators); rtrue; } ], found_in [; if (location == Field or Dieselgenerators && F_FOUND_HOLE_IN_FENCE) {rtrue;} else {rfalse; } ], has static concealed absent; ! will be ~absent in StartAct2 Outside Fencedarea "Fenced area" with description "You are standing by an open field, behind a fence, west of a white mansion with a closed front door. The fence is tall, and there is barbed wire at the top; the door here allowed people to go in and out, but the guardhouse shows it was closely monitored. A sign by the guardhouse right behind the fence reads ~Authorised Personnel Only~. You can follow the fence by going north or southeast, or go to the centre of the village by going west; a dirt path to the southwest leads to a few houses near the edge of the village.", n_to Dieselgenerators, e_to OneBigLockableDoor, ! Field, w_to Centralplaza, se_to Aroundthefence, sw_to Houses, has ; Object Guardhouse "guardhouse" with parse_name [ n ; n = 0; while (NextWord() == 'guardhouse' or 'guard' or 'shack' or 'sign' or 'placar' or 'small' or 'chair' or 'desk') n++; return n; ], found_in Field Fencedarea, description [; print "A small shack, with only a chair and a little desk, is "; if (location == Fencedarea) { print "behind"; } else { print "near"; } " the fence, right next to the door. This means there was a guard employed full-time to monitor access, and occasionally point to the sign that says ~Authorised Personnel Only~. But what could be in that white house that was so important to be closed off to the rest of the people in the island?"; ], before [; Touch,Push,Pull,Turn, Insert,Rub: if (location == Fencedarea) { "You cannot do that, as you aren't on the right side of the fence."; } Search, Enter: if (location == Fencedarea) { <>; } else { "You enter the small shack, hoping to find something useful, like a key, or a torch with its batteries still in it; but you find nothing useful."; } ], has static concealed open enterable container absent; ! will be ~absent in StartAct2 Outside Aroundthefence "Around the fence" with description [; print "You are roughly to the south of the tall white mansion, but on the other side of the chainlink fence with barbed wire at the top. "; print_ret (string) MSG_EDGE_OF_PLATEAU, " You're guessing they weren't so tall when the island was inhabited. You can follow the fence to the northwest, or follow the edge of the plateau towards a few houses to the west."; ], w_to Houses, nw_to Fencedarea, has ; Object -> Largetree "trees" with parse_name [ n ; n = 0; while (NextWord() == 'large' or 'tall' or 'tree' or 'trees' or 'forest' or 'branch') n++; return n; ], description [; print_ret (string) MSG_EDGE_OF_PLATEAU, " One of them in particular seems rather sturdy and extends all the way behind the fence."; ], before [; Climb: if (F_CRAWLED_IN_HOLE == 0 && parent(Guardkey) == nothing) { print "You look up, and there is indeed one large branch that grows above the fence. You sigh; you would preferred not having to do this, but...^^You start climbing the tree, slowly and carefully, then sit astride the branch. Your heart is beating fast, and you try your best not to look down as you steadily progress along the branch, which bends under your weight. You keep going -- but the branch is getting too thin to support your weight, and starts cracking and tipping!^^You lose your grip, and land on your back in a mighty crash! Your back is sore, but you don't seem to have broken any bones. After a few minutes, you sit up with some difficulty... and find yourself inside the fenced area! Good thing you landed on the right side of the fence...^^"; if (F_CLIMBED_TREE == 0) { F_CLIMBED_TREE=1; if (F_CRAWLED_IN_HOLE == 0) {score = score + 5;} } PlayerTo(Field); rtrue; } else { "You already have found a way into the field; you'd rather spare yourself the effort of climbing the tree."; } ], has static concealed; Outside Field "Field" with description "You are inside the fence, in a wide open field that's overgrown with rather tall grass. In the middle, the grass hasn't grown as much, suggesting there used to be a dirt path leading from the gate in the fence and the guard's shack, which are west of you, to the front porch of the white house, which looms east of you.", e_to WhiteHousePorch, w_to OneBigLockableDoor, ! Fencedarea, has ; Object -> Grass "grass" with parse_name [ n ; n = 0; while (NextWord() == 'grass' or 'path' or 'tall' or 'short' or 'field' or 'open' or 'green') n++; return n; ], description "This is a big field, about half the size of a football field; whoever built the fence obviously didn't want people to get anywhere close to the white house. Tall, green grass has grown everywhere here, after years without any human presence.", before [; Enter: "You already are in the grass."; Exit: <>; Search: print "You start walking through the grass while looking down carefully; maybe something useful was dropped here, years ago. You drag your feet on purpose, hoping to stumble upon something. This takes a long time,"; if (F_GRASS_SEARCHED == 0) { F_GRASS_SEARCHED =1; print " but you'd rather be thorough; and after ten minutes, you find a shilling, which only strengthens your resolve to walk the rest of the field."; move Shilling1 to player;scope_modified = true; if (parent(Guardkey) == nothing) { score = score + 5; print " A few minutes later, your shoe hits a small, hard object. You get down on your knees and search the grass, and you end up finding a small key!"; if (_AtFullCapacity(player) == false) { move Guardkey to player; } else { move Guardkey to Field; } scope_modified = true; } print " You finish walking the field, but"; } else { print " and"; } " you don't find anything else."; ], has scenery concealed; Coin Shilling1 "dirty shilling" with name 'shilling' 'dirty' 'coin', age 1960; Object Guardkey "guard key" with parse_name [ w n i ; n = 0; w = NextWord(); i=0; while (w) { if (w == 'guard' or 'gate' or 'fence') { i++; w=NextWord(); } ! it's an adjective, only add it if there's other things else { if (w == 'key') { n=n+1+i; i=0; w=NextWord(); } else {return n;} } } return n; ], description "This key opens the fence around the white house. Given where you found it, you're guessing it fell out of the guard's pocket one day and was considered lost."; ! Have we removed the screw from the keypad Global F_KEYPAD_SCREW_REMOVED = 0; Outside WhiteHousePorch "Front door of the white house" with description [; print "Two wide steps lead to a small porch, which makes the front door of the white house look even more imposing. This is a tall double door, and it's made of metal, whereas the house itself is made of wooden boards painted in white. Clearly, this is the entrance of a very private building; the rusty keypad to the right makes it clear that only those who know the secret code can enter."; if (F_KEYPAD_SCREW_REMOVED) { print " You have removed the front plate of the keypad to study its wiring closer."; } " You can go back to the field by going west."; ], w_to Field, in_to [; "To open the door, you need to type the correct code on the keypad."; ], has ; Object -> SteelDoor "front door" with description "The tall double door on the front porch of the white house is made of metal, and looks reinforced. It has a handle, but no keyhole; and it is locked. It would be quite hard to go past this door without typing the correct code on the keypad to the right of the door.", parse_name [ n ; n = 0; while (NextWord() == 'tall' or 'double' or 'metal' or 'door' or 'steel' or 'reinforced' or 'porch') n++; return n; ], before [; Unlock, TryUnlock, Open: <>; ], has static concealed openable lockable locked; Object -> keypad "keypad" with description [; if (F_KEYPAD_SCREW_REMOVED == 0) { print "This is a rather primitive keypad, with buttons arranged in two rows and displaying all numbers from 0 to 9, and an extra button to clear the code. The metal plate has rusted over the years, but the screws holding the plate haven't."; if (F_GENERATORS_ON == 0) { print "You're guessing that, like all keypads, it requires electricity to work and open the door remotely."; } @new_line; @rtrue; } else { ; rtrue; } ], parse_name [ n ; n = 0; while (NextWord() == 'keypad' or 'numeric' or 'pad' or 'button' or 'lock') n++; return n; ], before [; Open, Turn: <>; Unlock: <>; Push: "You need to say which number you want to type."; ], has static concealed open transparent container; Object -> -> plate "metal plate" with description [; print "The rectangular metal plate is "; if (F_KEYPAD_SCREW_REMOVED == 0) { "holding the whole thing together, with a screw at each corner."; } else { "hanging from the wires; you have removed it to take a closer look at the circuit."; } ], name 'rusty' 'metal' 'plate' 'rectangular', before [; Open, Turn: <>; Unlock: <>; ], has static concealed; Object -> -> screws "screws" with description "There are four screws, one at each corner of the metal plate.", name 'screw' 'screws' 'four', before [; Turn, Open: if (Flatheadscrewdriver in player) { if (F_KEYPAD_SCREW_REMOVED == 0) { F_KEYPAD_SCREW_REMOVED=1; move wiring to keypad; scope_modified = true; "This is a flathead screwdriver, and the screw is cruciform, but you give it a go anyway. It ends up working rather well, as the screwdriver is small enough to fit in the screw and turn it without stripping it too much. You manage to remove the front plate; a bunch of wires and connections appear behind it.";} else { F_KEYPAD_SCREW_REMOVED=0; remove wiring; scope_modified = true; "You put the plate back on the keypad and screw the screws holding it."; } } else { "You can't manage to remove the screws with your bare hands."; } Unlock: if (second == 0 or Flatheadscrewdriver) { <>; } if (second == Fishingknife) { "You try inserting the knife in the screws to turn them, but the tip of the blade is too small to make the screws turn."; } "This won't unscrew the screws."; ], has static concealed; Object wiring "wiring" with name 'wiring' 'wire' 'wires' 'circuit', description "You follow the wires under the buttons to try to see where they go. There's a few pieces in the circuit you're not sure about; one of them is connected to the wires for the numbers 1, 2, 5 and 8, while the other wires end up somewhere else, deeper in the circuit.", before [; Search: ; rtrue; Touch,Rub: if (F_GENERATORS_ON ==0) {print_ret "You'd rather not touch these, even if", (string) MSG_NO_ELEC_ON_ISLAND;} else {"You know better than touching wires when the electricity is on.";} ], has static concealed; Global DIGICODE = 5218; [ TypeSub ; ! type number on noun if (second) { if (second ~= keypad) { "You don't know how you could type a number on that.";} } ! here we are in location and if there's a second it's keypad if (noun == -1000) { ! not a number if (verb_word == 'enter') {print_ret (string) MSG_PARSER_NOSUCHTHING; } ! enter nonexistentword else { "This is not a valid number.";} ! type aadvark } ! type number if (location ~= WhiteHousePorch) { "You don't see anything that could be used to type a number."; } if (noun == DIGICODE && F_GENERATORS_ON) { print "As soon as you pushed the last number, a buzz can be heard from the door. You hurry and grab the handle, and the door swings open. You enter the white mansion.^"; if (F_ACT3_STARTED == 0) { F_ACT3_STARTED=1; StartAct3(); } PlayerTo(WhiteHouseLobby); @rtrue; } "You press the button to clear input, then type the number on the keypad, but the door doesn't open."; ]; Verb 'type' * number ->Type * number 'on' noun ->Type; Extend only 'enter' * number ->Type * number 'on' noun ->Type; !======================================================================= ! Act 3 - Mansion [ StartAct3 i ; F_ACT3_STARTED = 1; score = score+5; ! do also the floating objects of act 4, there's not that many i = FIRST_FLOATING_ACT3; while (i < MAX_FLOATING_OBJECTS && floating_objects-->i ~=0) { give (floating_objects-->i) ~absent; i++; } print "^At last, you enter the white mansion, inside of which is something so important that it needed to be protected by a fence, a guard, and a keypad. There were two kinds of people on this island: the ones in the village, who fished and canned and mended and kept the island running, and weren't allowed to enter the fence; and the people who were, who knew the combination of the keypad and could enter the white house. You feel like whatever was going on inside was the whole purpose of occupying the island; at this point, it's not just about finding a working radio anymore, it's also about discovering the secrets of the white house, and finding out why everyone left."; @new_line; @rtrue; ]; ! Sentences used several times Constant MSG_CONTRAP_ROPE "The rope-and-pulley mechanism doesn't look like it does anything but make the buckets go up and down."; Constant MSG_CONTRAP_USHAPED "The U-shaped pipe is hanging horizontally from the ceiling, above the mezzanine. It is made of several segments; the extremity closest to the south wall is angled up, and the opening is wider, like a funnel, while the other side of the pipe runs above the mezzanine and stops right before the buckets."; Constant MSG_CONTRAP_WEIGHT "; should it fall, it would probably pull on the rope, that runs inside a pulley and towards a hole up high in the north wall."; Constant MSG_FOUR_TABLES_CAFET " four tables in total, and wooden benches on each side of the tables. The tables are long and wide, but you're guessing that no more than 20 people would fit here."; Constant MSG_PRIVACY_LOCK "The door has a lock, but it wouldn't be very hard to pick; it's just a privacy lock, the kind you find in bathrooms more often than on bedrooms. Anyone could enter this room by using a flat tool to turn the lock."; Constant MSG_WEIGHT_WAS_BLOCKING "; this was probably the weight that was keeping the door shut."; Constant MSG_NO_IDEA_WHERE_KEY "This door requires a key, and you don't have it; in fact, you have no idea where to find it."; Constant MSG_LIBRARY_MUSTY "You were expecting that wonderful smell of paper, but instead it smells rather musty."; Constant MSG_END_BABEL "flies upwards very fast. The edge of the bucket hits the weight.^^The weight, which wasn't very stable on such a small platform, is out of balance and falls towards the ground, but the rope tenses up before the weight hits the ground. The weight is now in mid-air, balanced with something at the other end of the rope, behind the north wall."; Constant MSG_EW_A_RAT " -- ew! You find the corpse of a rat in the bucket."; Constant MSG_YOUD_LIKE_TO_FIX "You'd like to repair the U-shaped pipe, but you're missing a screw"; Constant MSG_YOU_UNPLUG_PUMP "You unplug the bike pump from the nozzle."; Constant MSG_DESC_DESK "There is a desk, but all the drawers are open and empty."; Constant MSG_DRAWING_MR_CHAD " a picture of Mr Chad, with ~Wot, no sugar?~ caption, as always."; Class InMansion has light; Object InMansionLights "light" with found_in [; if (location ofclass InMansion) {rtrue;} else {rfalse; } ], parse_name [ n ; n = 0; while (NextWord() == 'light' or 'window' or 'opening' or 'outside' or 'switch') n++; return n; ], description [; print "The windows here are all boarded up; barely any sunlight is shining through, and what you see is mostly thanks to the lights in the "; if (location == Quarters or YellowRoom or WhiteRoom) {"hallway."; } else { "lobby."; } ], ! TODO: add it in lab too? "This complex is underground, deep inside the island, so there isn't any natural light here; only the pale glow of the neons." before [; SwitchOff: "You don't know where the switch would be. Besides, you appreciate having the light on."; ], has scenery concealed switchable on; ! Flags for the babel fish puzzle to work ! have we plugged the bike pump Global F_BIKE_PUMP_PLUGGED = 0; ! have we pumped some air in Global F_BIKE_PUMP_PUMPED = 0; ! have we inserted the ball ! this is just "ball in AirCannon" ! have we pushed the statue Global F_STATUE_TURNED = 0; ! have we EVER broken the u-shaped thing Global F_USHAPED_BROKEN = 0; ! have we fixed the u-shaped thing Global F_USHAPED_FIXED = 0; ! have we removed the dead rat ! this is just "aDeadRat in Bucketsandpulley" ! Yay! Global F_BABEL_SOLVED = 0; [ CheckBabelFish ; ! the heavy lifting of checking the puzzle if (F_USHAPED_FIXED == 0 && F_USHAPED_BROKEN) { "Before doing this, you should probably fix the U-shaped pipe."; } if (F_BIKE_PUMP_PUMPED == 0) { "You pull the lever, and nothing happens. You close it again."; } ! ok, so we have pumped some stuff F_BIKE_PUMP_PUMPED=0; print "You pull the lever, and quite a bit of air is expelled, making a loud noise for a fraction of a second."; if (~~(Cricketball in AirCannon)) {@new_line; rtrue; } ! ok, so the ball is in print "^^The cricket ball shoots into the air and flies upwards... "; if (F_STATUE_TURNED == 0) { move Cricketball to WhiteHouseLobby; scope_modified = true; "then unexpectedly hits the hand of the statue, which was on its trajectory, before falling on the floor.";} ! ok, so the ball made it past the statue print "and lands inside the funnel!^^You hear the ball travel through the pipe... "; if (F_USHAPED_FIXED == 0) { F_USHAPED_BROKEN=1; move Cricketball to Mezza; move ScrewUshaped to Mezza; scope_modified = true; "but a screw must have been loose, as the pipe comes undone and the ball drops on the mezzanine.";} print "and it lands perfectly in the bucket on the right.^^"; move Cricketball to Bucketsandpulley;scope_modified = true; if (aDeadRat in Bucketsandpulley) { print "You wait anxiously a couple of seconds, but the bucket doesn't go down. You wonder what could be the problem.";} else { F_BABEL_SOLVED=1; score = score+5; print "The bucket on the right drops down, and the bucket on the left ", (string) MSG_END_BABEL;} @new_line; rtrue; ]; InMansion WhiteHouseLobby "Lobby of the white house" with description [; if (player in Mezza) {"You lean on the railing, and you can see the whole lobby downstairs, with the statue in the middle of the room, the hallway to the library, and the closed door to the north. The ropes, the weight, and the buckets are all out of reach, but the U-shaped pipe is right above your head. A hallway leads further to the east; the entrance is down, to the west."; } else { "The entrance of the white house is a large and rather messy atrium, lit only by a few lights as the windows have been boarded up. The walls are covered in notices and placards, some official-looking, some less so. A bewildering assortment of pipes, buckets and a weight hang on the wall and the ceiling, like some sort of Heath Robinson contraption. A tall statue stands in the middle of the room, in front of a wooden staircase leading up; next to the stairs, leading east, is a wide passageway. A hallway leads to the library, south of here; there is a closed door on the north wall, next to an odd tube-like contraption fixed onto a tilted stand."; } ], n_to [; if (F_BABEL_SOLVED == 0) { return DoorToAntechamber; } else { give DoorToAntechamber open; print "You open the door inwards very easily and enter the room.^"; return Antechamber;} ], s_to LibraryMansion, e_to Cafeteria, u_to [; if (player notin Mezza) { print "You climb the stairs and get on the mezzanine.^"; return Mezza; } ], out_to [; if (player notin Mezza) { print "You open the steel door and exit the white house.^"; return WhiteHousePorch; } ], w_to [; <>; ], before [; Search, Remove, Take, Touch, Turn, Tie, Untie, Smell, Push, Pull, Cut1, Cut2, Rub: if (noun == Weightonplatform || (parent(noun) == Bucketsandpulley or AirCannon && parent(player) == Mezza) || ( ( (parent(player) == Mezza && parent(noun) == WhiteHouseLobby) || (parent(player) == WhiteHouseLobby && parent(noun) == Mezza)) && ~~(noun == 0 or Mezza or Pipebytheroof)) ) { print_ret (The) noun, " ", (isorare) noun, " out of reach.";} ], has ; Object -> GeneralContraption "giant contraption" with parse_name [ n ; n = 0; while (NextWord() == 'machine' or 'giant' or 'contraption' or 'rube' or 'goldberg' or 'heath' or 'robinson') n++; return n; ], description [; print "It all looks purposeful, but it's absolutely mystifying. "; print (string) MSG_CONTRAP_ROPE, " "; print (string) MSG_CONTRAP_USHAPED, " "; print "The weight is precariously resting on a platform that's too small for it"; print (string) MSG_CONTRAP_WEIGHT, " "; "Simply baffling."; ], has scenery concealed; Object -> Mezza "mezzanine" with parse_name [ n ; n = 0; while (NextWord() == 'stairs' or 'staircase' or 'mezzanine' or 'wood' or 'wooden' or 'banister' or 'balustrade' or 'railing' or 'rail' or 'handrail' or 'barrier') n++; return n; ], description [; if (player in self) { <>; } else { "A wide staircase in the lobby leads up to a mezzanine. The mezzanine is rather wide, and has wooden banisters around it.";} ], ! this is called when trying to go a direction while on the mezzanine ! in theory "3" is allowing and "2" is disallowing, but no diff in practice before [; Go: if (selected_direction == e_to) { PlayerTo(Quarters); return 3; } if (selected_direction == u_to) { print "You're already up on the mezzanine.^"; return 2; } if (selected_direction == d_to or w_to) { PlayerTo(WhiteHouseLobby); return 3; } print (string) MSG_GO_CANT_GO, "^"; return 2; Climb,Enter: if (player in self) { ! climb banister if (F_USHAPED_BROKEN) { <>; } else { "You step on the railing, carefully, and see that you can reach the U-shaped pipe from here. You get down safely."; } } else { <>;} ], has static concealed enterable supporter open transparent container ; Object -> Statueof "statue of a small boy" with parse_name [ n ; n = 0; while (NextWord() == 'statue' or 'of' or 'peter' or 'pan' or 'small' or 'boy' or 'child' or 'tunic' or 'flute') n++; return n; ], description [; print "The chalk statue on top of the cylindrical base is that of a little boy wearing a tunic, in a dynamic position, blowing in a sort of small flute. You've seen this sculpture before, though you can't remember where. Is this child the Pied Piper? Peter Pan? Anyway, it's actually not a bad sculpture; it is rather aesthetically pleasing, even though some details look a bit crude. Your best guess is that someone with an artistic inclination cut a slab of the cliffs and worked from a model, to pass time perhaps. The statue "; if (F_STATUE_TURNED == 0) { "looks a bit off-kilter; the child is looking towards the northern door instead of towards the entrance, where you would expect it to look.";} else { "is looking towards the entrance.";} ], before [; Push, Pull, Turn: if (F_STATUE_TURNED == 0) { F_STATUE_TURNED=1; score = score+2; "You turn the statue slightly so the little child faces towards the entrance.";} else { "You feel like the statue is fine like this."; } ], has static concealed; ! have we looked at the cannon yet Global F_CANNON_EXAMINED = 0; Object -> AirCannon "tube-like contraption" with parse_name [ w n ; n = 0; w = NextWord(); while (w) { if (w == 'tube' or 'like' or 'tube-like' or 'contraption' or 'stand' or 'valve' or 'nozzle' or 'opening' or 'hole' || (F_CANNON_EXAMINED && w == 'cannon' or 'air' or 'compressed')) { n++; w=NextWord(); } else {return n;} } return n; ], description [; if (F_CANNON_EXAMINED == 0) { print "This is odd. "; } print "This is a rather wide tube, fixed tight onto a tilted stand. The lower extremity is closed, and some sort of nozzle is attached to it. The other end is open; the diameter is big enough you could put your fist in there. "; print (string) AirCannonTap.description; if (F_CANNON_EXAMINED == 0) { F_CANNON_EXAMINED=1; " You scratch your head and think for a moment. A tilted tube open on one side, with a lever that presumably opens or seals the space between both extremities... Maybe some kind of air cannon?"; } else { " This looks like some kind of air cannon that was hacked together out of spare parts -- for what purpose, though?"; } ], before [; Receive: if (noun == Bikepump) { <>; } if (noun ~= Cricketball) { "This doesn't seem a good fit for the tube's opening."; } Tie: if (second == Bikepump) { <>; } Untie: if (F_BIKE_PUMP_PLUGGED) { <>; } Shoot: <>; ], has static container open transparent concealed; Object -> AirCannonTap "lever in the narrow part of the tube" with name 'narrow' 'handle' 'faucet' 'lever', description "The middle part of the tube narrows, and a lever has been placed here.", before [; Lock, Close: "It seems this lever is already firmly closed."; Unlock, Turn, Open, Turn, Push, Pull: CheckBabelFish(); rtrue; ], has static concealed; ! TODO: shoot cannon / shoot ball ! F_USHAPED_FIXED already declared Object -> Pipebytheroof "U-shaped pipe by the roof" with parse_name [ n ; n = 0; ! horizon = horizontal; i need to write it like that to avoid a compiler bug while (NextWord() == 'angled' or 'u-shaped' or 'ushaped' or 'pipe' or 'hanging' or 'horizon' or 'funnel' or 'extremity') n++; return n; ], description [; print (string) MSG_CONTRAP_USHAPED, " "; if (F_USHAPED_BROKEN == 0) { ; rtrue; } else { print "The pipe broke, "; if (F_USHAPED_FIXED == 0) {"and you probably need to fix it to see what the contraption's mechanism culminates to.";} else { "but you managed to fix it by screwing the screw back on.";} } ], before [; Touch,Rub: print "You "; if (player in Mezza) { "can reach it from here by climbing the railing.";} else { "might be able to reach up to the pipe from the mezzanine.";} Fix: if (player in Mezza) { if (F_USHAPED_FIXED == 0) { if (parent(Flatheadscrewdriver) == player or backpack or Mezza) { if (parent(ScrewUshaped) == player or backpack or Mezza) { remove ScrewUshaped; scope_modified = true; F_USHAPED_FIXED=1; "You climb the banister so you can reach the pipe more easily. You line up the holes for the screw and screw as tight as you go. It should be good enough."; } else { print_ret (string) MSG_YOUD_LIKE_TO_FIX, "."; } } else { print_ret (string) MSG_YOUD_LIKE_TO_FIX, "driver."; } ! screwdriver } else { "You've already fixed the U-shaped pipe; it should be good now."; } } else {<>; } ], has static concealed; Object -> Bucketsandpulley "buckets hanging from a rope" with parse_name [ n ; n = 0; ! also covers "buckets" while (NextWord() == 'bucket' or 'pulley' or 'rope' or 'mechanism' or 'left' or 'right') n++; return n; ], description [; print (string) MSG_CONTRAP_ROPE, " "; if (aDeadRat in self) {"The bucket on the left looks like it's under the platform supporting the weight. It is currently down, while the bucket on the right is up, out of reach.";} else { print "The bucket on the left is currently "; if (Cricketball in self) { "up, and has knocked the weight off its platform, while the other bucket is down.";} else {"at the same height as the bucket on the right, as both are empty.";} } ], before [; Search: if (aDeadRat in self) { if (player in Mezza) { "The highest bucket looks empty, but there seems to be something in the lower bucket."; } else { print_ret "You look in the bucket on the left and", (string) MSG_EW_A_RAT; }} Receive: if (player notin Mezza && aDeadRat in self) { print_ret "You go to insert something in the lower bucket and", (string) MSG_EW_A_RAT; } else {<>;} ! bucket is out of reach Push, Pull, Turn: "This wouldn't change much."; ], has static concealed container open pluralname; Object -> -> aDeadRat "dead rat", with name 'dead' 'rat' 'corpse' 'rodent', description "Ew. No, you don't really want to look at that.", before [; Eat, Burn: "This is the most disgusting suggestion I've heard you make so far."; Take: if (self hasnt moved) { move self to WhiteHouseLobby; give self moved; scope_modified = true; print "You pick up the rat carefully by its tail and drop it on the floor.^^As soon as you do this, the bucket "; if (Cricketball in Bucketsandpulley) { F_BABEL_SOLVED=1; score = score+5; print_ret (string) MSG_END_BABEL; } else { "goes up; the system of buckets ends up stabilizing with both buckets roughly at the same height."; } } else { <>;} Touch: "No way you're touching that thing more than you need to."; default: <>; ], has ; Object -> Weightonplatform "weight on a small platform" with parse_name [ n ; n = 0; while (NextWord() == 'platform' or 'on' or 'weight' or 'l-pieces' or 'bracket' or 'angled' or 'metal' or 'rope' or 'steel' or 'screwed' or 'thin') n++; return n; ], description [; if (F_BABEL_SOLVED == 0) { print "The platform supporting the weight is nothing but a couple of thin metal L-shaped brackets screwed in the wall. It looks like it wouldn't take much to knock the weight out of balance"; print_ret (string) MSG_CONTRAP_WEIGHT; } else { "The weight has been knocked out of the platform and is now hanging in mid-air."; } ], !before [; Take, Touch, Turn, Push, Pull, Cut1, Cut2,Rub: print_ret (The) self, " is out of reach."; !], has static concealed; Array notices static --> "WARNING: we remind you that civilians are not allowed behind the fence. Details of the project, such as schematics or scientific reports, are extremely valuable to the Crown -- and to its enemies. Do not give out the keypad code, and do not write it anywhere, out of precaution.~" "NOTE: the shortages that have plagued us lately will be no more with the arrival of another boat in the next couple of weeks. In the meantime, I expect you strong British boys to put on a brave face. --Major Westwood.~" "WARNING: due to the incident that happened at the pub on the 9th of January, I'm imposing a curfew at 10pm for two weeks. Anyone who is still at the pub at that time will be found and disciplined. --Major Westwood.~" "Who currently has ~Kensington Gardens~, by Brian Moriarty? I was going to re-read it but I couldn't find it in the library. --Steve~" "Mr Chad says: Wot, no sugar?~, with a drawing of a bald man with a large nose poking out of a wall." "... well, some kind of math formula. An... integral sign? E to the x ? Equals f(un). You don't get it." "Help! I'm trapped on a secret island, kept by the British military to work on a deadly project!~" "Tristam Island. Come enjoy its natural beauty, its peace and quiet, its crater, its man-made desolation.~" "Now I am become Death, the destroyer of worlds.~" "Petition to remove all the love songs from the pub's jukebox. All they do is make us more lonesome.~, with six marks next to it."; ! have we looked at the placards yet Global F_PLACARDS_LOOKED = 0; Object -> Placards "placards" with parse_name [ n ; n = 0; ! also covers most plurals, and placard while (NextWord() == 'placar' or 'wall' or 'notice' or 'announcement' or 'drawing' or 'graffiti' or 'board' or 'cork' or 'walls' or 'notes' or 'note') n++; return n; ], description [; print "On both sides of the hall, placards, notices, and handwritten notes are taped to the wall or pinned to notice boards. You read one of them at random, and it says: ~"; if (F_PLACARDS_LOOKED == 0) { F_PLACARDS_LOOKED=1; score=score+1; "A reminder for everyone: I approved that ridiculous Heath Robinson mechanism to open the door to the laboratory to keep morale up while preserving secure access to it. I could very well replace it with a keypad. Do NOT waste more time making it more complex, and get on with your work. --Major Westwood.~"; } else { print_ret (string) (notices-->(random(10)-1)); } ], has static pluralname concealed; Object DoorToAntechamber "door" with found_in WhiteHouseLobby Antechamber, name 'door', description [; if (location == WhiteHouseLobby) { "This tall door looks rather heavy. It is closed."; } else { give self open; "The door is open; a weight is hanging above it."; } ], door_dir (n_to) (s_to), describe [; rtrue; ], before [; Open: if (location == WhiteHouseLobby) { if (F_BABEL_SOLVED == 0) { "You try to push the door open, but it doesn't budge. But it doesn't feel like it's locked; rather, there seems to be something heavy behind it."; } else { <>; } } Push: <>; Pull: if (location == WhiteHouseLobby) { "You need to push this door to open it."; } ], has static door absent; ! will be ~absent in StartAct3 Object ScrewUshaped "big screw" with name 'screw' 'big', description "A rather large screw that was holding a section of the U-shaped pipe together.", before [; Receive: if (noun == Flatheadscrewdriver) { "You check that your flathead screwdriver can fit in that screw; luckily for you, it does."; } Turn: if (self in player && player in Mezza) { <>; } if (parent(Flatheadscrewdriver) == player or location or backpack) { <>; } ], has ; InMansion LibraryMansion "Library" with description [; print_ret (string) MSG_LIBRARY_MUSTY, " Half a dozen shelves are packed with books of all shapes and sizes. The shelf closest to you reads ~SCI-FI~; these books look well-loved, and their spines are crinkled and slightly faded. The lobby is back north."; ], n_to WhiteHouseLobby, before [; Smell: if (noun == 0) {<>;} ], has ; ! Similar to the jukebox code; this saves 74 bytes over Barrett's structure {%~Colonial Survey~ by Murray Leinster| etc Array booktitles static --> "Colonial Survey" "The Stars My Destination" "Foundation" "Starship Troopers" "Childhood's End" "Shadow on the Hearth" "Last and First Men" "Non-Stop"; Array bookauthors static --> "Murray Leinster" "Alfred Bester" "Isaac Asimov" "Robert Heinlein" "Arthur C. Clarke" "Judith Merrill" "Olaf Stapledon" "Brian Aldiss"; Object -> Shelvesfullofscifibooks "shelves full of books" with parse_name [ n ; n = 0; while (NextWord() == 'shelf' or 'shelves' or 'science' or 'fiction' or 'book' or 'books') n++; return n; ], description [ _i ; print "You pick a book at random: ~"; _i = random(8)-1; print (string) booktitles-->(_i); print "~, by "; print (string) bookauthors-->(_i); print ". The "; print (string) random("lower right corner", "upper right corner", "cover", "spine"); print " is "; print (string) random("absolutely destroyed", "very faded", "still in good shape", "pretty worn"); ". You flip through it distractedly, then put it back."; ], before [; Take, Search: <>; Smell: print_ret (string) MSG_LIBRARY_MUSTY; Receive: if (noun == SFbookwiththecode) { remove SFbookwiththecode; scope_modified = true; print_ret "You put the book back where it belongs, in this small library of ", (string) MSG_SCIFI_BOOK, "s. Somehow, it feels right."; } ], has static concealed pluralname; [ MrChad n; print_ret "You look under ", (the) n,", and sure enough, there is", (string) MSG_DRAWING_MR_CHAD; ]; InMansion Cafeteria "Cafeteria" with description [; print "This is a rather small cafeteria, with"; print (string) MSG_FOUR_TABLES_CAFET; " The whole room feels deserted and only slightly lit. The door to the kitchen is closed. You can go back to the lobby, to the west."; ], s_to "This would be the door to the kitchen, but it is locked.", w_to WhiteHouseLobby, out_to WhiteHouseLobby, has ; Object -> TablesBenchesCafet "benches and tables" with name 'bench' 'benche' 'table' 'tables', description [; print_ret "There are", (string) MSG_FOUR_TABLES_CAFET; ], before [; LookUnder: MrChad(self); rtrue; Enter: print_ret "You sit on a bench for a few minutes, to think and try", (string) MSG_FIGURE_OUT_NEXT_MOVE; ], has static concealed; Object -> DoorKitchen "door to the kitchen" with name 'door' 'to' 'the' 'kitchen', description "The door to the kitchen is locked.", describe [; rtrue; ], before [; Unlock, TryUnlock: print_ret (string) MSG_NO_IDEA_WHERE_KEY; ], has static door openable lockable locked; ![ MoveInQuarters ; !]; InMansion Quarters "Quarters" with description "This is a rather short hallway, lit by a single light bulb, with four different doors. The furthest one, at the very back, is a door saying ~OFFICERS ONLY~. On the north wall is a yellow door with the name of two PhDs on it; on the other wall, a white door has the name of two other people on it, while the last one has a sign saying ~GUARD~ on it. The mezzanine is west.", !w_to WhiteHouseLobby, ! on the mezzanine though w_to Mezza, !n_to MoveInQuarters, ! check if the yellowroom door is open n_to YellowDoorQuarters, !s_to MoveInQuarters, ! check if the white room is open s_to WhiteDoorQuarters, in_to "You'll have to be more precise, as there are multiple doors to choose here.", e_to OfficersDoorQuarters, has ; Object -> OfficersDoorQuarters "door to the officers quarters" with description "The door at the end of the hallway is locked, and says ~OFFICERS ONLY~.", name 'office' 'door' 'to' 'quarters', ! officer, officers (need to write it like that to avoid a bug) described "", before [; Enter,Pick,Unlock, TryUnlock: print_ret (string) MSG_NO_IDEA_WHERE_KEY; ], has static door openable lockable locked; Object -> GuardDoorQuarters "door to guard room" with name 'guard' 'door' 'room' 'to', description "This door has a sign saying ~GUARD~ on it. It is locked, and it would require a key to be unlocked.", described "", before [; Enter,Pick,Unlock, TryUnlock: print_ret (string) MSG_NO_IDEA_WHERE_KEY; ], has static door openable lockable locked; Constant MSG_SCREWDRIVER_UNLOCKS_DOOR "You take your flathead screwdriver and insert it in the lock, then turn. The door unlocks."; Global F_QUARTERS_UNLOCKED = 0; Object -> YellowDoorQuarters "yellow door" with name 'yellow' 'door' 'room' 'lock', description [; print "On this yellow door, the names are Dr Jerome Thorpe and ~Doc~ Walt Horvak. "; print_ret (string) MSG_PRIVACY_LOCK; ], found_in Quarters YellowRoom, door_dir (n_to) (s_to), with_key Flatheadscrewdriver, before [; TryUnlock, Pick: print_ret (string) MSG_PRIVACY_LOCK; ], after [; Unlock: if (F_QUARTERS_UNLOCKED == 0) { F_QUARTERS_UNLOCKED=1; score = score + 5; } print_ret (string) MSG_SCREWDRIVER_UNLOCKS_DOOR; ], describe [; if (location == YellowRoom) {rtrue;}], has static door openable lockable locked; Object -> WhiteDoorQuarters "white door" with name 'white' 'door' 'room' 'lock', description [; print "On this white door, the names are Mick Antrim and Marv Siegel. "; print_ret (string) MSG_PRIVACY_LOCK; ], found_in Quarters WhiteRoom, door_dir (s_to) (n_to), with_key Flatheadscrewdriver, before [; TryUnlock, Pick: print_ret (string) MSG_PRIVACY_LOCK; ], after [; Unlock: if (F_QUARTERS_UNLOCKED == 0) { F_QUARTERS_UNLOCKED=1; score = score + 5; } print_ret (string) MSG_SCREWDRIVER_UNLOCKS_DOOR; ], describe [; if (location == WhiteRoom) {rtrue;}], has static door openable lockable locked; ! State of the yellow room door !Global PARSED_YELLOW_DOOR = 0; !Global PARSED_WHITE_DOOR = 0; !Global PARSED_GUARD_DOOR = 0; !Global PARSED_YELLOW_DOOR = 0; !Global F_YELLOW_ROOM_OPEN = 0; !Global F_YELLOW_ROOM_UNLOCKED = 0; ! State of the white room door !Global F_YELLOW_ROOM_OPEN = 0; !Global F_WHITE_ROOM_UNLOCKED = 0; ! TODO: 4 doors to distinguish, use the same parsing as OneBigDoor (there is no key, only screwdrivers for 2 of them) !Object Doortoquarters "Door to quarters" Quarters ! with parse_name [; ! ], ! description "Door to quarters", ! has ; Object Bedbunks "bunk beds" with name 'Bed' 'bunks' 'beds' 'bunk', description [; print "Two bed bunks are here; they have"; if (location == YellowRoom) {print "n't"; } " been made."; ], found_in YellowRoom WhiteRoom, before [; Enter, SleepOn: SleepSub(); rtrue; ], has static concealed; ! TODO: make beds ! TODO: you have more objects than you thought, add more scenery? InMansion YellowRoom "Yellow room" with description [; print_ret "The room has been emptied hurriedly, it seems; the beds in the bunk haven't been made, and there's a chest basically in the middle of the room. ", (string) MSG_DESC_DESK, " You can go out by going south."; ], s_to YellowDoorQuarters, out_to YellowDoorQuarters, before [; Sleep: <>; ], has ; Object -> DeskYellowRoom "desk" with name 'desk' 'drawer' 'wooden', description [; print_ret (string) MSG_DESC_DESK; ], before [; Close: "You don't know if you should worry about this sort of details right now."; ], has static concealed; Object -> YellowTrunk "chest" with name 'chest' 'wood' 'deep' 'trunk', description "A rather deep chest, made -- locally, it would seem -- of solid wood.", has static concealed openable container; Object -> -> Cricketball "cricket ball" with name 'cricket' 'red' 'old' 'ball', description "An old cricket ball, rough under your fingers; one side seems more polished than the other one.", before [; ThrowAt: if (second == Bucketsandpulley or Weightonplatform or Pipebytheroof) { ! after all, if it wasn't too complicated, it could be a solution, with a 1/10 chance... ! knocking the weight down with a cricket ball is a good idea though if (second == Bucketsandpulley or Weightonplatform) { move self to WhiteHouseLobby; } else { move self to Mezza; } scope_modified = true; print "You aim at the "; if (second == Bucketsandpulley) { print "bucket"; } if (second == Weightonplatform) { print "weight"; } if (second == Pipebytheroof) { print "funnel"; } print ", and try to give the cricket ball a nice trajectory, but it veers off and you miss the target."; if (second == Pipebytheroof) { " The ball lands on the mezzanine."; } else { @new_line; @rtrue; } } Insert: if (second == Bucketsandpulley or Weightonplatform or Pipebytheroof) { <>;} Rub: "You rub the cricket ball slightly, hoping to give it more swing, but you don't go as far as putting saliva on it. The red stain on your hands eventually comes off."; Smell: "The cricket ball smells like old leather."; ], after [; Insert: if (second == AirCannon) { "You put the cricket ball in the hole. It fits perfectly, as if the hole had been made for it."; } ], has; InMansion WhiteRoom "White room" with description "The room is rather tidy, with both beds in the bunks made. There is a chest by the foot of the bed. You can go out by going north.", n_to WhiteDoorQuarters, out_to WhiteDoorQuarters, before [; Sleep: <>; ], has ; Object -> WhiteTrunk "chest" with name 'chest' 'wood' 'deep' 'trunk', description "A rather deep chest, made -- locally, it would seem -- of solid wood.", has static concealed openable container; ! for points awarding Global F_BIKE_PUMP_PLUGGED_FIRSTTIME = 0; Object -> -> Bikepump "bike pump" with name 'bike' 'pump' 'bicycle' 'handle', description "This bike pump is made of metal, and has rusted over the years. Strange; you don't recall seeing any bikes on the island.", before [; Tie: if (player in Mezza) { <>; } ! out of reach if (second == AirCannon or 0) { if (F_BIKE_PUMP_PLUGGED) { "The bike pump is already plugged to the nozzle of the air cannon.";} else { F_BIKE_PUMP_PLUGGED=1; move Bikepump to WhiteHouseLobby; scope_modified = true; if (F_BIKE_PUMP_PLUGGED_FIRSTTIME == 0) { F_BIKE_PUMP_PLUGGED_FIRSTTIME=1; score = score+2; } "You plug the bike pump on the nozzle on the slanted tube; it fits perfectly."; } } else { "You can't seem to plug the bike pump here."; } Untie: if (player in Mezza) { <>; } ! out of reach if (F_BIKE_PUMP_PLUGGED) { F_BIKE_PUMP_PLUGGED = 0; print_ret (string) MSG_YOU_UNPLUG_PUMP; } Push, Pump: if (F_BIKE_PUMP_PLUGGED == 0) { "You push the handle of the bike pump up and down, and you hear some air coming out at the other side.";} else { if (player in Mezza) { <>; } ! out of reach if (F_BIKE_PUMP_PUMPED) {"You seem to have filled the cannon with compressed air; it is very hard for you to push any more air in.";} else { F_BIKE_PUMP_PUMPED=1; "You pump air into the tube until the pressure is too great for you to keep going."; } } ], after [; Take: if (F_BIKE_PUMP_PLUGGED) {F_BIKE_PUMP_PLUGGED = 0;print_ret (string) MSG_YOU_UNPLUG_PUMP;} ], has ; InMansion Antechamber "Antechamber" with description [; print "This small room seems to have for only purpose to serve as a waiting room "; if (self hasnt visited) { print "before entering the next door, which", (string) MSG_ELEVATOR_DESC, " Right -- an elevator!^^You step away from the door to the lobby, as a large weight is hanging from the ceiling right above it", (string) MSG_WEIGHT_WAS_BLOCKING; } else { print "for the elevator.";} " At this point, there is only one sensible thing to do..."; ], s_to "This elevator is too important. You feel like you're getting closer to knowing the secrets of the island...", in_to Insidetheelevator, has ; Object -> WeightAboveDoor "weight hanging above the door" with name 'weight' 'hanging' 'rope', description [; print_ret "A weight is hanging above the door", (string) MSG_WEIGHT_WAS_BLOCKING; ], before [; Take, Touch, Pull, Push, Cut1, Cut2,Rub: "You do not particularly wish to stand under that weight. You never know what might happen."; ], has static concealed; Object -> Elevator "elevator" with name 'elevator' 'door' 'button', description [; print_ret "The elevator's door", (string) MSG_ELEVATOR_DESC; ], before [; Enter: if (self has open) {print "You enter the elevator.^"; <>;} else { PrintMsg(MSG_ENTER_NOT_OPEN); rtrue; } Push: <>; ], after [; Open: "You push the button, and the elevator opens."; ], ! take the elevator = enter it has openable static concealed enterable; Constant MSG_HALLWAY_ARTIF_LIGHT " a long hallway lit only by artificial light. "; InMansion Insidetheelevator "Inside the elevator" ! TODO: how do we know we need to go down? is there a small sign in the break room that says "down to the salt mines"? with description [ i; ! ! testing code !for(i=0:ii) ~= 0) { give (floating_objects-->i) ~absent; }} print "This elevator could probably fit two people, but not more. Outside the elevator, you can see"; if (F_ELEVATOR_DOWN) {print (string) MSG_HALLWAY_ARTIF_LIGHT;} else {print " the antechamber. "; } ; rtrue; ], s_to [; <>; ], in_to [; "You already are in the elevator."; ], out_to [; if (F_ELEVATOR_DOWN) { return LobbyReception; } else { return Antechamber; } ] , d_to [; if (F_ELEVATOR_DOWN == 0) { <>; } ], u_to [; if (F_ELEVATOR_DOWN) { <>; } ], has ; Object -> Button "elevator button" with name 'button' 'elevator', description "There is only one button in this elevator.", before [; Push: if (F_ELEVATOR_DOWN) {"You could probably go back up, but you feel like there is still more to explore down here.";} else {F_ELEVATOR_DOWN=1; StartAct4(); rtrue;} Enter: print_ret (string) MSG_ENTER_ALREADY; ! enter elevator Open: print_ret (string) MSG_OPEN_ALREADY; ! open elevator ], has static concealed; !======================================================================= ! Act 4 - Lab Constant MSG_BOX_ON_DESK "The most notable thing on the desk is a filing box filled with papers."; Constant MSG_WIDE_WORKBENCH "There is a wide workbench here, with a small sink and a few empty beakers."; Constant MSG_LOCKERS_DESC "A few lockers are against the south wall; they are all open, except one, which has a hanging combination lock on it."; Constant MSG_DOOR_MAJOR_PLATE "This is the door to Major Westwood's office, as the plate indicates. "; Constant MSG_TOO_SHORT "You're too short to reach this."; Constant MSG_TRANSMITTERS "One large radio transmitter is in this room. On a desk, you can see a microphone with a small button on its stand"; Constant MSG_NO_NOISE_HEADPHONES "here doesn't seem to be any noise coming in the headphones. Maybe the radio isn't working properly?"; Constant MSG_MESS_CABLES "a mess of cables and wires, and a microphone. This must have been the comms guy's locker."; Constant MSG_ELEVATOR_DESC " is made of glass. There is a button on the door frame."; Constant MSG_NOTHING_DRAWN_UNDER "You look under there, but you don't see anything written or drawn."; Constant MSG_NOTHING_BUT_STATIC " -- nothing but static."; [ StartAct4 i ; F_ACT4_STARTED=1; score = score + 5; ! we're never going back up; might as well save some parsing and make all found_in objects since act 1 till here absent for (i=0: ii) absent; print_ret "You push the button with some trepidation; the doors close, and the elevator starts its descent.^^You turn and turn the facts in your head, trying to figure out what this place is. An elevator going deep underground. A mansion with a floor for military personnel, and another one for civilians, but under military supervision. A door with a complicated mechanism, with one part moving another in a big chain reaction. A library full of ", (string) MSG_SCIFI_BOOK, "s, and barely anything else.^^The elevator is still going deeper.^^Who were the civilians living here, under military supervision, but clearly not jailed? Were they working for the military? On what kind of project? This is getting a bit spooky.^^The elevator finally stops. After what seems like an eternity, it opens, revealing", (string) MSG_HALLWAY_ARTIF_LIGHT, "But at this precise moment, it all comes together, and you understand everything. The shock makes you unable to move for a few minutes, as all the pieces come together perfectly in your head. You know the secret of this island."; ]; [ ReadLetter ; if (location == Conferenceroom) { print "You search the pile of papers, and the one that catches your attention is a"; } if (location == Bossroom) { print "In the litter bin is a crumpled";} print " letter written by Doctor Alexander Grant to the Major Westwood:"; print "^^Major,^ I urgently request that you and your superiors reconsider the test scheduled for the 15th of February 1962. Our estimates for the type and size of bomb we are working with are several hundred kilotons above what we would consider safe, considering the distance between our island and Tristam Island.^ Our worries are not about the damage the bomb would cause to our island and its structures, but more about the radioactive fallout that has a high chance of blowing our way. Should this happen, our radiation exposure would be high, and remain high as the ashes deposit on our island. Remaining on the island would not be an option; we calculated with our resident doctor that the risk of cancer would increase one hundredfold.^ Please, we urge you to reconsider the size of the explosion, if you want the experimentations here to continue; a blast this size would render our island unlivable, and would require us to evacuate it.^ Sincerely,^ Doctor Alexander Grant^^"; print "Wow. Is this what happened on this island? Is this why everyone left? Did they go ahead with the explosion, and it exposed everybody to so much radiation that the island was uninhabitable?"; if (location == Bossroom) { print " After all, you found this letter in the litter bin -- it doesn't sound like the Major took the warning very seriously."; } print " Given the state of the village, "; if (F_EXAMINED_COMIC) { print "the date on the comic book, "; } if (F_EXAMINED_SONGLIST) { print "the songs in the jukebox, "; } if (F_EXAMINED_SIGNUP) { print "the fact people stopped signing up to take care of the garden after the 18th of February, ";} print "it would make sense to guess that this island was indeed abandoned in February 1962...^^"; print "Either way, you hadn't considered how the fallout might affect this island -- and with it, you. You ate a fish that probably was pretty close to Tristam Island, "; if (F_FOUNTAIN_DRANK) { print "drank the water from the fountain, "; } print "touched a lot of objects... You need to "; if (Masterkeyring hasnt moved) {print "find the key to the communications room, and ";} "quickly get out of this island."; ]; Object CommsRoomDoor "door" with parse_name [; return ParseDoorName(self); ], ! can't put "concealed" on the door otherwise it's a secret door; so in order for it to not show in the list of objects, we need to give it an empty describe routine describe [; rtrue; ], description [; DescribeADoor(self); rtrue; ], found_in LobbyReception CommsRoom, ! this is to translate the "go in" where "in" is a door into a "go location" door_dir (in_to) (out_to), with_key Masterkeyring, has static door lockable locked openable absent; ! will be ~absent in StartAct4 Object BossRoomDoor "door" with parse_name [; return ParseDoorName(self); ], ! can't put "concealed" on the door otherwise it's a secret door; so in order for it to not show in the list of objects, we need to give it an empty describe routine describe [; rtrue; ], description [; DescribeADoor(self); rtrue; ], found_in Bossroom Infrontofthebosssroomdoor, ! this is to translate the "go in" where "in" is a door into a "go location" door_dir (out_to) (in_to), with_key Masterkeyring, has static door lockable locked openable absent; ! will be ~absent in StartAct4 Class InsideLab with before [; Jump: <>; ], has light; Constant MSG_RAISE_YOUR_ARM "You raise your arm, and "; ! Have we pushed the tile out of the way Global F_PUSHED_TILE = 0; ! TODO: should we have "mr chad graffiti" recognized here? Object NeonLights "fluorescent lamp" with description [; if (location == Bossroom) { "There is a big hole in the ceiling, now."; } ! if we went in and we're back here, we moved the Masterkeyring if (location == Infrontofthebosssroomdoor) { print "You look up towards the blinking lamp, and notice something funny. Someone drew", (string) MSG_DRAWING_MR_CHAD; if (F_PUSHED_TILE==0) { " Right next to the picture, one of the tiles of the false ceiling is a bit crooked, which makes a small hole in the ceiling."; } else {" You have pushed one of the ceiling tiles out of the way to enter the Major's office.";} } else { "You are standing directly under a fluorescent lamp; you can't really look at it directly without your eyes hurting. But looking beside it, at the tiles of the false ceiling, makes it better."; } ], parse_name [ w n ; n = 0; w = NextWord(); while (w) { if (w == 'neon' or 'neons' or 'lamp' or 'fluorescent' or 'lamp' or 'lamps' or 'light' or 'lights' or 'false' or 'ceiling' or 'suspended' or 'dummy' or 'tile' or 'tiles' || (location == Infrontofthebosssroomdoor && w=='hole' or 'missing' or 'blinking')) { n++; w=NextWord(); } else {return n;} } return n; ], found_in [; if (location ofclass InsideLab) {rtrue;} else {rfalse; } ], before [; Touch: if (player in MeetingChair) { if (Organicchemistrytextbook in MeetingChair || FilingCabinet in MeetingChair) { print_ret (string) MSG_RAISE_YOUR_ARM, "you manage to touch the ceiling quite easily."; } else { print "You stretch and extend yourself as much as you can, but you're still short by "; if (Otherthinnertextbook in MeetingChair) { "less than an inch. Frustrating!"; } else { "a couple of inches."; } } } else { print_ret (string) MSG_TOO_SHORT; } Take, Pull,Push: if (location == Infrontofthebosssroomdoor) { if (player in MeetingChair && (Organicchemistrytextbook in MeetingChair || FilingCabinet in MeetingChair)) { if (F_PUSHED_TILE==0) { F_PUSHED_TILE=1; print_ret (string) MSG_RAISE_YOUR_ARM, "put your hand against the ceiling tile; you manage to shove it out of the way."; } else { "You have already pushed a tile out, creating a bigger hole."; } } else { <>; } } else { "You don't really see why you would do this here."; } Climb, Enter: if (location == Infrontofthebosssroomdoor) { if (F_PUSHED_TILE == 0) { "The hole doesn't seem big enough for you to fit; you might need to push a tile first."; } else { if (player in MeetingChair && (Organicchemistrytextbook in MeetingChair || FilingCabinet in MeetingChair)) { if (Bossroom has visited) { "It'd be less effort to go through the door."; } else { score = score+5; print "You look up. The space looks quite tight, but your fingers can reach the metal supports of the suspended ceiling. You should be able to do it...^^You take a deep breath, and jump! Then using all your strength, you pull yourself up into the crawl space above the tiles, grabbing the ceiling's supports with the tip of your fingers. Your arms are burning, your fingers hurt, and you are momentarily exhausted, but you made it!^^You crawl a few feet in the space above the false ceiling, then remove one of the tiles: you are indeed above the Major's office! You crawl into the opening, then drop down awkwardly.^"; PlayerTo(Bossroom); @rtrue; } } else { "You can't quite reach the ceiling."; } } } else { <>; } SwitchOn, SwitchOff: "You have no idea how you could turn the fluorescent lamps on or off; there doesn't seem to be any light switch around here."; ], has static concealed absent; ! activated at the end of act 3 or 4 InsideLab LobbyReception "Lobby" with description "You are by an elevator, north of you. This looks like an underground complex, with a long hallway going southwards, dimly lit by pale fluorescent lights fixed to a false ceiling, leading to various rooms to explore, none of which have doors. However, to the west, you can see a door, with a plate that reads ~COMMS ROOM~ -- at last, a way to use the radio and send an SOS message! There is a small desk here, facing the elevator; above the desk is a poster of the explosion of an atom bomb.", n_to Insidetheelevator, s_to Hallway, w_to CommsRoomDoor, !Commsroom, in_to CommsRoomDoor, !commsroom has ; ! x hallway : you decide to go take a look Object -> LabLobbyDesk "desk" with name 'desk' 'secretary' 'checkpoint', description [; print "If this small and tidy desk wasn't directly facing the elevator, you would have guessed it was used by a secretary; but really, it was probably a soldier who sat here and monitored access."; if (FilingCabinet in self) { print_ret (string) MSG_BOX_ON_DESK;} ], before [; Search: if (FilingCabinet in self) { print_ret (string) MSG_BOX_ON_DESK;} ], has static concealed supporter; Object -> -> FilingCabinet "filing box" with parse_name [ n ; n = 0; while (NextWord() == 'box' or 'cardboard' or 'dividers' or 'filing' or 'file' or 'paper' or 'papers' or 'files' or 'packed' or 'full' or 'densely' or 'dense') n++; return n; ], description "The filing box is nothing but a cardboard box that's filled to the brim with papers; there are 26 dividers, one for each letter of the alphabet.", daemon [; if (parent(self) ~= player) { StopDaemon(self); rfalse;} else { if (random(5) == 1) {print_ret (string) random("^You readjust the filing box to get a better grip.", "^You try to shift the weight of the filing box to the other arm, but it's just heavy, no matter what.", "^You take a deep breath; your arms are starting to burn.");} } ], before [; Search: print "You "; if (self hasnt open) { give self open; print "open the filing box and ";} print "search the files and take one at random. It consists in multiple pages stapled together; the front page shows the picture of a "; print (string) random("young", "bearded", "arrogant", "moustachioed", "bespectacled", "blond", "square-jawed", "redhead"); print " man named "; print (string) random("Doctor Alexander Grant, expert in nuclear physics", "Doctor Jerome Thorpe, a specialist in nuclear chemistry", "Walt Horvak, listed as a medical doctor", "Mick Antrim, apparently a nuclear engineer", "Marv Siegel, from the US Defense Department, who specialises in sensor technology", "Douglas Williamson, a sapper from the Royal Engineers", "Private Tom Jolley", "Private John Atkinson", "Corporal Steven Saunders", "Private Tim Gorecki", "Corporal Peter Dahl"); print_ret ". You put the file back in the tightly packed box."; Insert: if (second == backpack) { if (keep_silent == 0) {"This heavy box would not fit in your backpack.";} rtrue;} Receive: "The box is packed so densely, you wouldn't be able to fit anything in it."; ThrowAt: "You can barely lift this box, let alone throw it."; Climb: if (self in MeetingChair) { <>; } else { if (parent(self) == player or LabLobbyDesk) {"You should probably put it on the floor first.";} else {"You climb on the cardboard box; it is so densely packed that it supports your weight. You get off the box."; }} ], after [; Take: StartDaemon(self); "The box is very heavy, since it's packed so densely. You pick it up with a grunt."; ], has concealed openable open enterable supporter; ! have we looked at that poster? Global F_SAW_ATOMIC_POSTER = 0; Object -> Atomicbombposter "atom bomb poster" with parse_name [ n ; n = 0; while (NextWord() == 'poster' or 'picture' or 'atom' or 'nuclear' or 'atomic' or 'bomb' or 'explosion' or 'bikini' or 'fat' or 'boy' or 'hiroshima' or 'nagasaki') n++; return n; ], description [; if (F_SAW_ATOMIC_POSTER == 0) { F_SAW_ATOMIC_POSTER=1; score = score + 5; } print "This is it. The smoking gun. The missing part of the puzzle, that makes everything else make sense. The people on this island were working on nuclear testing. "; if (F_SAW_TRISTAM_PRECISELY) {"That explains the poor state Tristam Island is in: it was their Guinea pig, where they detonated the bomb, so they could destroy it and study the effects of the explosion.";} else { ! in theory at this point we can't be here without WE_SAW_TRISTAM on, since we went by the BaseOfTower "If they did set off a nuclear bomb, it was probably on the neighbouring island, which they could then study."; } ], has concealed static; InsideLab Hallway "Hallway" with description "You are standing in a wide hallway, under the bright white light of a fluorescent lamp. Going north takes you back towards the lobby and the elevator; the hallway turns here and continues east, or you can enter what looks like a lab to the south.", n_to LobbyReception, s_to Lab, e_to Hallway2, has ; ! enter lab : you go see blabla ! x lobby/desk : you go see blabla InsideLab Lab "Lab" with description [; print "This is a rather dark lab, lit only by the lamp in the hallway; you can't locate a light switch, but there is enough light to see. "; print (string) MSG_WIDE_WORKBENCH; print " There are more beakers on the shelves"; if (geiger hasnt moved) { print ", as well as a small device with a dial";} print_ret ". You can go back to the hallway by going north, or go east to explore another part of the lab connected to this one."; ], n_to Hallway, e_to Lab2, has ; Object -> LabWorkbench "workbench" with name 'workbench' 'worktop' 'sink', description [; print (string) MSG_WIDE_WORKBENCH; if (PrintContents(" There is ", self)) { print " on it.";} @new_line; @rtrue; ], before [; Climb,Enter: PrintMsg(MSG_CUT_NO_USE); rtrue; ! you would achieve nothing ], has static concealed supporter; Object -> -> beakers "beakers" with name 'beaker' 'erlenmeyer' 'empty' 'clean', ! covers "beakers" description "Some beakers, that have been cleaned, then left on the shelves to collect dust.", before [; Attack: print_ret (string) MSG_THROW_ANIMATE; Receive: "You're not really here to play scientist."; Take: "You don't see how these would be useful right now."; ], has concealed; ! https://soeks-usa.com/blogs/radiation/blog-what-is-cpm-in-radiation Global F_LOOKED_GEIGER = 0; Object -> geiger "Geiger counter" with parse_name [ n ; n = 0; while (NextWord() == 'small' or 'device' or 'radiation' or 'detector' or 'geiger' or 'tube' or 'counter' or 'dial' or 'needle' or 'reading') n++; return n; ], description [; if (F_LOOKED_GEIGER ==0 ) {F_LOOKED_GEIGER=1; print "You are guessing this is a Geiger-Muller counter, that counts the radiation events per minute and displays it on the dial. "; } if (self has on) { print "The Geiger counter is currently on; the needle on the dial is around "; if (location == Hallway3 or Infrontofthebosssroomdoor or Storagelockers) {print (string) random("2300", "2500", "2800"); } else { print (string) random("900","1000","1200");} print " counts per minute.^"; return 2; ! no need to display the state } else { return 0; } ! need to display the state ], before [; Listen: if (self has on) { print "You listen to the Geiger counter; it is clicking a "; if (location == Hallway3 or Infrontofthebosssroomdoor or Storagelockers) { "lot."; } else {"bit.";} } else { <>; } ], has switchable concealed; InsideLab Lab2 "Lab" with description [; print "This looks like an area where some serious thinking was happening. A few comfortable-looking armchairs and a sofa are all facing a blackboard, which is covered is symbols and esoteric drawings; not too far from the blackboard, a coffee maker is resting on a filing cabinet"; if (Organicchemistrytextbook hasnt moved || Otherthinnertextbook hasnt moved) { print ". There "; if (Organicchemistrytextbook hasnt moved && Otherthinnertextbook hasnt moved) { print "are only two books"; } else { print "is only one book"; } print " left on the shelves, "; if (Otherthinnertextbook hasnt moved) { print "a rather thick one"; if (Organicchemistrytextbook hasnt moved) { print ", and ";}} if (Organicchemistrytextbook hasnt moved) { print "an absolutely massive one"; } } print_ret ". You can go to the hallway by going north, or west to another part of the lab connected to this room."; ], n_to Hallway2, w_to Lab, has ; Object -> Blackboard "blackboard", with parse_name [ n ; n = 0; ! covers drawings and symbols while (NextWord() == 'board' or 'chalk' or 'chalkboard' or 'blackboard' or 'equation' or 'chain' or 'reaction' or 'chad' or 'mr' or 'caption' or 'drawing' or 'symbol' or 'diagram') n++; return n; ], description [; print_ret "The blackboard on the wall is covered in diagrams, equations, and other things you know nothing about -- although you're pretty sure one of the diagrams represents a chain reaction. In the top right corner, someone drew", (string) MSG_DRAWING_MR_CHAD; ], has static concealed; Object -> ThinkingChairs "seats" with name 'armchair' 'chairs' 'sofa' 'couch', description "These armchairs look pretty comfortable, as does the sofa. The scientists here probably spent hours in them, reading, having lively scientific arguments, or staring at the suspended ceiling tiles until an idea comes.", before [; Enter: print_ret "You lounge on the sofa for a couple of minutes and stare at the tiles of the false ceiling, trying", (string) MSG_FIGURE_OUT_NEXT_MOVE, " Then you get bored, and get up."; LookUnder: print_ret (string) MSG_NOTHING_DRAWN_UNDER; Take, Push, Pull, Turn: "These are much too heavy to move."; ], has static concealed supporter pluralname; Object -> Cabinet "filing cabinet" with name 'filing' 'cabinet' 'drawer', ! covers "drawers" description "The filing cabinet has been emptied, but nobody bothered taking the coffee maker with them.", has static concealed supporter; Object -> -> CoffeeMaker "coffee maker" with name 'coffee' 'maker' 'pot', description [; <>; ], before [; Take: "This doesn't seem like it'd be useful right now."; Search, Drink, SwitchOn: "There is no coffee left in the coffee maker.";], has concealed switchable; ! TODO: make coffee [ CountPageBook n; print_ret "There are ", n, " pages in this book. Wow."; ]; [ StandOnBook o; if (o in MeetingChair) {<>; } else { print_ret "You stand on the book; you are now", (string) o.size, "taller. You get off the book."; } ]; Constant MSG_OPEN_BOOK_RANDOM_PAGE "You open the book at a random page; "; Constant MSG_CLOSE_BOOK_V_QUICKLY ", make you close the book very quickly."; ! http://oasys2.confex.com/acs/232nm/techprogram/P1008027.HTM for the historical reference Object -> Organicchemistrytextbook "organic chemistry textbook" with parse_name [ n ; n = 0; while (NextWord() == 'organic' or 'chemistry' or 'massive' or 'huge' or 'books' or 'book' or 'volume' or 'textbook' or 'tome' or 'heavy' or 'pages') n++; return n; ], size " a couple of inches ", description [; print_ret "This is ~Organic Chemistry 1~, by Louis and Mary Fieser -- and it's an absolute beast of a book,", (string) self.size, "thick, and weighing several pounds. You wonder if volume 2 is just as big."; ], before [; Count: CountPageBook(1125); rtrue; ! count pages, and just that ideally Search, Open: print_ret (string) MSG_OPEN_BOOK_RANDOM_PAGE, "drawings of monstruous structures, full of hexagons and tentacles, with hyphen-riddled, unpronounceable names", (string) MSG_CLOSE_BOOK_V_QUICKLY; Climb,Enter: StandOnBook(self); rtrue; ], after [; Take: "You take the organic chemistry book. Wow, it's even heavier than you thought."; ], has openable concealed; ! https://www.amazon.ca/Theoretical-Nuclear-Physics-John-Blatt/dp/0486668274/ Object -> Otherthinnertextbook "nuclear physics textbook" with parse_name [ n ; n = 0; while (NextWord() == 'nuclear' or 'physics' or 'thick' or 'big' or 'book' or 'books' or 'volume' or 'textbook' or 'tome' or 'heavy' or 'pages') n++; return n; ], size " over one inch ", description [; print_ret "This is ~Theoretical Nuclear Physics~, by John Blatt and Victor Weisskopf -- a pretty thick book,", (string) self.size, "thick, and weighing a couple of pounds.";], before [; Count: CountPageBook(896); rtrue; ! count pages, and just that ideally Search,Open: print_ret (string) MSG_OPEN_BOOK_RANDOM_PAGE, "terrible equations, and explanations full of ~quantum~ this and ~wave function~ that", (string) MSG_CLOSE_BOOK_V_QUICKLY; Climb,Enter: StandOnBook(self); rtrue; ], has openable concealed; InsideLab Hallway2 "Hallway" with description "This seems to be like a central part of this underground complex. Paths go west along the hallway, east towards some lockers, south to what looks like a research lab, and north to a sort of meeting room.", n_to Conferenceroom, s_to Lab2, e_to Storagelockers, w_to Hallway, has ; InsideLab Conferenceroom "Meeting room" with description "This looks like a meeting room, with several tables put together at the centre of the room, and a number of chairs around. There is a pile of papers on the table. You can go back to a hallway to the south or the east.", s_to Hallway2, e_to Hallway3, has ; Object -> Table "tables and chairs" with name 'table' 'tables' 'chair' 'chairs', description "There are four wooden tables together put together at the centre of the room, and about a dozen chairs around them.", before [; Count: <>; LookUnder: print_ret (string) MSG_NOTHING_DRAWN_UNDER; Take: if (parent(MeetingChair) == nothing) { <>; } else { "You don't need to take more chairs out."; } !LookUnder: <>; rtrue; ! redirect open and search to the MeetingChair Enter: "Nobody will sit with you at this meeting."; Push, Pull: print "The tables are fine like that, "; if (parent(MeetingChair) == nothing) { print "but maybe you could take"; } else { print "and you already took"; } " a chair."; ], has static supporter concealed pluralname; Object -> -> PileOfPapers "pile of papers" with name 'pile' 'papers' 'paper' 'letter', description "A messy pile of papers is at a corner of one of the tables.", before [; Take: "You don't know if they'd be all that useful to you."; Search: ReadLetter(); rtrue; ], has concealed; Object MeetingChair "sturdy chair" with name 'chair' 'meeting' 'sturdy', description [; print "A chair you took from the meeting room. It looks sturdy."; if (PrintContents(" There is ", self)) { print " on it.";} @new_line; @rtrue; ], !before [ o; Take: move MeetingChair to player; scope_modified = true; "Taken."; before [; !while(child(player)) { ! if (o ~= backpack) { ! if (backpack in player) { move o to backpack; } ! else { move o to location; } ! } else { break; } !} !print "You put everything "; !if (backpack in player) { print "in your backpack"; } !else { print "on the floor"; } !", and you lift the chair."; LookUnder: print_ret (string) MSG_NOTHING_DRAWN_UNDER; Climb: <>; Enter: if (self in player) { "You need to drop the chair before climbing on it."; } ], after [; Take: if (self hasnt moved) {"You decide to take one of the chairs.";} Drop: "You put the chair down."; Enter: print "You climb on the chair"; if (FilingCabinet in self) { print " and on the box"; } if (Organicchemistrytextbook in self || Otherthinnertextbook in self) { print " and on the book"; if (parent(Organicchemistrytextbook) == parent(Otherthinnertextbook)) {print "s"; } } "."; ], has enterable supporter; ! Did we look through this window Global F_SAW_HANGAR = 0; InsideLab Hallway3 "Hallway by a window" with description [; print "In this part of the hallway, there is a large window, which goes almost all the way to the false ceiling; the window overlooks "; if (F_SAW_HANGAR == 0) {print "something you can't quite see"; } else {print "a grotto which serves as a loading bay";} ". The fluorescent lamp to the north, near a door at the end of the hallway, is blinking. You can see some lockers to the south, and a meeting room to the west."; ], n_to Infrontofthebosssroomdoor, s_to Storagelockers, w_to Conferenceroom, has ; Object -> WindowHangar "window" with parse_name [ n ; n = 0; while (NextWord() == 'grotto' or 'window' or 'space' or 'bay' or 'crate' or 'loading' or 'dock' or 'cave' or 'water' or 'bay' or 'submarine') n++; return n; ], description [; F_SAW_HANGAR=1; "You look through the window, and see a wide open space. Your eyes habituate to the darkness, and you see shimmering water, and what looks like a very large loading dock. There doesn't seem to be a way to enter or exit this sort of grotto, which explains why you didn't see it from the beach. But there still is a loading dock, suggesting some kind of boat, maybe a submarine, was moored here... On the loading dock is a large crate. You have no idea what is in it."; ], before [; Take, Touch, Push, Pull, Cut1, Cut2,Rub: "You can only touch the window from here."; Enter: "There doesn't seem to be a way in."; ], has static concealed; InsideLab Storagelockers "Storage lockers" with description [; print_ret "The hallway runs north towards a window and a door at the end of the hallway, or west towards a lab. East is a door to a staircase, which is closed. ", (string) MSG_LOCKERS_DESC; ], n_to Hallway3, w_to Hallway2, has ; Object -> Lockedstaircase "door to the staircase" with name 'locked' 'staircase' 'stairs' 'door', description "A plain door, with a sign indicating a staircase.", before [; Attack: "It looks very thick and reinforced; you doubt you'll manage to open this door at all."; Enter, Open, Unlock, TryUnlock: if (second == Masterkeyring || Masterkeyring in player) { "Oddly enough, you can't find the key to this door on the keyring."; } else {print_ret (string) MSG_NO_IDEA_WHERE_KEY; } ], has openable lockable locked static concealed; ! TODO: lockers visible from Hallway2 and Hallway3, with a GoSee Object -> Lockers "locker", with parse_name [ n ; n = 0; ! covers "lockers" and "numbers" while (NextWord() == 'locker' or 'lock' or 'number' or 'combination' or 'dial' or 'rotary') n++; return n; ], description [; if (self has open) {"The locker that was locked is now open."; } else { print_ret (string) MSG_LOCKERS_DESC, " You need to turn a dial to open it, but it is so worn with use that the numbers on the dial are all but unreadable."; } ], before [; Open: if (self has locked) { "The combination lock is locked, and you have no clue about the right combination. Guess you'll just have to practice your safecracking skills."; } Unlock, TryUnlock, Turn: if (self has locked) { "You grab the combination lock and turn the dial back and forth, but you're not getting anywhere. You stop and try to think of a method that would tell if you're getting any closer."; } else { "The combination lock is already unlocked."; } Pick: if (self hasnt open) { <>; } else { <>; } Lock: if (self hasnt locked) { "There is nobody here who will steal anything."; } Attack: "Even if it looks worn, the combination lock is still very strong."; ! turn dial gently TheTouch, Touch, Listen: if (self has locked) { give self ~locked; score=score+5; "You try turning the combination lock very gently while listening closely for any click. Slowly, steadily, you manage to make the lock click three times; you pull on it, and the lock unlocks.";} ], after [; Open: print_ret "The locker opens, revealing ", (string) MSG_MESS_CABLES; ], has static concealed openable lockable locked container; Object -> -> MessOfWires "tangled mess of cables" with parse_name [ n ; n = 0; while (NextWord() == 'wire' or 'wires' or 'mess' or 'knot' or 'bundle' or 'cable' or 'cables' or 'radio' or 'microphone') n++; return n; ], description [; print_ret "This is ", (string) MSG_MESS_CABLES; ], before [; Remove, Take: if (parent(Wireinalockedlocker) == nothing) { if (_AtFullCapacity(player) == false) { move Wireinalockedlocker to player; scope_modified = true; if (radio has open) { "You look closely and find a cable that looks just like the melted one in the comms room."; } else { "The microphone is probably useless, but this bundle of cables looks like something you might need for the radio. You don't really know which one to pick, so you choose one at random."; } } else { print_ret (string) MSG_TAKE_NO_CAPACITY; } } else {"You already took a cable out of there."; } ], has ; Object Wireinalockedlocker "cable" with name 'wire' 'cable' 'from' 'locker', description "This is a cable you took in the comms guy's locker. You hope it's the right one.", has ; InsideLab Infrontofthebosssroomdoor "By the Major's office" with description [; print_ret (string) MSG_DOOR_MAJOR_PLATE, "There's not much else here, and if that blinking lamp doesn't stop blinking soon, you're going to get a headache. You can go back south towards the window in the hallway."; ], n_to BossRoomDoor, ! Bossroom, in_to BossRoomDoor, ! Bossroom s_to Hallway3, has ; ! todo: 'plate' 'sign' 'major' 'door' InsideLab Bossroom "Office of Major Westwood" with description [; print_ret "The office of Major Westwood isn't that big, all things considered. There is a desk facing the door, with a litter bin against it, and three chairs -- the Major's chair looking like the most comfortable one", (string) MSG_ONLY_WAY_IS_OUT, "."; ], s_to BossRoomDoor, !Infrontofthebosssroomdoor, out_to BossRoomDoor, ! Infrontofthebosssroomdoor has ; ! Have we searched the bin Global F_BIN_SEARCHED = 0; Object -> Garbagebin "litter bin" with parse_name [ w n ; n = 0; w = NextWord(); while (w) { if ((w == 'garbage' or 'litter' or 'bin' or 'paper' or 'papers' or 'crumpled') || (F_BIN_SEARCHED && w == 'note' or 'letter' or 'report' or 'warning')) { n++; w=NextWord(); } else {return n;} ! TODO: too nice? } return n; ], description "The litter bin has a few crumpled papers.", before [; Search, Take: if (F_BIN_SEARCHED == 0) { F_BIN_SEARCHED=1; } ReadLetter(); rtrue; ], has concealed; Object -> Desk "nice desk" with name 'desk' 'nice' 'import' 'detail', ! imported (avoid a compiler bug), detailed and details description "The desk is rather well-made, with a careful attention to details on the edges and the drawers. You wonder if the Major got it imported from the land.", before [; LookUnder: MrChad(self); rtrue; Open, Close: PerformAction(action, Drawer); rtrue; ], has concealed supporter open container transparent static; Object -> -> Drawer "drawer" with name 'drawer', description [; <>; ], before [; Push: <>; Pull, Remove: <>; ], has concealed container openable static; Global F_MASTER_KEYRING_TAKEN=0; Object -> -> -> Masterkeyring "master keyring" with name 'master' 'keyring' 'keys' 'key', description [; print "This keyring, with dozens of keys on it, "; if (self has moved) { print "was"; } else { print "is"; } " in the desk drawer of the Major; you're guessing it contains all the keys you need here."; ], before [; Search: "Unfortunately, they are not labeled. You'll just have to try each of them."; ], after [; Unlock: if (noun == OneBigLockableDoor) { "You try half a dozen keys, before finally finding the correct one, that unlocks the door."; } Take: if (F_MASTER_KEYRING_TAKEN == 0) { score = score + 5; F_MASTER_KEYRING_TAKEN=1; } ! take succeeded for the first time => points ], has; Object -> Chair "chairs" with name 'chair' 'chairs' 'major' 'comfortable', description "There are three chairs here; the Major's chair is very comfortable, while the chairs closest to the doors are mere wooden chairs. That's petty.", before [; Count: <>; Enter: "You sit in the most comfortable chair, and enjoy your position of power. Kinda."; ], has concealed pluralname supporter static; InsideLab Commsroom "Comms room" with description [; print "At last, you have managed to enter the island's communications room. You just need to figure out how to send an SOS, and you'll be able to be rescued from this island! "; print (string) MSG_TRANSMITTERS; if (headphones in location) { print ", and a pair of headphones on the desk"; } print_ret (string) MSG_ONLY_WAY_IS_OUT, ", to the east."; ], out_to [; <>; ], e_to [; if (headphones has worn) { "You should take off the headphones first."; } else { return CommsRoomDoor; } ], ! LobbyReception, before [; Listen: if (noun == 0 && headphones has worn) { <>; } ], has ; !Global freq = 4130; Constant RIGHT_FREQ = 4035; ! Have we found the right frequency Global F_FREQ_REACHED = 0; [ PrintFreq ; print "12.", freq, " Mc"; rtrue; ]; [ RustyKnobMessage ; print "The knob is rusty and not very precise anymore. You try your best to keep a light touch, but you land on the "; PrintFreq(); " frequency."; ]; [ KnobStuck f ; print "You turn the knob to the "; if (f) { print "left"; } else { print "right"; } print ", but it gets stuck; this is the end of the frequency band, and you are now at the "; PrintFreq(); " frequency."; ]; [ RadioLeftSub; if (location == Canningworkbench) { <>; } if (location == Pubkitchen) { <>; } if (location ~= Commsroom) { print_ret (string) MSG_PARSER_UNKNOWN_SENTENCE; } freq = freq -13; if (freq == RIGHT_FREQ && F_FREQ_REACHED == 0) { F_FREQ_REACHED = 1; score = score+5; } if (freq < 3895 ) { freq = 3895; KnobStuck(1); } ! then you have to turn up 6 times else { RustyKnobMessage(); rtrue; } ]; [ RadioRightSub; if (location == Canningworkbench) { <>; } if (location == Pubkitchen) { <>; } if (location ~= Commsroom) { print_ret (string) MSG_PARSER_UNKNOWN_SENTENCE; } freq = freq + 20; if (freq == RIGHT_FREQ && F_FREQ_REACHED == 0) { F_FREQ_REACHED = 1; score = score+5; } if (freq > 4126) { freq = 4126; KnobStuck(0); } ! then you have to turn down 6 times else { RustyKnobMessage(); rtrue; } ]; [ TheTouchSub ; <>; ]; Extend 'turn' * 'knob' 'left' ->RadioLeft * 'knob' 'right' ->RadioRight * noun 'slowly'/'gently' ->TheTouch; ! TODO: if fixed, give self general Object -> radio "radio transmitter" with description [; print (string) MSG_TRANSMITTERS; print ". The dial of the transmitter on the desk, above a wide access panel, is unusually large, which makes it easy to read precisely the frequency currently in use; a large knob below controls the frequency."; if (self has open) { print " You have opened the panel under the dial; there are some wires, and a cable that "; if (Wireinalockedlocker notin self) { print "appears to have melted, which isn't a good sign."; } else { print "you have fixed."; } } print "^^The transmitter is on, and currently set to the frequency of "; PrintFreq(); print ".^"; return 2; ! suppress the state message ], parse_name [ n ; n = 0; while (NextWord() == 'radio' or 'transreceiver' or 'transmitter' or 'radiotransmitter' or 'frequency' or 'dial' or 'panel' or 'access' or 'flap' or 'knob' or 'needle' or 'mic' or 'microphone' or 'receiver' or 'button') n++; return n; ], before [; Mic, Call, Push, Tell, Answer: if (headphones hasnt worn) { "You should probably wear the headphones first, to listen for an answer."; } if (Wireinalockedlocker in self && freq == RIGHT_FREQ) { EndGame(); rtrue; } else { PrintMsg(MSG_CALL_FOR_HELP_REPEAT); if (Wireinalockedlocker notin self) { print_ret ". In fact, t", (string) MSG_NO_NOISE_HEADPHONES; } else { print_ret (string) MSG_NOTHING_BUT_STATIC; } } ! TODO: replace wire / change cable ! test: is everything on one line if we type "put cable in radio" ? Receive: if (self hasnt open) { print "The access panel of the radio needs to be opened first. "; <>; } else { if (noun == Wireinalockedlocker) { move Wireinalockedlocker to self; remove MeltedCable; scope_modified = true; score = score + 5; "You carefully remove the melted cable, and replace it with the cable you found in the locker. That should do it."; } else {"That won't help fixing the radio.";} } Fix: if (parent(Wireinalockedlocker) == player or backpack) { <>; } ! take receiver/microphone Take: if (headphones has worn && Wireinalockedlocker in self && freq == RIGHT_FREQ) { EndGame(); rtrue; } SwitchOn: if (Wireinalockedlocker notin self) { "The radio transmitter is on, but for some reason it isn't working; you can't hear anything in the headphones."; } SwitchOff: "You'd rather leave the radio on, to listen and call for help."; Listen, Tie: PerformAction(action, headphones); rtrue; Turn: "Please specify if you want to turn the knob left or right."; ], after [; Open: print "You open the access panel of the radio, revealing some wires and a "; if (Wireinalockedlocker notin self) { print "melted"; } else { print "brand-new"; } " cable."; ], has static concealed openable switchable on container ; Object -> -> MeltedCable "melted cable" with name 'melted' 'broken' 'wires' 'cable', description "A cable has melted inside the radio, which is probably why it doesn't work.", before [; Fix,Take, Remove: if (parent(Wireinalockedlocker) == location or player or backpack) { <>;} else { "You should find another cable first."; } ], has static concealed; ! Works: call coast guards / call rescuers / call for help / call sos / send a sos / send distress call / send help message / call radio / talk in microphone / push button / talk to radio / shout at radio Object -> coastguards "coast guards" with name 'rescuers' 'coast' 'guards' 'guard', before [; Tell, Answer, Call: <>; default: print_ret (string) MSG_PARSER_NOSUCHTHING;], has concealed; !Constant MSG_YOU_PUT_THE_HEADPHONES "You put the headphones "; Object -> headphones "headphones" with name 'headphones', description [; <>; ], before [; Listen: PrintMsg(MSG_LISTEN_HEADPHONES); rtrue; Tie: "The headphones are already plugged in the radio transmitter."; ], after [; Disrobe: if (keep_silent == 0) { <>; } Take: if (keep_silent == 0) { <>;} Wear: print "You put the headphones on. "; PrintMsg(MSG_LISTEN_HEADPHONES); rtrue; Drop: "You put the headphones back on the desk."; ], has clothing pluralname concealed; Object -> note "note" with description [; print "The paper note "; if (self has moved) { print "that was "; } "taped to the radio lists a few frequencies, but it's the first one that interests you the most: ~Coast Guards: 12.4035 Mc~."; ], name 'note' 'paper', before [; LookUnder, Turn: "The back of the paper is blank."; ], has ; [ EndGame ; score = score +5; PrintMsg(MSG_CALL_FOR_HELP_REPEAT); print (string) MSG_NOTHING_BUT_STATIC; print " You're about to take the headphones off, when...^~Namibian Coast Guards here. SOS, can you hear me?~^~YES!~^You frantically push the button, and establish contact with them -- the first people you have talked to in a long while, and your lifeline here. After a few hours, they are able to confirm your position, and tell you to stand by.^^It takes a few more days, but when you see the helicopter approaching, you yelp in delight. The helicopter lands on the field in front of the white house, and a British officer gets off the helicopter. ~How do you do. My name is Colonel Bradley, and I'm here to take you home. Are you ready?~^~I've never been more ready to go home, Colonel.~^He smiles. ~Good. Glad we could find you so quickly. Get in.~^^As you get in the helicopter, you hear a squawk. You turn around and smile: the albatross is here, looking at you with a quizzical look.^~Goodbye, friend!~ you say as you wave at it.^The bird doesn't reply, but you imagine it must be thanking you for the fish... The thought makes you smile.^^And as the helicopter gains altitude, you look back down at Tristam Island. The small, charred, destroyed island is soon nothing more than a speck in the middle of the Atlantic Ocean; but you're taking its secret home with you.^"; deadflag = 2; ]; #endif; ! ifndef IS_DEMO