#include die: function; scoreRank: function; init: function; terminate: function; pardon: function; sleepDaemon: function; eatDaemon: function; darkTravel: function; preparse: function(cmd) { return(true); } parseError: function(num, str) { return(nil); } die: function { "\b*** You have died ***\b"; scoreRank(); "\bYou may restore a saved game, start over, undo the last move, or quit. "; while ( 1 ) { local resp; "\nPlease enter RESTORE, RESTART, UNDO, or QUIT: >"; resp := upper(input()); /* get input, convert to uppercase */ if ( resp = 'RESTORE' ) { resp := askfile( 'File to restore' ); /* find filename */ if ( resp = nil ) "Restore failed. "; else if ( restore( resp )) "Restore failed. "; else { setscore( global.score, global.turnsofar ); abort; } } else if ( resp = 'RESTART' ) { setscore( 0, 0 ); restart(); } else if ( resp = 'UNDO' ) { if (undo()) { "(Undoing one command)\b"; Me.location.lookAround(true); setscore(global.score, global.turnsofar); abort; } else "Sorry, no undo information is available."; } else if ( resp = 'QUIT' ) { /* * We're quitting the game. Do any final activity necessary, * and exit. */ terminate(); quit(); abort; } } } scoreRank: function { local s; s := global.score; "In a total of "; say( global.turnsofar ); " turns, you have achieved a score of "; say( s ); " points out of a possible "; say( global.maxscore ); ". "; } init: function { "\t\bYou're falling, the cold night air rushes through your hair, penetrates your clothes freezing your body. The ground rushes towards you at an alarming rate, if there was only someway of.... .\nDarkness...\b"; version.sdesc; // display the game's name and version number "\b"; setdaemon( turncount, nil ); // start the turn counter daemon // setdaemon( sleepDaemon, nil ); // start the sleep daemon // setdaemon( eatDaemon, nil ); // start the hunger daemon Me.location := startroom; // move player to initial location startroom.lookAround( true ); // show player where he is startroom.isseen := true; } preinit: function { local o; global.lamplist := []; o := firstobj(lightsource); while( o <> nil ) { if ( o.islamp ) global.lamplist := global.lamplist + o; o := nextobj(o, lightsource); } } terminate: function { "\(\bThe end, just another a beginning. 'till next time.\n\)"; } pardon: function { "What the hell are you doing?"; } goToSleep: function { } sleepDaemon: function( parm ) { local a, s; global.awakeTime := global.awakeTime + 1; a := global.awakeTime; s := global.sleepTime; if ( a = s or a = s+10 or a = s+20 ) "\bYou're feeling a bit drowsy; you should find a comfortable place to sleep. "; else if ( a = s+25 or a = s+30 ) "\bYou really should find someplace to sleep soon, or you'll probably pass out from exhaustion. "; else if ( a >= s+35 ) { global.awakeTime := 0; if ( Me.location.isbed or Me.location.ischair ) { "\bYou find yourself unable to stay awake any longer. Fortunately, you are "; if ( Me.location.isbed ) "on "; else "in "; Me.location.adesc; ", so you gently slip off into unconsciousness. \b* * * * * \bYou awake some time later, feeling refreshed. "; } else { local itemRem, thisItem; "\bYou find yourself unable to stay awake any longer. You pass out, falling to the ground. \b* * * * * \bYou awaken, feeling somewhat the worse for wear. You get up and dust yourself off. "; itemRem := Me.contents; while (car( itemRem )) { thisItem := car( itemRem ); if ( not thisItem.isworn ) thisItem.moveInto( Me.location ); itemRem := cdr( itemRem ); } } } } eatDaemon: function( parm ) { local e, l; global.lastMealTime := global.lastMealTime + 1; e := global.eatTime; l := global.lastMealTime; if ( l = e or l = e+5 or l = e+10 ) "\bYou're feeling a bit peckish. Perhaps it would be a good time to find something to eat. "; else if ( l = e+15 or l = e+20 or l = e+25 ) "\bYou're feeling really hungry. You should find some food soon or you'll pass out from lack of nutrition. "; else if ( l=e+30 or l = e+35 ) "\bYou really can't go much longer without food. "; else if ( l >= e+40 ) { "\bYou simply can't go on any longer without food. You perish from lack of nutrition. "; die(); } } numObj: basicNumObj; strObj: basicStrObj; global: object isclothed = nil moonphase= 1 status = 1 turnsofar = 0 // no turns have transpired so far score = 0 // no points have been accumulated yet maxscore = 80 // maximum possible score verbose = nil // we are currently in TERSE mode awakeTime = 0 // time that has elapsed since the player slept sleepTime = 600 // interval between sleeping times (longest time awake) lastMealTime = 0 // time that has elapsed since the player ate eatTime = 250 // interval between meals (longest time without food) lamplist = [] // list of all known light providers in the game ; version: object sdesc = "\(Night of the Phoenix\) \nby Ferret \bRelease 1.0 \nDeveloped with TADS: The Text Adventure Development System. " ; Me: basicMe ; darkTravel: function { "You stumble around in the dark, and don't get anywhere. "; } //----------------------------------------------------------------------------------- replace listcont: function( obj ) { local i, count, tot, list, cur, disptot, prefix_count; list := obj.contents; tot := length( list ); count := 0; disptot := itemcnt( list ); for (i := 1 ; i <= tot ; ++i) { cur := list[i]; if ( cur.isListed ) { /* presume there is only one such object */ prefix_count := 1; /* * if this is one of more than one equivalent items, list * it only if it's the first one, and show the number of * such items along with the first one */ if (cur.isEquivalent) { local before, after; local j; local sc; sc := firstsc(cur); for (before := after := 0, j := 1 ; j <= tot ; ++j) { if (isIndistinguishable(cur, list[j])) { if (j < i) { /* * note that objects precede this one, and * then look no further, since we're just * going to skip this item anyway */ ++before; break; } else ++after; } } /* * if there are multiple such objects, and this is the * first such object, list it with the count prefixed; * if there are multiple and this isn't the first one, * skip it; otherwise, go on as normal */ if (before = 0) prefix_count := after; else continue; } if ( count > 0 ) { if ( count+1 < disptot ) ", "; else if (count = 1) " and "; else ", and "; } /* list the object, along with the number of such items */ if (prefix_count = 1) cur.adesc; else { sayPrefixCount(prefix_count); " "; cur.pluraldesc; } /* show any additional information about the item */ if (cur.isworn) {" (being worn)"; global.isclothed:=true;}; if (cur.islamp and cur.islit ) " (providing light)"; count := count + 1; } } } replace iVerb: deepverb verb = 'inventory' 'i' action( actor ) = { "Status: "; if (global.status=1) "'I feel like shit.'"; if (global.status=2) "'I need a beer.'"; if (global.status=3) "'I'll live'"; if (global.status=4) "'I'm fine'"; if (global.status=5) "'100%, boy am I good'"; "\n"; if (length( actor.contents )) { "%You% %have% "; listcont( actor ); ". "; listcontcont( actor ); } else "%You% %are% empty-handed.\n"; if (not global.isclothed) "\nYou are completely naked.\n"; } ; //------------------------------------------------------------------------ liftVerb: deepverb sdesc ="lift" verb='lift' doAction = 'Lift' ; smashVerb: deepverb sdesc = "smash" verb = 'smash' doAction = 'Smash' ; sniffVerb: deepverb sdesc="sniff" verb='sniff' doAction='Sniff' ; wankVerb: deepverb sdesc= "wank" verb= 'wank' action (actor) = "Wadeesh. Slap Slap Slap Slap. SPLURGE. 'I needed that'." ; //-------------------------------------------------------------------------- l32street: room sdesc="\(\b32nd Street.\)" ldesc="\bYou stand in 32nd street. Litter blows across the floor. To the east there is an entrance to an apartment block. To the west an iron fence blocks the way to the graveyard." west = "The graveyard fence is in the way." north= {"You think you're going to wander round the city pointlessly? Does the pope shit in the woods?"; return(nil); } south= m32street east= apartmentblock ; m32street: room sdesc= "\(\b32nd Street.\)" ldesc= "\bYou stand in 32nd street. Litter blows across the floor in the wind, and steam rises from manholes. The gate to the graveyard is to the west. The street runs north, south, there is an alleyway to the east." west = graveyard east= alley south = n32street north = l32street down ={if (manholem32.isopen) "'You really want to get lost in the dark sewer? I don't think so.'"; else "The manhole is closed.";} ; n32street: room sdesc= "\(\b32nd Street.\)" ldesc= "\bYou stand in 32nd street, Litter blows across the ground in the wind. The road runs north and south. A newspaper blows into your legs and crumples at your feet. To the west an iron fence blocks the way to the graveyard" west="The graveyard fence is in the way." north= m32street south= { "You ain't wandering round this goddamned city with no reason."; return(nil); } ; alley: room sdesc= "\(\bAlleyway\)" ldesc= "\bYou walk into a deserted dead-end alleyway, gang markings cover the walls in a variety of wild colours. A large dirty bin stands to one wall, and a rusty fire escape runs up the other." up = fireescape1 west = m32street ; apartmentblock: room notfirsttime = nil sdesc= "\(\bApartment Entrance.\)" ldesc= {if (self.notfirsttime) "A double door stands between you and the lobby, your room lies beyond this door."; else "A double door stands before you and the lobby, as you scan up and down the intercom buttons, you stagger backwards as images and sounds flood your mind. Momentarily you see yourself opening the door with your key, you live here, or used to. Then your mind clears."; self.notfirsttime:=true; global.status:=global.status+1; } west= l32street ; apartmentroom1a: room sdesc="\(\bApartment\)" ldesc="\bYou stand in an apartment, obviously uninhabited for months. The dusty room is devoid of furniture except an old dressing table and a wardrobe. The apartment door stands to the north, taped up with police tape." south = fireescape1 ; apartmentroom2a: room sdesc="\(\bApartment\)" ldesc="\bYou stand in an nicely decorated apartment, luckily the inhabitant is out. Prints of various flowers adorn the walls, and a wardrobe, chest of drawers and a bed furnish the room." south=fireescape2 ; apartmentroom3a: room sdesc="\(\bApartment\)" ldesc="\bYou stand in an apartment, luckily the inhabitant is out. A bed and a wardrobe are among the few items of scant furniture. A heavy metal poster hangs on one of the walls." south=fireescape3 ; fireescape1: room sdesc= "\(\bFire Escape\)" ldesc= "\bYou stand on an old rusty fire escape, there is a window to the north. The fire escape heads upwards and downwards." north= apartmentroom1a down= alley up= fireescape2 south="You want to jump off? Surely life isn't that bad?" ; fireescape2: room sdesc= "\(\bFire Escape\)" ldesc= "\bYou stand on an old rusty fire escape, there is a window to the north. The fire escape leads up and down." north= apartmentroom2a down= fireescape1 up= fireescape3 south="You want to jump off? Surely life isn't that bad?" ; fireescape3: room sdesc= "\(\bFire Escape\)" ldesc="\bYou stand at the top of an old rusty fire escape, there is a window to the north." north=apartmentroom3a down=fireescape2 south="You want to jump off? Surely life isn't that bad?" up={"You have already reached the top of the fire escape"; return(nil);} ; graveyard: room sdesc= "\(\bGraveyard\)" ldesc= "\bYou stand in a graveyard surrounded by a heavy iron fence rusted with age, the gate swings opens and closes in the wind to the east. There is an open grave overshadowed by an engraved tombstone." down = startroom west = graveyard5 south = graveyard1 north = graveyard7 east = m32street ; graveyard7: graveyard ldesc = "\bYou stand in a graveyard surrounded by a heavy iron fence rusted with age." down = "You cannot go down without digging." north = "The fence is in the way." west = graveyard8 east = "The fence is in the way." south = graveyard ; graveyard8 : graveyard7 east = graveyard7 south=graveyard5 north="The fence is in the way." west="The fence is in the way." ; graveyard5 : graveyard7 east = graveyard west = "The fence is in the way." south = graveyard2 north = graveyard8 ; graveyard2 : graveyard5 north = graveyard5 south = "The fence is in the way." east = graveyard1 west = "The fence is in the way." ; graveyard1 : graveyard2 north = graveyard south = "The fence is in the way." west = graveyard2 east = "The fence is in the way." ; startroom: room sdesc = "\t\(\bDarkness\)" ldesc = "\bYou come round, you are laying half-buried in soft damp mud. You move your stiff limbs to find earthen walls all around. You force open your heavy eyes, and look upwards. Pale moonlight shines down to fill the 6' pit which you are lying in. A crescent moon shines brightly in the velvety blackness of the night sky." up = graveyard ; //-------------------------------------------------------------------------- bed1a: beditem noun='bed' location = apartmentroom1a ; bed2a: beditem noun='bed' location = apartmentroom2a ; bed3a: beditem noun='bed' location = apartmentroom3a ; bigbin: openable, qcontainer, fixeditem noun= 'bin''tip''can' adjective = 'big''dirty''large''trash''garbage''rubbish' isopen=nil sdesc="bin" ldesc="A large dirty trash can with the word BIFFA written down one side, it is closed." location = alley ; bullet: item sdesc = "a bullet" noun = 'bullet' adjective = 'silver' ldesc = "Wait a minute, underneath all this mud the bullet is actually silver!" location = mud issilver=true ; chestofdrawers2a: fixeditem, surface sdesc="chest of drawers" ldesc="A chest of drawers, spotlessly clean, a photo of an old woman stands on top." noun='chest''drawers' adjective='chest''of' location= apartmentroom2a ; coddrawer2a: fixeditem, qcontainer, openable sdesc="drawer" isopen=nil ldesc="The drawer in the chest of drawers has no lock." noun='drawer' location=apartmentroom2a ; deadmouse: item sdesc="dead mouse" ldesc="This unfortunate soul has squeeked it's last squeek." location=wardrobe3a noun='mouse''corpse' adjective='mouse''dead' iscorpse=true ; dressingtable1a: fixeditem sdesc="dressing table" ldesc="An old dressing table with a cracked mirror and a drawer." noun='table' adjective='dressing''old''dirty' location= apartmentroom1a ; dtdrawer1a: fixeditem, qcontainer, openable sdesc="drawer" isopen=nil ldesc="The drawer in the dressing table has no lock." noun='drawer' adjective='dressing''table' location=apartmentroom1a ; engagementring:clothingItem sdesc="ring" ldesc="A gold engagement ring" hasbeenworn=nil noun='ring' adjective='gold''engagement' location=dtdrawer1a verDoWear(actor)={} doWear(actor)= { if (engagementring.hasbeenworn) { "As you slide the ring onto your finger, the memory of Joshua stings in your mind.\n"; } else { "As you slide the ring onto your finger, you stagger backwards. Memories flood into your head, a face.. so beautiful, so much emotion... love, a touch... so soft, a name.... Joshua.\n"; "You feel your strength return to you.\n"; global.status:=global.status+1; engagementring.hasbeenworn := true; } pass doWear; } ; eveningdress: clothingItem sdesc="black dress" ldesc="A figure hugging, low-cut, short black dress." location= wardrobe2a noun='dress' adjective='short''black''low-cut' ; fireescapei: fixeditem noun='escape''fireescape' adjective='fire' location=alley sdesc="a fire-escape" ldesc="This rusty old fire escape seems sturdy enough." ; fireescape1i: fixeditem noun='escape''fireescape' adjective='fire' location=fireescape1 sdesc="a fire-escape" ldesc="This rusty old fire escape seems sturdy enough." ; fireescape2i: fixeditem noun='escape''fireescape' adjective='fire' location=fireescape2 sdesc="a fire-escape" ldesc="This rusty old fire escape seems sturdy enough." ; fireescape3i: fixeditem noun='escape''fireescape' adjective='fire' location=fireescape3 sdesc="a fire-escape" ldesc="This rusty old fire escape seems sturdy enough." ; intercombuttons: fixeditem noun='button''buttons''intercom' adjective='intercom' sdesc="intercom buttons" ldesc="You are sure one of these buzzes your room." location=apartmentblock verDoPush(actor)={} doPush(actor)={"\ \ No answer.";} ; knickers2a: clothingItem noun='knickers' adjective='black''lacy' sdesc="knickers" ldesc="A pair of lace black knickers" adesc={ "a pair of ";self.sdesc; } verDoSniff(actor)={} doSniff(actor)={"'Hmmmm, smells good.'";} location=coddrawer2a ; leatherjeans: clothingItem sdesc="leather jeans" ldesc="A pair of knackered old black leather jeans" noun='jeans''trousers' adesc= { "a pair of "; self.sdesc; } noun='jeans''trousers' adjective='old''leather''knackered''black' location=bigbin ; manholem32: fixeditem, openable noun='manhole''hole''cover' adjective='man''hole''manhole' isopen=nil sdesc="a manhole" ldesc={if (self.isopen) "A hole leads down into the darkness."; else "The way down into the sewers is blocked by a solid metal cover." ; } location=m32street ; mirror1a: fixeditem sdesc="dressing table mirror" ldesc="You look into the cracked mirror, your piercing grey eyes stare out of a pale face, you run a finger across a small scar above your left eye. In life you were probably quite a looker, but now the veil of death hangs over your features. Who you are, or were, or why you are here, is a mystery. 'Who the hell am I ?'" noun='mirror' adjective='dressing''table' location=apartmentroom1a ; mud: qcontainer, fixeditem sdesc = "mud" adesc = "some" noun = 'mud''soil''dirt''earth' location = startroom verDoSearch(actor) = {} doSearch(actor) = self.doExamine(actor) verDoDig (actor) = {} doDig(actor)= self.doExamine(actor) ; newspaper: readable, item sdesc= "newspaper" noun= 'newspaper''paper' adjective='news' ldesc= "It gives the date as 31/10/98" readdesc= "It gives the date as 31/10/98, and contains a variety of constructive stories about celebraties and their sexual habits. 'Hey, I didn't know Pamela Anderson, liked her dog THAT much!'" location= n32street ; Photo2a: item sdesc="photograph" ldesc="A silver framed photograph of a middle aged woman." noun='photo''photograph''frame' adjective='photo' location= chestofdrawers2a issilver= true ; policetape: item isListed=nil sdesc="police tape" adesc={"some ";self.sdesc;} ldesc="Standard yellow and blue tape used to seal off crime scenes, looks quite old." noun='tape' adjective='police' location=apartmentroom1a ; prints: item sdesc="floral prints" ldesc="High quality floral prints, probably hot in this block." noun='print''prints' adjective='floral''flower' location=apartmentroom2a ; poster: item sdesc="heavy metal poster" ldesc="A picture of a band called Nightlife a dodgy looking bunch of ageing rockers with stupid perms." noun='poster' adjective='heavy''metal' location=apartmentroom3a ; tombstone: fixeditem, readable noun = 'gravestone''tombstone''stone''engraving' adjective = 'grave''tomb''my' sdesc = "tombstone" ldesc = "It's engraved with a loving message." readdesc = "Martyn Taylor. Thank god that useless charmless ugly monkey-spank lord-of-all that is spack master spanner and all round plum-monger is dead." location = graveyard ; tshirt: clothingItem sdesc="t-shirt" ldesc="A plain black t-shirt." location= wardrobe1a noun='tshirt''shirt''t-shirt' adjective='t''plain''black' ; wardrobe1a: fixeditem, qcontainer, openable isopen=nil hasbeenopened=nil sdesc="wardrobe" ldesc= "A dusty old wardrobe." location=apartmentroom1a noun='wardrobe''cupboard' adjective='old''dusty' verDoOpen(actor)={} doOpen(actor)={ if (not wardrobe1a.hasbeenopened) { tshirt.moveinto(apartmentroom1a); wardrobe1a.hasbeenopened:=true; } pass doOpen; } ; wardrobe2a: fixeditem, qcontainer, openable isopen=nil hasbeenopened=nil sdesc="wardrobe" ldesc ="A wardrobe unlike any other." location=apartmentroom2a noun='wardrobe''cupboard' verDoOpen(actor)={} doOpen(actor)={ if (not wardrobe2a.hasbeenopened) { eveningdress.moveinto(apartmentroom2a); wardrobe2a.hasbeenopened:=true; } pass doOpen; } ; wardrobe3a: fixeditem, qcontainer, openable isopen=nil hasbeenopened=nil sdesc="wardrobe" ldesc ="A wardrobe unlike any other except it smells bad." location=apartmentroom3a noun='wardrobe''cupboard' verDoOpen(actor)={} doOpen(actor)={ if (not wardrobe3a.hasbeenopened) { deadmouse.moveinto(apartmentroom3a); wardrobe3a.hasbeenopened:=true; } pass doOpen; } ;