! --------------------------------------------------------------------------------------------------- ! Inform Demonstration ! --------------------------------------------------------------------------------------------------- Constant Story "Adventure Core"; Release 1; ! Some attributes for objects. Attribute light; Attribute concealed; Attribute worn; Attribute clothing; Attribute animate; Attribute proper; Attribute moved; Attribute portal; Attribute container; Attribute interior; Attribute open; Attribute openable; Attribute workflag; Attribute enterable; Attribute scenery; Attribute static; Attribute direction; Attribute visited; Attribute lockable; Attribute locked; Attribute switchable; Attribute on; Attribute general; Attribute edible; Attribute autosearch; Attribute scored; Attribute talkable; Attribute is_cube; ! Some Default Properties Property longdesc 0; Property article "a"; Property initpos 0; Property preroutine $ffff; Property postroutine $ffff; Property rodroutine $ffff; Property weight 1; Property score_value 0; Property dirprop; Property n_to; Property s_to; Property e_to; Property w_to; Property ne_to; Property se_to; Property nw_to; Property sw_to; Property u_to; Property d_to; Property portalto; Property closedpos; Property long timeleft; Property with_key; Property becomes; ! Compass Direction Objects (Shouldn't need changing) Object compass "compass" nothing has concealed; Object n_obj "north wall" compass with name "n" "north" "wall", article "the", dirprop n_to has direction scenery; Object s_obj "south wall" compass with name "s" "south" "wall", article "the", dirprop s_to has direction scenery; Object e_obj "east wall" compass with name "e" "east" "wall", article "the", dirprop e_to has direction scenery; Object w_obj "west wall" compass with name "w" "west" "wall", article "the", dirprop w_to has direction scenery; Object ne_obj "northeast wall" compass with name "ne" "northe" "wall", article "the", dirprop ne_to has direction scenery; Object nw_obj "northwest wall" compass with name "nw" "northw" "wall", article "the", dirprop nw_to has direction scenery; Object se_obj "southeast wall" compass with name "se" "southe" "wall", article "the", dirprop se_to has direction scenery; Object sw_obj "southwest wall" compass with name "sw" "southw" "wall", article "the", dirprop sw_to has direction scenery; Object u_obj "ceiling" compass with name "u" "up" "ceiling", article "the", dirprop u_to has direction scenery; Object d_obj "floor" compass with name "d" "down" "floor", article "the", dirprop d_to has direction scenery; ! Help Object Object help "Help Object" nothing with longdesc "This adventure was created using Adventure Core.", ! An object for Dark locations Object thedark "Darkness" nothing with longdesc "It is pitch dark, and you can't see a thing."; ! A starting Room object Object gen_room "Generic Room" nothing with longdesc "This is the Generic room, describe as fit." has light; ! This next object is for Yourself, describe as appropriate Object selfobj "yourself" office_1 with name "me" "myself" "self", article "the", has concealed animate proper; ! Add your objects after this. ! A few dictionary definitions. Dictionary again_word "again"; Dictionary g_word "g"; Dictionary it_word "it"; Dictionary them_word "them"; Dictionary and_word "and"; Dictionary comma_word "xcomma"; Dictionary but_word "but"; Dictionary except_word "except"; Dictionary all_word "all"; Dictionary both_word "both"; Dictionary everyt_word "everyt"; Dictionary the_word "the"; Dictionary a_word "a"; Dictionary an_word "an"; Dictionary o_word "o"; Dictionary oops_word "oops"; ! Global Definitions, the first three must be location,score and turns ! for status line Global location = gen_room; ! Change this to wherever you want to start Global score = 0; Global turns = 1; Global maxscore = 50; ! Change to a suitable value for game Global player = selfobj; ! Change if not selfobj Global max_carry = 4; ! Maximum weight you can carry Global itobj = 0; Global toomanyf = 0; Global actor = 0; Global lightflag = 1; Global deadflag = 0; Global buffer string 120; Global parse string 64; Global buffer2 string 120; Global parse2 string 64; Global inputobjs data 16; Global action = 0; Global inp1 = 0; Global inp2 = 0; Global multinps data 64; Global special_word = 0; Global special_number = 0; Global scr_mode = 0; ! --------------------------------------------------------------------------------------------------- ! Game control code ! --------------------------------------------------------------------------------------------------- [ Main; print "^^^^Add your own Game intro message here.^" Banner(); LookSub(); Game(); ]; global multiflag; [ Game unused i j k l meta aflag; for i 1 to 100 { j=random(i); } while deadflag==0 { .Error; inp1=0; inp2=0; action=0; Input(inputobjs); if actor~=player { CDefArt(actor); print " has better things to do.^"; jump timeslice; } if toomanyf==1 { toomanyf=0; print "(taking the first sixteen objects only)^"; } aflag=0; if action~=0 { aflag=1; } if action==0 { action=inputobjs->0; } meta=0; if action==#a$ScoreSub or #a$ScriptonSub or #a$ScriptoffSub { meta=1; } if action==#a$SaveSub or #a$RestoreSub { meta=1; } if aflag==0 { i=inputobjs->1; inp1=inputobjs->2; inp2=inputobjs->3; } if aflag~=0 { i=2; } multiflag=0; if i==0 { Process(0,0); } if i>0 { if inp1~=0 { Process(inp1,inp2); } if inp1==0 { multiflag=1; j=multinps->0; if j==0 { print "Nothing to do!^"; jump Error; } for k 1 to j { l=multinps->k; print_obj l; print ": "; Process(l,inp2); } } } .timeslice; if deadflag==0 { if meta==0 { Time(); } } } print "^^ ***"; if deadflag==1 { print " You have died "; } if deadflag==2 { print " You have won "; } print "***^^^"; ScoreSub(); .RRQPL; print "^Would you like to RESTART, RESTORE a saved game or QUIT?^"; .RRQL; print_char '?'; print_char ' '; read buffer parse; i=parse-->1; if i==#w$quit or #w$q { quit; } if i==#w$restar { restart; } if i==#w$restor { RestoreSub(); jump RRQPL; } print "Please answer RESTART, RESTORE or QUIT.^"; jump RRQL; ]; [ Process i j; inp1 = i; inp2 = j; if location~=0 { i=prop(location,preroutine); if i~=$ffff { if indirect(i)~=0 { ret#true; } } } if inp1~=0 { i=prop(inp1,preroutine); if i~=$ffff { if indirect(i)~=0 { ret#true; } } } j=#actions_table-->action; indirect(j); ]; [ PostAct i k; k=location; i=prop(k,postroutine); if i==$ffff { jump NoLocPost; } if indirect(i)~=0 { ret#true; } .NoLocPost; k=0; i=inputobjs->1; if i~=0 { k=inp1; } if k==0 { ret#false; } i=prop(k,postroutine); if i==$ffff { ret#false; } indirect(i); return sp; ]; [ LPostAct i k; k=location; if k==0 { ret#false; } i=prop(k,postroutine); if i==$ffff { ret#false; } indirect(i); return sp; ]; [ Banner i; print_paddr #Story; print "^An Interactive Demonstration^\ Copyright (c) YYYY Authors Name . Rights Notice.^\ Release "; print_num (0-->1) & $03ff; print " / Serial number "; for i 18 to 23 { print_char 0->i; } print " (Compiled by Inform v"; inversion; print ")^"; ]; [ Time i j k; inc turns; ! Insert any timer dependant code here. i=lightflag; lightflag=OffersLight(parent(player)); if i==0 { if lightflag==1 { new_line; location=parent(player); LookSub(1); } } if i==1 { if lightflag==0 { new_line; print "It is now pitch dark in here!^"; location=thedark; } } ]; ! Check for Time up on an object. [ TimeUp i j; j=prop(i,timeleft); if j>turns { ret#false; } if j==0 { ret#false; } put_prop i timeleft 0; ret#true; ]; [ DecTimeUp i j; j=prop(i,timeleft); if j==0 { ret#false; } dec j; put_prop i timeleft j; if j>0 { ret#false; } ret#true; ]; [ SetTimer i j; j=turns+j; put_prop i timeleft j; ]; [ Clock i j; j=prop(i,timeleft)-turns; return j; ]; [ OffersLight i; if i has light { ret#true; } if i has container { if i has interior { if i hasnt open { ret#false; } } } i=child(i); while i~=0 { if 1==OffersLight(i) { ret#true; } i=sibling(i); } ret#false; ]; ! --------------------------------------------------------------------------------------------------- ! Verb action routines ! --------------------------------------------------------------------------------------------------- [ ScoreSub rsc; if deadflag==0 { print "You have so far scored "; } if deadflag > 0 { print "In that game you scored "; } print_num score; print " out of a possible " print_num maxscore; print ", in "; print_num turns; print " turns, earning you the rank of "; ! Change rating to suit your game. rsc=score; if rsc >= 35 { print_ret "navigator."; } if rsc >= 20 { print_ret "adventurer."; } if rsc >= 5 { print_ret "explorer."; } if rsc >= 1 { print_ret "tourist."; } print_ret "somnambulist."; ]; [ QuitSub i; print "Are you sure you want to quit? "; .QSL; read buffer parse; i=parse-->1; if i==#w$yes or #w$y { quit; } if i==#w$no or #w$n { ret#true; } print "Please answer yes or no."; print_char '>'; print_char ' '; jump QSL; ]; [ QQuitSub; quit; ]; [ RestartSub i; print "Are you sure you want to restart? "; .RSL; read buffer parse; i=parse-->1; if i==#w$yes { restart; } if i==#w$y { restart; } if i==#w$no { ret#true; } if i==#w$n { ret#true; } print "Please answer yes or no."; print_char '>'; print_char ' '; jump RSL; ]; [ RestoreSub; restore Rmaybe; print_ret "Failed."; .RMaybe; print "Ok.^"; ]; [ SaveSub; save Smaybe; print_ret "Failed."; .Smaybe; print "Ok.^"; ]; [ ScriptOnSub i; if scr_mode==1 { print_ret "Transcripting is already on."; } scr_mode=1; i=(0-->8)|1; put 0 word 8 i; print "Start of a transcript of^"; Banner(); ]; [ ScriptOffSub i; if scr_mode==0 { print_ret "Transcripting is already off."; } print "^End of transcript.^"; scr_mode=0; i=(0-->8)&$fffe; put 0 word 8 i; ]; [ InvSub i; i=child(player); if i==0 { print_ret "You are carrying nothing."; } print "You are carrying:^"; Inventory(player); ]; [ Inventory obj n o2 i; o2=1; if n~=0 { for i 1 to n { print " "; } o2=DescribeObj(obj,0); new_line; } if o2==0 { ret#true; } o2=child(obj); while o2~=0 { Inventory(o2,n+1); o2=sibling(o2); } ]; [ TakeSub i; i=RTakeSub(location); if i~=0 { ret#true; } if 1==PostAct() { ret#true; } print "Taken.^"; ]; [ RTakeSub fromobj i j k; if inp1==player { print_ret "As the bishop said to the actress."; } if inp1 has animate { print "I don't suppose "; DefArt(inp1); print_ret " would care for that."; } i=parent(inp1); if i==player { print_ret "You already have that."; } while i~=fromobj { if i hasnt container { print_ret "That isn't available."; } if i hasnt open { print "Unfortunately the "; print_obj i; print_ret " isn't open."; } i=parent(i); if i==player { i=fromobj; } } if inp1 has scenery { print_ret "That's hardly portable."; } if inp1 has static { print_ret "Fixed in place."; } j=child(player); k=0; while j~=0 { if j hasnt worn { k=k+prop(j,weight); } j=sibling(j); } if k>max_carry { print_ret "You're carrying too many things already."; } remove_obj inp1; insert_obj inp1 player; if inp1 hasnt moved { set_attr inp1 moved; if inp1 has scored { score=score+prop(inp1,score_value); } } ret#false; ]; [ DropSub i j k; i=parent(inp1); if i==location { print_ret "Already on the floor."; } if i~=player { print_ret "You haven't got that."; } if inp1 has worn { print "(First taking it off)^"; clear_attr inp1 worn; } remove_obj inp1; i=parent(player); insert_obj inp1 i; if 1==PostAct() { ret#true; } print "Dropped.^"; ]; [ RemoveSub i; i=parent(inp1); if i hasnt open { print_ret "Alas, it is closed."; } if i~=inp2 { print_ret "But it isn't there now."; } if inp2 has worn { print_ret "You'll need to take it off first."; } i=RTakeSub(inp2); if i~=0 { ret#true; } action=#a$TakeSub; if 1==PostAct() { ret#true; } action=#a$RemoveSub; if 1==PostAct() { ret#true; } print "Removed.^"; ]; [ InsertSub i; if inp2==d_obj { action=#a$DropSub; Process(inp1,0); ret#false; } i=parent(inp1); if i~=player { print_ret "You need to be holding it before you can put it into something else."; } if inp2 hasnt container { print_ret "That can't contain things."; } if inp2 hasnt open { print_ret "Alas, it is closed."; } if inp2 has worn { print_ret "You'll need to take it off first."; } if inp1 has worn { print "(first taking it off)^"; clear_attr inp1 worn; } remove_obj inp1; insert_obj inp1 inp2; if 1==LPostAct() { ret#true; } if multiflag==1 { print_ret "Done."; } print "You put the "; print_obj inp1; print " into the "; print_obj inp2; print_ret "."; ]; [ TransferSub i a; a=#a$InsertSub; if inp2==d_obj { a=#a$DropSub; } i=parent(inp1); if i~=player { while i~=0 { if i hasnt open { print_ret "That isn't in your possession."; } i=parent(i); if i==player { jump Segue; } } print_ret "First pick that up."; } .Segue; remove_obj inp1; insert_obj inp1 player; action=a; Process(inp1,inp2); ret#false; ]; [ EmptySub; inp2=d_obj; EmptyTSub(); ]; [ EmptyTSub i j; if inp1 hasnt container { CDefArt(inp1); print_ret " can't contain things."; } if inp1 hasnt open { CDefArt(inp1); print_ret " is closed."; } if inp2~=d_obj { if inp2 hasnt container { CDefArt(inp2); print_ret " can't contain things."; } if inp2 hasnt open { CDefArt(inp2); print_ret " is closed."; } } i=inp1; i=child(i); if i==0 { DefArt(inp1); print_ret " is empty already."; } while i~=0 { j=sibling(i); print_obj i; print ": "; action=#a$TransferSub; Process(i,inp2); i=j; } ]; [ EnterSub i; if inp1 has portal { GoSub(); ret#true; } i=parent(player); if i~=location { print "But you're already in the "; print_obj i; print_ret "."; } if inp1 hasnt enterable { print_ret "A surreal idea."; } i=parent(inp1); if i==compass { GoSub(); ret#true; } if i~=location { print_ret "You can only get into something on the floor."; } remove_obj player; insert_obj player inp1; print "You get into the "; print_obj inp1; print_ret "."; ]; [ ExitSub i; i=parent(player); if i==location { print_ret "But you're aren't in anything at the moment."; } remove_obj player; insert_obj player location; print "You are on your own two feet again.^"; LookSub(1); ret#true; ]; [ VagueGoSub; print_ret "You'll have to say which compass direction to go in."; ]; [ GoSub i j k df movewith; movewith=0; i=parent(player); if location~=thedark { if i~=location { print "You'll have to get out of the "; print_obj i; print_ret " first."; } } j=prop(i, prop(inp1, dirprop)); if j==0 { print_ret "You can't go that way."; } if j has portal { if j has concealed { print_ret "You can't go that way."; } if j hasnt open { if inp1==u_obj { print "You are unable to climb "; Defart(j); print_ret "."; } if inp1==d_obj { print "You are unable to descend "; Defart(j); print_ret "."; } print "You can't, since "; Defart(j); print_ret " is in the way."; } j=prop(j,portalto); if j==0 { print "You can't, since "; Defart(j); print_ret " leads nowhere."; } } if movewith==0 { remove_obj player; insert_obj player j; } if movewith~=0 { if inp1==d_obj or u_obj { print_ret "It won't go that way."; } remove_obj movewith; insert_obj movewith j; } df=OffersLight(j); if df~=0 { location=j; lightflag=1; } if df==0 { location=thedark; lightflag=0; } if 1==LPostAct() { ret#true; } LookSub(1); ]; [ LookSub weary i j k o flag descin; descin=location; new_line; print_obj location; i=parent(player); if location~=thedark { if i~=location { print " (in the "; print_obj i; print ")"; descin=i; } } new_line; if location has visited { if weary==1 { jump NoLD; } } i = prop(location,longdesc); print_paddr i; new_line; .NoLD; if location hasnt visited { set_attr location visited; if location has scored { score=score+5; } } o=child(descin); k=0; while o~=0 { if o hasnt concealed { if o hasnt scenery { set_attr o workflag; inc k; if o hasnt moved { j=prop(o,initpos); if o has portal { if o hasnt open { j=prop(o,closedpos); } } if o has switchable { if o hasnt on { j=prop(o,closedpos); } } if j~=0 { new_line; print_paddr j; new_line; flag=1; clear_attr o workflag; dec k; } } } } o=sibling(o); } if k==0 { jump AskRoom; } new_line; if descin~=location { print "In the "; print_obj descin; print " you"; } if descin==location { print "You"; } print " can "; if flag==1 { print "also "; } print "see "; i=0; o=child(descin); while o~=0 { if o has workflag { i=i+1; DescribeObj(o,1); if i==k-1 { print " and "; } if i < k-1 { print ", "; } } o=sibling(o); } if descin~=location { print ".^"; } if descin==location { print " here.^"; } .AskRoom; action=#a$LookSub; if 1==LPostAct() { ret#true; } ]; [ ExamineSub i; if location==thedark { print_ret "Darkness, noun. An absence of light to see by."; } if inp1 has autosearch { SearchSub(); ret#false; } i=prop(inp1,longdesc); if i==0 { if inp1 has container { SearchSub(); ret#false; } print "You see nothing special about "; Defart(inp1); print_ret "."; } print_paddr i; new_line; if inp1 has switchable { print "It is currently switched "; if inp1 has on { print "on.^"; } if inp1 hasnt on { print "off.^"; } } if 1==PostAct() { ret#true; } ]; [ DescribeObj o listmode p p2 i k rval; if listmode ~=2 { Indefart(o); } if listmode ==2 { Defart(o); } if o has light { print " (providing light)"; } if o has worn { print " (being worn)"; } if o has container { if listmode ~=2 { print " (which is "; } if listmode ==2 { print ", which is "; } if o hasnt open { print "closed"; if o has interior { jump Cdone; } } if o has open { print "open"; } p=child(o); if p==0 { print " but empty"; jump Cdone; } if listmode==0 { rval=1; jump Cdone; } print " and contains "; k=0; p2=p; while p2~=0 { p2=sibling(p2); inc k; } i=0; while p~=0 { inc i; DescribeObj(p,1); if i==k-1 { print " and "; } if i < k-1 { print ", "; } p=sibling(p); } .Cdone; if listmode ~=2 { print ")"; } } return rval; ]; [ GiveSub i j; print_obj inp2; print_ret " doesn't seem interested.^"; ]; [ UnlockSub i; if inp1 hasnt lockable { print_ret "I can't see how to unlock that."; } if inp1 hasnt locked { print_ret "It is in fact unlocked now."; } i=prop(inp1,with_key); if i~=inp2 { print_ret "That doesn't seem to fit the lock."; } clear_attr inp1 locked; if 1==PostAct() { ret#true; } print "You unlock the "; print_obj(inp1); print ".^"; ]; [ LockSub i; if inp1 hasnt lockable { print_ret "I can't see how to lock that."; } if inp1 has locked { print_ret "It is in fact locked now."; } if inp1 has open { print_ret "First you'll have to close it."; } i=prop(inp1,with_key); if i~=inp2 { print_ret "That doesn't seem to fit the lock."; } set_attr inp1 locked; if 1==PostAct() { ret#true; } print "You lock the "; print_obj(inp1); print ".^"; ]; [ SwitchonSub; if inp1 hasnt switchable { print_ret "That's not something you can switch."; } if inp1 has on { print_ret "It's already on."; } set_attr inp1 on; if 1==PostAct() { ret#true; } print "You switch the "; print_obj(inp1); print " on.^"; ]; [ SwitchoffSub; if inp1 hasnt switchable { print_ret "That's not something you can switch."; } if inp1 hasnt on { print_ret "It's already off."; } clear_attr inp1 on; if 1==PostAct() { ret#true; } print "You switch the "; print_obj(inp1); print " off.^"; ]; [ OpenSub; if inp1 hasnt openable { print_ret "That's not something you can open."; } if inp1 has locked { print_ret "It seems to be locked."; } if inp1 has open { print_ret "It's already open."; } set_attr inp1 open; if 1==PostAct() { ret#true; } print "You open the "; print_obj(inp1); print ".^"; ]; [ CloseSub; if inp1 hasnt openable { print_ret "That's not something you can close."; } if inp1 hasnt open { print_ret "It's already closed."; } clear_attr inp1 open; if 1==PostAct() { ret#true; } print "You close the "; print_obj(inp1); print ".^"; ]; [ DisrobeSub; if inp1 hasnt worn { print_ret "You're not wearing that."; } clear_attr inp1 worn; print "You take off the "; print_obj(inp1); print ".^"; ]; [ WearSub i; if inp1 hasnt clothing { print_ret "You can't wear that!"; } i=parent(inp1); if i~=player { print_ret "You're not holding that!"; } set_attr inp1 worn; if 1==PostAct() { ret#true; } print "You put on the "; print_obj(inp1); print ".^"; ]; [ RhetSub; print_ret "That was a rhetorical question."; ]; [ MagicWordSub; print_ret "For a moment you can almost hear a hoarse voice say something to you. But it passes."; ]; [ BurnSub; print_ret "In this game, arson is (usually) forbidden."; ]; [ PraySub; print_ret "Spooky! For a moment there, a deep voice seemed to say ~you're on your own~."; ]; [ WakeSub; print_ret "The dreadful truth is, this is not a dream."; ]; [ WakeOSub; print_ret "That seems unnecessary."; ]; [ KissSub; print_ret "Keep your mind on the game."; ]; [ ThinkSub; print_ret "Worth a try, anyway. Why don't you?"; ]; [ SmellSub; print_ret "You smell nothing unexpected."; ]; [ ListenSub; print_ret "You hear nothing unexpected."; ]; [ TasteSub; print_ret "You taste nothing unexpected."; ]; [ TouchSub; print_ret "You feel nothing unexpected."; ]; [ TouchTSub; if inp1 has animate { print_ret "Keep your hands to yourself!"; } print_ret "You feel nothing unexpected."; ]; [ DigSub; print_ret "The ground is unsuitable for digging here."; ]; [ CutSub; print_ret "In this game, cutting things up is never helpful."; ]; [ JumpsSub; print_ret "You jump on the spot, fruitlessly."; ]; [ JumpSub; print_ret "In this game, it is never useful to jump over things."; ]; [ TieSub; print_ret "In this game, it is never useful to tie things."; ]; [ DrinkSub; print_ret "There's nothing suitable to drink here."; ]; [ FillSub; print_ret "But there's no water here to carry."; ]; [ SorrySub; print_ret "Oh, don't apologise."; ]; [ StrongSub i; print_ret "Disgraceful! Once upon a time adventurers had moral standards."; ]; [ MildSub; print_ret "Quite."; ]; [ AttackSub; print_ret "Violence isn't the answer, you know."; ]; [ SwimSub; print_ret "There's not enough water to swim in."; ]; [ SwingSub; print_ret "There's nothing sensible to swing here."; ]; [ BlowSub; print_ret "You can't usefully blow that."; ]; [ RubSub; print_ret "You achieve nothing by this."; ]; [ SetSub i j; print_ret "No, you can't set that."; ]; [ EatSub; if inp1 hasnt edible { print_ret "No, it's plainly inedible."; } remove inp1; print "You eat the "; print_obj inp1; print_ret ". Not bad."; ]; [ WaveNSub; print_ret "You wave, feeling foolish."; ]; [ WaveSub i; i=parent(inp1); if i~=player { print_ret "But you aren't holding it."; } print "You look ridiculous waving the "; print_obj inp1; print_ret "."; ]; [ PullSub i j; if inp1 has static { print_ret "It is fixed in place."; } if inp1 has scenery { print_ret "You are unable to."; } print_ret "Nothing obvious happens."; ]; [ PushSub i; if inp1 has static { print_ret "It is fixed in place."; } if inp1 has scenery { print_ret "You are unable to."; } print_ret "Nothing obvious happens."; ]; [ PushDirSub i; i=parent(inp2); if i~=compass { print_ret "That's not a direction."; } if inp2==u_obj or d_obj { print_ret "Not that way you can't."; } print_ret "Sorry, nothin here to push."; ]; [ TurnSub; if inp1 has static { print_ret "It is fixed in place."; } if inp1 has scenery { print_ret "You are unable to."; } print_ret "Nothing obvious happens."; ]; [ SqueezeSub i; if inp1 has animate { print_ret "Keep your hands to yourself."; } print_ret "You achieve nothing by this."; ]; [ LookUnderSub i; print_ret "You find nothing of interest."; ]; [ SearchSub i j; if inp1 hasnt container { print_ret "You find nothing of interest."; } if inp1 has interior { if inp1 hasnt open { print_ret "You can't see inside, since it is closed."; } } if 1==PostAct() { ret#true; } print "You peer at "; DescribeObj(inp1,2); print_ret "."; ]; [ Indefart o; if o hasnt proper { print_paddr prop(o,article); print " "; } print_obj(o); ]; [ Defart o; if o hasnt proper { print "the "; } print_obj(o); ]; [ CDefart o; if o hasnt proper { print "The "; } print_obj(o); ]; [ ThrowAtSub i j; if inp2 hasnt animate { print_ret "Futile."; } print_ret "You lack the nerve when it comes to the crucial moment."; ]; [ AnswerSub i j c; print_ret "No reply."; ]; [ BuySub i; print_ret "Nothing is on sale."; ]; [ AskSub; print_ret "No reply."; ]; [ SingSub; if random(2)==1 { print "Your yodelling "; } else { print "Your singing "; } print_ret "is atrocious, if you say so yourself."; ]; [ ClimbSub; print_ret "I don't think much is to be achieved by that."; ]; [ WaitSub; print_ret "Time passes."; ]; [ EchoSub; print_ret "There isn't an echo here."; ]; [ SleepSub i j; print_ret "You must have slept yourself out. You certainly aren't drowsy now."; ]; [ HelpSub i; Banner(); DescribeObj(help); ret#true; ]; ! --------------------------------------------------------------------------------------------------- ! The Z-code part of the parser ! --------------------------------------------------------------------------------------------------- global wn; global nwords; global mmode; global mfilter; global allmode; global verbn; global pstack data 16; global pspare data 16; global pcount; global pcounts; global inferfrom; global inferword; global oops_from = 0; global e_oops = 0; global oops_heap data 16; global matchlist data 64; global match_p; global match_t; global match_w; global indef_mode; global wnbase; [ Keyboard b p nw i w x1 x2; .KAgain; for i 0 to 9 { put oops_heap byte i p->i; } new_line; print_char '>'; read b p; .KKAgain; nw=p->1; w=p-->1; if nw == 0 { print "I beg your pardon?^"; jump KAgain; } if w == oops_word { jump dooops; } if w ~= o_word { return nw; } .dooops; if oops_from == 0 { print "Sorry, that can't be corrected.^"; jump KAgain; } if nw == 1 { print "Think nothing of it.^"; jump KAgain; } if nw > 2 { print "~Oops~ can only correct a single word.^"; jump KAgain; } x1=p-->3; x2=p-->4; for i 0 to 9 { put p byte i oops_heap->i; } w=2*oops_from - 1; put p word w x1; inc w; put p word w x1; return nw; ]; [ Input ibuff parset cl clines pline i j k l m o etype amode allwn allk; .Retry; Keyboard(buffer,parse); .Retrynotk; nwords=parse->1; etype=1; wnbase=1; actor=player; .BeginComm; wn=wnbase; verbn = NextWord(); if verbn==g_word { verbn=again_word; } if verbn==again_word { ret#true; } if verbn==0 { etype=11; jump GiveError; } i=(verbn->4) & 1; if i==0 { wn=wnbase; l=NounDomain(compass,0,0); if l==1000 { jump Retrynotk; } if l~=0 { put ibuff byte 1 1; put ibuff byte 0 #a$GoSub; put ibuff byte 2 l; ret#true; } if actor==player { for j 2 to nwords { i=NextWord(); if i==comma_word { jump Converse; } } } etype=11; jump GiveError; .Converse; j=wn-1; k=6; if j==1 { print "You can't begin with a comma.^"; jump Retry; } wn=1; l=NounDomain(player,location,k); if l==1000 { jump RetryNotK; } if l==0 { print "You seem to want to talk to someone, but I can't see whom.^"; jump Retry; } if l has talkable { jump CTAA; } if l hasnt animate { print "You can't talk to "; DefArt(l); print ".^"; jump Retry; } .CTAA; if wn~=j { print "To talk to someone, try ~someone, hello~ or some such.^"; jump Retry; } wnbase=j+1; actor=l; jump BeginComm; } i=$ff-(verbn->5); parset=(0-->7)-->i; clines=(parset->0)-1; for cl 0 to clines; { wn=wnbase+1; pline=parset+1+cl*8; inferfrom=0; j=0; allmode=0; for pcount 1 to 6; { put pstack word pcount 0; k=pline->pcount; if k>7 { put pstack word pcount 1000+k; if wn > nwords { if inferfrom==0 { if j< pline->0 { inferfrom=pcount; inferword=k; } } if inferfrom==0 { break; } } if wn <= nwords { if k~=Adjective(parse) { break; } } jump Back; } if j == pline->0 { if wn < nwords+1 { for m 0 to 7 { put pspare word m pstack-->m; } pcounts=pcount; etype=2; break; } if allmode==1 { wn=allwn; k=allk; jump OList; } .AllDone; put ibuff byte 1 pline->0; put ibuff byte 0 pline->7; if j > 0 { itobj=ibuff->2; } oops_from = 0; ret#true; } mmode=0; amode=0; .OList; o=NextWord(); dec wn; if o==it_word { if itobj==0 { etype=8; break; } } if o==them_word { if itobj==0 { etype=8; break; } } indef_mode=0; if o==the_word { inc wn; jump OList; } if o==a_word { inc wn; indef_mode=1; } if o==an_word { inc wn; indef_mode=1; } if k==7 { special_number=TryNumber(wn); special_word=NextWord(); put ibuff byte j+2 $ff; j=j+1; put pstack word pcount $ff; jump KeepGoing; } mfilter=0; if o==everyt_word { o=all_word; } if o==both_word { o=all_word; } if o==all_word { if k<2 { etype=6; break; } if k>=6 { etype=6; break; } inc allmode; if allmode>2 { etype=7; break; } if allmode==2 { if k==5 { DoAll(ibuff->3); } if k==4 { DoAll(actor); o=parent(ibuff->3); if o==actor { MultiSub(ibuff->3); } } if k==2 { DoAll(location); } if k==3 { DoAll(actor); } if mfilter~=0 { MultiFilter(mfilter); } } if allmode==1 { allwn=wn; allk=k; DoAll(location); } inc wn; jump Exceptions; } oops_from=wn; if k~=1 { l=NounDomain(location, actor, k); if l==1000 { jump Retrynotk; } if l==0 { etype=3; e_oops=oops_from; break; } if k==6 { if l hasnt animate { etype=10; break; } } if amode==0 { put ibuff byte j+2 l; j=j+1; put pstack word pcount l; } if amode==1 { MultiAdd(l); } if amode==2 { m=MultiSub(l); if allmode~=1 { if m~=0 { etype=m; break; } } } } if k==1 { l=NounDomain(actor,location,k); if l==1000 { jump Retrynotk; } if l==0 { etype=3; e_oops=oops_from; break; } o=parent(l); if o~=actor { etype=5; e_oops=oops_from; break; } put ibuff byte j+2 l; j=j+1; put pstack word pcount l; } .KeepGoing; o=NextWord(); if 0~=Refers(l,o) { jump KeepGoing; } if o==comma_word { o=and_word; } if o==and_word { if k<2 { etype=6; break; } if k>=6 { etype=6; break; } if mmode==0 { put multinps byte 0 1; put multinps byte 1 l; j=j-1; mmode=1; } if amode==0 { amode=1; } jump Olist; } wn=wn-1; .Resume; if allmode==2 { jump AllDone; } if mmode==1 { put ibuff byte j+2 0; put pstack word pcount 0; j=j+1; } .Back; } } .GiveError; if actor~=player { special_number=TryNumber(wnbase); wn=wnbase; special_word=NextWord(); action=#a$AnswerSub; inp1=1; inp2=actor; actor=player; ret#true; } if etype==1 { print "I didn't understand that sentence.^"; oops_from=1; } if etype==2 { print "I only understood you as far as wanting to "; for m 0 to 7 { put pstack word m pspare-->m; } pcount=pcounts; Pcommand(0,1); print ".^"; } if etype==3 { print "You can't see any such thing.^"; oops_from=e_oops; } if etype==4 { print "You seem to have said too little!^"; } if etype==5 { print "You aren't holding that!^"; oops_from=e_oops; } if etype==6 { print "You can't use multiple objects with that verb.^"; } if etype==7 { print "You can only use multiple objects once on a line.^"; } if etype==8 { print "I'm not sure what 'it' refers to.^"; } if etype==9 { print "You excepted something not included anyway!^"; } if etype==10 { print "You can only do that to something animate.^"; } if etype==11 { print "That's not a verb I recognise.^"; } jump Retry; .Exceptions; o=NextWord(); if o==the_word { jump Exceptions; } if o==except_word { o=but_word; } if o==but_word { amode=2; jump Olist; } wn=wn-1; jump Resume; for i 1 to nwords { j=parse-->(2*i-1); if j==0 { print "unknown "; } if j~=0 { print_addr j; print_char ' '; } } new_line; ]; [ MultiAdd o i j; i=multinps->0; if i==16 { toomanyf=1; ret#true; } for j 1 to i { if o==multinps->j { ret#true; } } i=i+1; put multinps byte i o; put multinps byte 0 i; ]; [ MultiFilter attr i j o; .MFiltl; i=multinps->0; for j 1 to i { o=multinps->j; if o hasnt attr { MultiSub(o); jump Mfiltl; } } ]; [ MultiSub o i j k et; i=multinps->0; for j 1 to i { if o==multinps->j { for k j to i { put multinps byte k multinps->(k+1); } i=i-1; put multinps byte 0 i; et=0; return et; } } et=9; return et; ]; [ DoAll domain i; mmode=1; put multinps byte 0 0; domain=child(domain); while domain~=0 { if domain hasnt concealed { if domain hasnt worn { MultiAdd(domain); } } domain=sibling(domain); } ]; [ Adjudicate context i j k l m n; j=match_p-1; k=0; l=matchlist->0; for i 0 to j { n=matchlist->i; if n has concealed { jump NeverHaveIt; } m=parent(n); if context==1 { if m==actor { inc k; l=n; } } if context==3 { if m==actor { inc k; l=n; } } if context==4 { if m==actor { inc k; l=n; } } if context==5 { if m==actor { inc k; l=n; } } if context==6 { if n has animate { inc k; l=n; } } if context==0 { if m==location { inc k; l=n; } } if context==2 { if m==location { inc k; l=n; } } .NeverHaveIt; } if k==1 { return l; } if indef_mode==1 { return l; } ret#false; ]; [ NounDomain domain1 domain2 context i j k oldw a; match_t=0; match_p=0; match_w=wn; NounD(domain1); NounD(domain2); wn=match_w+match_t; if match_p==0 { inc wn; ret#false; } if match_w <= nwords { i=matchlist->0; if match_p==1 { return i; } } if match_p>1 { i=Adjudicate(context); } if i~=0 { if inferfrom==0 { inferfrom=pcount; } put pstack word pcount i; print "("; Pcommand(inferfrom,0); print ")^"; return i; } if match_w > nwords { jump Incomp; } print "Which do you mean, "; j=match_p-1; for i 0 to j { k=matchlist->i; Defart(k); if i1); if j==both_word { j=all_word; } if j==everyt_word { j=all_word; } if j==all_word { print "Sorry, that's beyond my abilities. Which one exactly?^"; jump Whichl; } j=j->4; if 0~=j&1 { Copy(buffer, buffer2); Copy(parse, parse2); k=1000; return k; } oldw=parse->1; put parse byte 1 a+oldw; k=oldw+a; while k>match_w { i=k-a; MoveWord(k, parse, i); dec k; } for k 1 to a { i=match_w+k-1; MoveWord(i, parse2, k); } k=1000; return k; .Incomp; print "What do you want "; if actor~=player { DefArt(actor); } print "to "; Pcommand(0,1); print "?^"; a=Keyboard(buffer2, parse2); j=(parse2-->1); j=j->4; if 0~=j&1 { Copy(buffer, buffer2); Copy(parse, parse2); k=1000; return k; } oldw=parse->1; if inferfrom==0 { for k 1 to a { i=match_w+k-1; MoveWord(i, parse2, k); } } if inferfrom~=0 { for k 1 to a { i=match_w+k; MoveWord(i, parse2, k); } put parse2 word 1 Adjadd(inferword); MoveWord(match_w, parse2, 1); inc a; } put parse byte 1 a+oldw; k=1000; return k; ]; [ Pcommand from emptyf i j k f m n; if from==0 { i=parse-->1; from=1; f=1; if i==#w$invent { print "take an inventory"; jump vprinted; } if i==#w$examine { print "examine"; jump vprinted; } if i==#w$discard { print "discard"; jump vprinted; } print_addr i; } .vprinted; j=pcount-emptyf; for k from to j { if f==1 { print_char ' '; } i=pstack-->k; if i==0 { print "those things"; jump eopcl; } if i==$ff { print "that"; jump eopcl; } if i<256 { Defart(i); } if i>=1000 { i=i-1000; print_addr Adjadd(i); } .eopcl; f=1; } ]; [ Adjadd i n m; m=#adjectives_table; while 1==1 { n=m-->1; if n==i { m=m-->0; return m; } m=m+4; } ]; [ MoveWord at1 b2 at2 x y; x=at1*2-1; y=at2*2-1; put parse word x b2-->y; inc x; inc y; put parse word x b2-->y; ]; [ NPutin obj thresh; if thresh < match_t { ret#true; } if thresh > match_t { match_t=thresh; match_p=0; } put matchlist byte match_p obj; inc match_p; ]; [ NounD domain i j k o matched thresh; if domain==location { i=NounD(compass); } domain=child(domain); while domain~=0 { if match_w > nwords { NPutin(domain,1); jump DontAccept; } wn=match_w; i=Noun(); if i==1 { if itobj==domain { NPutin(itobj,1); } } if 0 == Refers(domain, i) { jump DontAccept; } thresh=0; .KGL; inc thresh; o=NextWord(); if 0~=Refers(domain,o) { jump KGL; } NPutin(domain,thresh); .DontAccept; if domain has container { if domain has open { jump DoDown; } if domain has interior { jump DontDown; } .DoDown; k=child(domain); if k~=0 { k=NounD(domain); } .DontDown; } domain=sibling(domain); } ret#false; ]; [ Refers o w j k l m; k=prop_addr(o,1); l=(prop_len(k)/2)-1; for m 0 to l { j=k-->m; if w==j { ret#true; } } ret#false; ]; [ Noun ncount i j; ncount=0; i=NextWord(); if i==it_word { j=1; return j; } if i==them_word { j=1; return j; } if i==0 { ret#false; } j=i-->4; if j&128 == 0 { ret#false; } return i; ]; [ Adjective parse i j; j=NextWord(); if j==0 { ret#false; } i=j->4; if i&8 == 0 { ret#false; } return(j->5); ]; [ NextWord i j k; if wn > (parse->1) { wn=wn+1; ret#false; } i=wn*2-1; wn=wn+1; j=parse-->i; if j==0 { k=wn*4-3; i=buffer->(parse->k); if i==',' { j=comma_word; } } return j; ]; [ HitComma i j k l; l=wn-1; if l > (parse->1) { ret#false; } i=l*4; j=parse->i; k=parse->(i+1); k=k+j; print "Word "; print_num l; print " ends with "; .HCL; i=buffer->k; if i==' ' { inc k; jump HCL; } if i==',' { print "a comma^"; k=1; return k; } print "no comma^"; k=0; return k; ]; [ Trynumber w i j c num len mul tot d digit; i=w*4+1; j=parse->i; num=j+buffer; len=parse->(i-1); if len>=4 { mul=1000; } if len==3 { mul=100; } if len==2 { mul=10; } if len==1 { mul=1; } tot=0; c=0; len=len-1; for c 0 to len { digit=num->c; if digit=='0' { d=0; jump digok; } if digit=='1' { d=1; jump digok; } if digit=='2' { d=2; jump digok; } if digit=='3' { d=3; jump digok; } if digit=='4' { d=4; jump digok; } if digit=='5' { d=5; jump digok; } if digit=='6' { d=6; jump digok; } if digit=='7' { d=7; jump digok; } if digit=='8' { d=8; jump digok; } if digit=='9' { d=9; jump digok; } ret#false; .digok; tot=tot+mul*d; mul=mul/10; } return tot; ]; [ Empty buff i size; size=buff->0; for i 1 to size { put buff byte i 0; } ]; [ Copy bto bfrom i size; size=bto->0; for i 1 to size { put bto byte i bfrom->i; } ]; [ Dump buff i; print "Dump at "; HexOut(buff); new_line; for i 0 to 31 { HexOut(buff->i); print " "; } new_line; ]; [ HexOut i j; j=(i/$10)/$10; if j ~= 0; { ; HexDig(j/$10); HexDig(j); } ; HexDig(i/$10); HexDig(i); ]; [ HexDig i; i=i % $10; if i<$a { print_char i+'0'; return; } print_char i+'a'-10; ]; ! --------------------------------------------------------------------------------------------------- ! The grammar table ! --------------------------------------------------------------------------------------------------- Verb "take" "get" "pick" "lift" * "out" -> ExitSub * multi -> TakeSub * multiinside "from" noun -> RemoveSub * "in" noun -> EnterSub * "off" held -> DisrobeSub; Verb "stand" * -> ExitSub * "up" -> ExitSub; Verb "remove" "shed" * held -> DisrobeSub * multiinside "from" noun -> RemoveSub; Verb "wear" * held -> WearSub; Verb "put" * multiexcept "in" noun -> InsertSub * multiexcept "into" noun -> InsertSub * multiexcept "on" noun -> InsertSub * "on" held -> WearSub * "down" multiheld -> DropSub * multiheld "down" -> DropSub; Verb "insert" * multiexcept "in" noun -> InsertSub * multiexcept "into" noun -> InsertSub; Verb "empty" * noun -> EmptySub * noun "to" noun -> EmptyTSub * noun "into" noun -> EmptyTSub; Verb "transfer" * noun "to" noun -> TransferSub; Verb "drop" "throw" "discard" * multiheld -> DropSub * multiexcept "in" noun -> InsertSub * multiexcept "into" noun -> InsertSub * multiexcept "down" noun -> InsertSub * held "at" noun -> ThrowAtSub; Verb "give" "pay" "offer" "feed" * creature multiheld -> GiveSub * multiheld "to" creature -> GiveSub * "over" multiheld "to" creature -> GiveSub; Verb "go" "walk" "run" "leave" * -> VagueGoSub * noun -> GoSub * "through" noun -> EnterSub; Verb "inventory" "i" * -> InvSub; Verb "score" * -> ScoreSub; Verb "look" * -> LookSub * "at" noun -> ExamineSub * "inside" noun -> SearchSub * "in" noun -> SearchSub * "under" noun -> LookUnderSub * "through" noun -> SearchSub; Verb "open" "unwrap" "uncover" "undo" * noun -> OpenSub * noun "with" held -> UnlockSub; Verb "close" "shut" "cover" * noun -> CloseSub; Verb "enter" * noun -> EnterSub; Verb "exit" * -> ExitSub; Verb "examine" "x" "read" "watch" "descri" "check" * noun -> ExamineSub; Verb "q" "quit" "die" * -> QuitSub; Verb "restore" * -> RestoreSub; Verb "restart" * -> RestartSub; Verb "save" * -> SaveSub; Verb "script" * -> ScriptOnSub * "off" -> ScriptOffSub * "on" -> ScriptOnSub; Verb "noscript" * -> ScriptOffSub; Verb "yes" "y" * -> RhetSub; Verb "no" * -> RhetSub; Verb "sorry" * -> SorrySub; Verb "shit" "fuck" "damn" "sod" * -> StrongSub * special -> StrongSub; Verb "bother" "curses" "drat" "darn" * -> MildSub * special -> MildSub; Verb "search" * noun -> SearchSub; Verb "wave" * -> WaveNSub * noun -> WaveSub; Verb "set" * noun -> SetSub; Verb "pull" "drag" * noun -> PullSub; Verb "push" "move" "shift" "clear" "press" * noun -> PushSub * noun noun -> PushDirSub * noun "to" noun -> TransferSub; Verb "turn" "rotate" "twist" "unscrew" "screw" * noun -> TurnSub * noun "on" -> SwitchonSub * noun "off" -> SwitchoffSub; Verb "switch" * noun -> SwitchonSub * noun "on" -> SwitchonSub * noun "off" -> SwitchoffSub * "on" noun -> SwitchonSub * "off" noun -> SwitchoffSub; Verb "lock" * noun "with" held -> LockSub; Verb "unlock" * noun "with" held -> UnlockSub; Verb "attack" "break" "smash" "hit" "fight" "wreck" "crack" "destro" "murder" "kill" "tortur" * noun -> AttackSub; Verb "wait" "z" * -> WaitSub; Verb "answer" "say" "shout" "speak" * special "to" creature -> AnswerSub; Verb "ask" * creature "about" special -> AskSub; Verb "eat" * held -> EatSub; Verb "sleep" "nap" * -> SleepSub; Verb "peel" * noun -> TakeSub * "off" noun -> TakeSub; Verb "sing" * -> SingSub; Verb "climb" "scale" * noun -> ClimbSub; Verb "buy" "purchase" * special -> BuySub; Verb "squeeze" "squash" * noun -> SqueezeSub; Verb "swim" "dive" * -> SwimSub; Verb "swing" * noun -> SwingSub * "on" noun -> SwingSub; Verb "blow" * held -> BlowSub; Verb "pray" * -> PraySub; Verb "echo" * -> EchoSub; Verb "wake" "awake" "awaken" * -> WakeSub * "up" -> WakeSub * creature -> WakeOSub * "up" creature -> WakeOSub; Verb "kiss" "embrace" "hug" * creature -> KissSub; Verb "think" * -> ThinkSub; Verb "smell" "sniff" * -> SmellSub * noun -> SmellSub; Verb "hear" "listen" * -> ListenSub * noun -> ListenSub * "to" noun -> ListenSub; Verb "taste" * -> TasteSub; Verb "touch" "fondle" "feel" "grope" * -> TouchSub * noun -> TouchTSub; Verb "rub" "shine" "polish" * noun -> RubSub; Verb "tie" "attach" "fasten" "fix" * noun -> TieSub * noun "to" special -> TieSub; Verb "burn" "light" * noun -> BurnSub; Verb "drink" "swallow" "sip" * noun -> DrinkSub; Verb "fill" * noun -> FillSub; Verb "cut" "slice" "prune" "chop" * noun -> CutSub; Verb "jump" "skip" "hop" * -> JumpsSub * "over" noun -> JumpSub; Verb "xyzzy" "plugh" "plover" "blorple" * -> MagicWordSub; Verb "help" * -> HelpSub; ! --------------------------------------------------------------------------------------------------- end;