Global GuideActive = true; Object GuideContext with count 0, brief_look_count 0, blank_line_count 0, unknown_verb_count 0, unknown_verb_ever false, just_undid false; Constant GUIDE_QUEUE_SIZE 10; Array GuideArray --> GUIDE_QUEUE_SIZE; [ GuideEnqueue obj ix; for (ix=0 : ixix) return; ! This message is already queued. } if (GuideContext.count >= GUIDE_QUEUE_SIZE) { "[BUG] too many guide references"; } GuideArray-->(GuideContext.count) = obj; GuideContext.count++; ]; [ GuideAnyQueued; return GuideContext.count; ]; [ GuideBeforePrompt ix obj; if (GuideContext.count == 0) return; for (ix=0 : ixix; GuidePrint(obj); } GuideContext.count = 0; ]; [ GuidePrint obj force; if (obj == nothing) return; if ((~~GuideActive) && (~~force)) return; style underline; global_italic = true; print "^["; switch (metaclass(obj)) { String: print (string) obj; Routine: obj(); Object: PrintOrRun(obj, description); default: print "[BUG] unknown guide reference"; } print "]"; style roman; global_italic = false; new_line; ]; [ GuideInvokeOnce; ! uses "self"; use as a property value if (self has general) return; give self general; GuideEnqueue(self); ]; [ GuideSeedMessage; ! used on the first turn, for unknown verbs, and for blank lines if (BasementHall hasnt general) { print "Don't know how to get started?"; } else { print "Don't know what to do?"; } print " Type ", (helpcmd) "help"; if (Hall3 hasnt visited) print " and then hit enter."; else print ". If you're trying to find the right word to make something happen, try ", (helptopic) "commands", "."; ]; [ GuideLeaveCellMessage; print "This cell isn't very exciting. You can stay if you want... but life is probably more interesting outside.^^ Have you looked around for an exit? Type ", (helpcmd) "look", "."; ]; [ GuideLeaveCell1Message; print "Notice the gap in the wall. You can take a closer look by typing ", (helpcmd) "examine gap", "."; ]; [ GuideLeaveCell2Message; print "Notice the gap in the wall. You can take a closer look by typing ", (helpcmd) "examine gap", "."; ]; [ GuideLeaveCell3Message; print "To crawl into the narrow gap, type ", (helpcmd) "enter gap", " or ", (helpcmd) "go through gap", ". Typing ", (helpcmd) "east", " will also work. (So will just ", (helpcmd) "e", ". Compass-direction commands can be abbreviated that way.)^^ For more information about basic IF commands, type ", (helptopic) "basics", "."; ]; [ GuideWelcomeMessage; print "Looks like you've taken the first step. Well done.^^ Let me introduce myself. I am the Voice of this tutorial. Most games don't have me; but in ", (emph) "this", " game, I will watch over your shoulder and give you some help. With a little practice, you'll soon be moving around the text adventure world in style.^^ Back to the story. Remember what's going on? Actually, you don't. As the introduction said, you can't remember who you are or what you're doing here!^^ Amnesia. Yes, it's a clich@'e, but it'll do for a tutorial.^^ I'll let you go on exploring. The west corridor leads back to the cell where you started, so you'll want to try up the stairs instead. Type ", (helpcmd) "up", " or ", (helpcmd) "climb stairs", "."; ]; Object GuideVerboseMessage with description [; give self general; print "The first time you enter a room, you'll see a detailed description. But if you ", (emph) "return", " to a room, you see just the room name, followed by a list of the more portable objects lying around.^^"; print "You can type ", (helpcmd) "look", " or ", (helpcmd) "l", " at any time to see the full description. But if you get tired of that, try the ", (helpcmd) "verbose", " command. In ", (helpcmd) "verbose", " mode, the game will give a detailed description of each room as you enter it -- every time you move."; ], has ~general; Object GuideBriefLookMessage with evoke [; self.number = 1; ], invoke [; if (self has general) return; if (self.number) { self.count++; self.number = 0; } if (self.count < 4) return; if (GuideAnyQueued()) return; give self general; GuideEnqueue(self); ], number 0, count 0, description [; print "If you get tired of typing ", (helpcmd) "look", " or ", (helpcmd) "l", " every time you return to a room, you can try the ", (helpcmd) "verbose", " command. In ", (helpcmd) "verbose", " mode, the game will give a detailed description of each room as you enter it -- every time you move."; ], has ~general; [ GuideInviteInvMessage; print "Time to test some of these commands. You're not sure where you are, but it can't hurt to take stock of yourself. Try typing ", (helpcmd) "i", " -- that will show what you're carrying."; ]; [ GuideFirstInvMessage ix; ix = children(player); if (ix == 1) print "You're carrying something unusual -- well, it's hard to say if it's unusual or not, just yet"; else print "You're carrying ", (EnglishNumber) ix, " things. You just picked up ", (EnglishNumber) ix-1, " of them, but you must have been holding ", (the) quill, " when you awoke. It may be important"; print ". Type ", (helpcmd) "examine the pen", " to take a close look at it.^^ Or just ", (helpcmd) "x pen", " will work. ~Examine~ can be abbreviated to one letter, and you can always leave out nonessential words like ~a~, ~an~, and ~the~."; ]; [ GuideRoomSceneryObject; print "In most games, there isn't any need to refer to the room as a whole. If you just want to look around, type ", (helpcmd) "look", ". Otherwise, refer to particular objects that you see."; ]; [ GuideVagueGoMessage; print "If you want help in moving around, type ", (helptopic) "moving", "."; ]; Object GuideTakingMessage with invoke [ obj; if (Hall3 has visited) return; if (obj == self.number) return; if (obj hasnt moved) { self.number = obj; GuideEnqueue(self); } ], number 0, description [; print "To pick up what you have discovered, type "; if (self.number == whitemask) print (helpcmd) "take mask"; else print (helpcmd) "take key"; print ".^^Remember, you can list what you're carrying by typing ", (helpcmd) "i", ". For more about picking up and dropping things, type ", (helptopic) "take", "."; ]; [ GuidePutKeyInObject; print "It does make sense to say ", (helpcmd) "put key in keyhole", ", but it's more common to type ", (helpcmd) "unlock door with key", ". More games will accept the latter."; ]; Array GuideSearchStudyList table desk book studydoor studytrunk cabinet cabinetstuff studyanimals studyplants studyinstruments studybooks studycandles clutter; Object GuideSearchStudyObject with description [ num ix; num = GuideSearchStudyList-->0; ix = self.count(); self.helpmode = ix; print "You've been here before, but it's a particularly crowded room. And examining your surroundings -- in detail -- is a valuable skill in IF. Not everything you see will be needed to solve the game... but anything may give you a clue, or a detail, or an insight. Or simply a better sense of where you are!^^ There are at least ", (EnglishNumber) num, " things (or groups of things) around here which are worth a look. You"; if (ix == 0) print " haven't examined any"; else print "'ve examined ", (EnglishNumber) ix; print " of them. Try ", (helpcmd) "look", " (or ", (helpcmd) "l", ") to survey the room; then ", (helpcmdobj) "examine", " (or ", (helpcmdobj) "x", ") on anything that catches your attention."; ], helpmode -1, count [ num total ix; num = GuideSearchStudyList-->0; total = 0; for (ix=1 : ix<=num : ix++) { if ((GuideSearchStudyList-->ix) has helpflag) total++; } return total; ]; [ GuideSearchStudySomeMessage ix num jx obj; ix = GuideSearchStudyObject.count(); num = GuideSearchStudyList-->0; GuideSearchStudyObject.helpmode = ix; print "That's at least ", (EnglishNumber) ix, " things in this room you've examined."; if (num-ix <= 3) { print " (Namely"; for (jx=1 : jx<=num : jx++) { obj = (GuideSearchStudyList-->jx); if (obj has helpflag) print ", ", (the) obj; } print ".)"; } jx = (num-ix); print " There"; if (jx == 1) print " is one"; else print " are ", (EnglishNumber) (num-ix); print " more worth a glance."; ]; [ GuideSearchStudyDoneMessage; GuideSearchStudyObject.helpmode = -1; print "Good, good. That's just about everything in this room which is worth examining.^^ Now, don't feel you have to obsessively ", (helpcmd) "examine", " every word you see in every room. A lot of stuff is just scenery. (For example, the plants, animals, instruments, and candles here aren't very important.) In a well-written game, you'll have a good idea what's important and what's merely decorative.^^ On the other hand, you ", (emph) "have", " discovered several items of interest. (That brass trunk, for example"; if (studytrunk hasnt general) print ". Why didn't you open it? It isn't locked.)"; else print " -- the key inside will certainly be useful.)"; print " Keep in mind what you've found. If you need to refresh your memory about anything, you can always ", (helpcmd) "examine", " again."; ]; Object GuideOpeningTrunkMessage with invoke [; if (hallkey has moved || studytrunk has open) return; if (GuideAnyQueued()) return; self.number++; if (self.number >= 2) { self.number = 0; GuideEnqueue(self); } ], number 0, description [; if (studytrunk has general) print "You've opened and closed the trunk, but you never picked up the key that you found inside. Keys are always useful somewhere, so you probably want to open the trunk again and grab this one."; else print "If you're curious what's inside the trunk -- and an adventurer is always curious -- you can open it. Try typing ", (helpcmd) "open trunk", "."; ]; Object GuideLockedDoorsMessage with invoke [ obj; if (Hall3 has visited) return; if (obj hasnt locked) return; if (self.helpmode ~= obj) { self.helpmode = obj; self.count = 0; } self.count++; if (self.count == 3) { self.count = 1; GuideEnqueue(self); } ], count 0, helpmode nothing, description [; if (~~(SittingRoom has visited && Study has visited && MirrorRoom has visited)) { print "This door seems to be locked. Maybe you should look around a bit more, and come back to tackle the door later. It's always good to become familiar with what's easy to reach, before you begin struggling with the difficulties."; } else if (studytrunk hasnt general) { print "This door seems to be locked. There's probably a key lying around somewhere... perhaps not in plain sight. Take another look around, and don't fear to be thorough."; } else if (hallkey hasnt moved) { print "This door seems to be locked. Didn't you see a key inside that brass trunk you opened?"; } else if (hallkey notin player) { print "This door seems to be locked. Didn't you leave a key lying around here somewhere?"; } else { print "This door seems to be locked, but you have found a key. Type ", (helpcmd) "unlock door with key", " to try it out."; } ]; Object GuideLockedWrongKeyMessage with invoke [ obj; if (Hall3 has visited) return; if (sittingdoor hasnt locked) return; if (self.helpmode ~= obj) { self.helpmode = obj; self.count = 0; } self.count++; if (self.count == 1) { GuideEnqueue(self); } ], count 0, helpmode nothing, description [; if (~~(SittingRoom has visited && Study has visited && MirrorRoom has visited)) { print "The key doesn't match this door. But have you explored everywhere yet? There may be another door elsewhere which this key unlocks."; } else { print "The key doesn't match this door. But there are two other locked doors nearby."; } ]; [ GuideUpStandUpMessage; print "The ", (helpcmd) "up", " command generally means to travel upward -- to climb a ladder or a flight of stairs. To get up from a chair, type ", (helpcmd) "stand", " or ", (helpcmd) "get up", "."; ]; Object GuideWalkedIntoDarkMessage with invoke GuideInvokeOnce, description [; print "Oh, dear. You've walked into a very dark place.^^"; if (torch in player) { print "(Yes, you were carrying a torch. Unfortunately you forgot to light it, so it isn't going to help much"; if (warmberries in player) print " -- unless you can light it right now, in the dark"; print ".)^^"; } print "Going ", (helpcmd) "south", " probably won't get you back; you can't tell directions in the dark. So what now? One option is to type ", (helpcmd) "undo", ". This will let you ~back up~ one move -- back to just before you walked in here. Everything will be the same, except that you'll be in the Natural Passage, and you'll be able to see.^^ In this game, you can only ", (helpcmd) "undo", " one move in a row. So if you do something else now (even ", (helpcmd) "look", " or ", (helpcmd) "south", "), you won't be able to jump back to the lit Passage. The ", (helpcmd) "undo", " command is intended only to fix immediate mistakes.^^ If you want to go back more than one turn, you'll have to use the ", (helpcmd) "restart", " or ", (helpcmd) "restore", " commands. Type ", (helptopic) "saving", " for more information.^^ Or you could stumble around in the dark, and try to find your way out. Since this is an introductory game, there ", (emph) "is", " a way out. And maybe more to discover, as well."; ], has ~general; [ GuideOpenedCageMessage; print "You may have made a mistake. You're not likely to get that apple back. (One never knows, of course, but that decay looked very final.) What can you do about it?^^ One option is to type ", (helpcmd) "undo", ". This will let you ~back up~ one move -- back to just before you opened the cage. Everything will be the same, except that the cage will still be closed and the apple will still be fresh.^^ In this game, you can only ", (helpcmd) "undo", " one move in a row. So if you do something else now (even ", (helpcmd) "look", " or ", (helpcmd) "examine apple", "), you won't be able to jump back to before the cage opened. The ", (helpcmd) "undo", " command is intended only to fix immediate mistakes.^^ If you want to go back more than one turn, you'll have to use the ", (helpcmd) "restart", " or ", (helpcmd) "restore", " commands. Type ", (helptopic) "saving", " for more information.^^ (Actually, many games protect you from severe mistakes. Since this is an introductory game, you don't really have to worry about accidentally running into a dead end. If you truly need a fresh apple, you'll probably find another way to get one.)"; ]; [ GuideOpenedCageUndoMessage; print "Go ahead, play with your food..."; ]; [ GuideFellInPitMessage; print "Oh, dear. You've gotten yourself killed.^^ I admit that was a very sudden death... perhaps even an unfair death. All you did was"; if (location ~= CavePit3) print " try to climb down a pit. A tricky, vertical pit. A vertical pit with slippery walls"; else print " climb down a pit. A tricky, vertical pit. A vertical pit with slippery walls, getting more slippery by the second. Where you hung out, waiting to get tired"; print "... Okay, let's just admit that neither of us is entirely blameless. But this ", (emph) "is", " a tutorial adventure; and everyone has to discover death, sooner or later.^^ Fortunately, you don't have to start the entire game over. You can take back your last move by typing ", (helpcmd) "undo", ". That will let you ~back up~ one move -- back to just before your fatal slip. You'll still be clinging to the pit wall, and you can try something safer for your next move. Like climbing ", (emph) "up", ".^^ If you ", (emph) "want", " to start the entire game over, you can -- type ", (helpcmd) "restart", ". You could also ", (helpcmd) "restore", " a save file you saved earlier. Or, if you find death discouraging, you could ", (helpcmd) "quit", " -- but I don't think that's necessary. You have much yet to discover."; ]; Object GuideDisambiguationMessage with invoke [ i marker; if (self hasnt general) { give self general; marker = 0; i = 1; while (((match_classes-->marker) ~= i) && ((match_classes-->marker) ~= -i)) marker++; self.number = match_list-->marker; GuideEnqueue(self); } ], number 0, description [; print "You typed a command which could refer to more than one object. The game is asking you to specify which you mean. You can type the name of one of these objects -- ", (helpcmd) self.number, ", for example -- and the game will execute your command correctly.^^ (You can type just part of the name. A single word will usually suffice, if it picks out exactly one option.)^^ You could also change your mind and type an entirely new command."; ], has ~general; Object GuideUnlimitedInventoryMessage with invoke [; if (self hasnt general) { give self general; GuideEnqueue(self); } ], description [; print "You're carrying quite a lot of stuff"; if (coolberries in player && warmberries in player) print " -- including two handfuls of berries"; print ". You might be wondering how you can juggle it all. Some games limit the number of things you can carry, or provide you with some kind of sack to carry your loot around in.^^ However, many games -- including this one -- simply ignore the problem. Packing your luggage, or stowing it in some central location, isn't all that much fun. Therefore, the game lets you carry around as much as you want."; ], has ~general; [ GuideIWantAmMessage; print "It's not helpful to enter declarations about yourself, like ~I want...~ or ~I am...~. The game doesn't know how to react to such announcements. Instead, enter simple commands, like ", (helpcmd) "take key", " or ", (helpcmd) "open door", ".^^ To learn about the kinds of commands you can use, type ", (helpcmd) "help", ". If you're just not sure what to try, type ", (helptopic) "strategy", "."; ]; [ GuideQuestionsMessage; print "It's not helpful to enter questions like ~What is...~ or ~Who am I?~ You are alone; there is no-one nearby to answer such questions. Instead, enter simple commands, like ", (helpcmd) "look", " or ", (helpcmd) "climb stairs", ".^^ To learn about the kinds of commands you can use, type ", (helpcmd) "help", ". If you're just not sure what to try, type ", (helptopic) "strategy", "."; ]; [ GuideIGiveUpMessage; print "What, you give up? Oh, don't. If you want help on how to play IF, type ", (helpcmd) "help", ". If you're just not sure what to try, type ", (helptopic) "strategy", ".^^ If you really do want to stop playing (and shut down the game), type ", (helpcmd) "quit", ". But you might want to ", (helpcmd) "save", " your progress first!"; ]; [ GuideUseMessage; print "There is no ~use~ command in most text adventures. (If there was, what would be the point in providing any other commands?) Instead, try a command which is appropriate to whatever you're doing. If you have a key, try ", (helpcmd) "unlock", " something. If you have a book, try to ", (helpcmd) "read", " it. If you find a lever, try to ", (helpcmd) "pull", " or ", (helpcmd) "push", " it."; ];