!\------------------------------------------------------------------------------------------------------------------ SCAVENGER HUNT - Version 0.1 Copyright (c) 2000-2002 by Gilles Duchesne Written using Hugo v3.0 This document is part of my "Scavenger Hunt" tutorial. It should be distributed as a package, along the following: SCAVHUNT1.HTM - Core & rooms (THIS FILE) SCAVHUNT2.HTM - Scenery objects SCAVHUNT3.HTM - Inventory objects SCAVHUNT4.HTM - NPCs SCAVHUNT5.HTM - Time & score SCAVHUNT6.HTM - Misc info, credits & hints SCAVHUNT7.HTM - Sounds & pictures The package, as a whole, can be redistributed freely. However, I'd appreciate it if the issues & mistakes would be reported to me rather than directly edited. Please contact me at lonecleric@bigfoot.com. If you think parts of this code could be reused for your own purposes, feel free to do so. ------------------------------------------------------------------------------------------------------------------\! !\Well, first of all, hi! I hope this set of "incremental" game code will help you familiarize yourself with the powerful and versatile IF programming language that is Hugo. First, I invite you to try playing the "final" version, either by compiling SCAVHUNT7.HTM or by getting a copy of "ScavHunt.hex", which should be available (along with the resource file ScavRes) on the IF Archive at ftp.gmd.de/int-fiction and/or at www.ifarchive.org. Once you've seen the final result, then you'll be in a better position to see the numerous steps involved in its creation. The game also contains credits and other info tidbits. Each of the HTML file can be compiled by converting it into a .HUG file. Simply use the "Save as" feature of your browser to convert the code into plain ASCII. Enjoy!\! !\DESIGN COMMENT: Scavenger Hunt, as its title implies, follows the age-old "treasure hunt" style of gaming. The goal of the player is to explore the environment, solving puzzles that will grant him access to more and more "treasures". The original "Adventure" followed such a pattern, as well as most of the ones written by Scott Adams. I wanted to point out, therefore, that although this might seem like a very neat idea at first, the premise has been pretty much worn out. Nowadays, players favor more story-oriented games. I started working on this lil' game of mine to learn Hugo, first and foremost, and not to win a Xyzzy Award. Keep that in mind. If you want to learn more about modern IF design in general, I strongly invite you to read "Chapter VII : The Craft of Adventure" in Graham Nelson's "Inform Designer Manual", 4th Edition.\! !Setting compilation flags allow you to easily pick which parts of a library are needed for your game, so that !the unneeded parts won't be compiled in your game file. !DEBUG indicates I want to produce a debugger-friendly file, while VERBSTUBS means I want to add the default !support for special actions like "burn", "kiss", "jump", "touch", "yell" and the like. NO_AUX_MATH, on the other !hand, states that I DON'T need the fancy-schmancy mathematical routines. #set DEBUG ! include HugoFix library and grammar #set VERBSTUBS ! include verb stub routines #set NO_AUX_MATH ! don't need advanced math routines !Here are some other flags which I ripped off from Kent's sample game. I didn't need them, however, so you can !kiss them goodbye. Look for them in OBJLIB.H !#set USE_VEHICLES !#set USE_PLURAL_OBJECTS !#set USE_ATTACHABLES #switches -ls ! print statistics to SAMPLE.LST #ifset DEBUG #switches -d #endif !This file contains the default "grammar". (The possible commands and their corresponding syntax.) !The grammar of the game must always be the first thing in the file, as its format differs from regular code. #include "verblib.g" ! normal verb grammar !---------------------------------------------------------------------------- !HUGOLIB.H defines several classes, attributes, properties and routines which most people need. #include "hugolib.h" ! standard library routines !This routine is called whenever the player starts (or restarts) a game. routine init { !The turn counter. We start the game 1 turn before turn 0. counter = -1 !Use the score/turn display in the status line. STATUSTYPE = 1 ! score/turns !Set the colors to the interpreter's defaults. You could, of course, set those to any colors of your choice. !However, as a side note, keep in mind that if you want to enforce a color, you need to enforce both !foreground & background, as default colors vary between 'terps. Also remember that those global variables !are used in several places in Hugolib, so any long-term color change should be recorded in those. TEXTCOLOR = DEF_FOREGROUND BGCOLOR = DEF_BACKGROUND SL_TEXTCOLOR = DEF_SL_FOREGROUND SL_BGCOLOR = DEF_SL_BACKGROUND color TEXTCOLOR, BGCOLOR !No indents whatsoever (doesn't fit my writing style) INDENT_SIZE = 0 prompt = ">" !Proportional (not fixed-width) font DEFAULT_FONT = PROP_ON Font(DEFAULT_FONT) !If the interpreter supports it, this will set the name of the game in the interpreter window display.title_caption = "Scavenger Hunt" !Clear the screen and print the intro cls "Here you are, visiting your best friend in his new house in Cheapsville. His nice, new, empty, tediously boring house in a charmingly boring suburban town.\nYour friend, who always liked games of all kind and doesn't say no to the occasional bet, has decided to set up a challenge for you...\n" "A scavenger hunt.\n" "Here's the idea: he gives you three hours to go around the neighborhood, trying to find all the miscellaneous things he's listed. You're supposed to bring all these items back to his house.\n" "\n\n" "\BScavenger Hunt\b" "A Small Visit in Cheapsville" "Version 0.1" print BANNER !Standard initialization (the only thing likely to change is the player & location objects.) player = you location = friendshome old_location = location move player to location ! initialize player location FindLight(location) ! whether the player can see DescribePlace(location) ! the appropriate description location is visited } !This method is called at the end of every "regular" turn. That is, the verb routine is processed, and assuming !everything goes right (i.e. it returns true), and then main is called to "wrap up the turn". !The HugoLib can also call on main if it decides to "spend one turn" doing stuff like opening a door before !letting you walk through it, taking some clothes before wearing them, etc. routine main { !All of this code was taken from SAMPLE.HUG - It's pretty much generic stuff counter = counter + 1 PrintStatusLine run location.each_turn RunEvents RunScripts if speaking not in location ! in case the character being spoken speaking = 0 ! to leaves } !The main character object. The player_character class, defined in OBJLIB.H, adequately defines what's required !for a typical player character. player_character you "you" {} !Since my game is strictly "2-dimensional", I decided to provide default responses to the "up" and "down" !commands. One easy to do so is to create a new "class" and make all the rooms "derive" from it. Likewise, !notice that I also "derive" that said class from the Hugolib's room class. !---------------------------------------------------------------------------- ! CL_ROOM CLASS ! Used to add generic answers to "up" and "down" !---------------------------------------------------------------------------- room cl_room { u_to { "Well, there aren't any stairs, elevators, or ladders, around, nor any wings on your back. You won't be able to go up." } d_to { "You can't go much lower than this." } } !Now here comes the first real room description. As I just mentioned, this room is "derived" from my cl_room !class, which basically means that it "borrows" any property and attribute from it, unless you explicitely replace !one. !---------------------------------------------------------------------------- ! FRIEND'S HOME !---------------------------------------------------------------------------- cl_room friendshome "At your friend's house" { long_desc { "Your good friend had just begun moving into this fine, empty house. The main center of attention is still the desk, which tells a lot about how much still has to be moved. That won't be until the afternoon, however. Because of that, a puerile game of scavenger hunt seems like a good idea. \nThe main door leads to the east, but there's also a back door to the north, leading to the neighbor's backyard. \nA work desk has been placed in one corner. The immediate area also has a closet." } n_to backyard e_to oakstreet out_to oakstreet cant_go { "Unless you smashed a hole in the wall (which wouldn't be very considerate) you can't go that way." } } !---------------------------------------------------------------------------- ! NEIGHBOR'S YARD !---------------------------------------------------------------------------- cl_room backyard "Some neighbor's back yard" { long_desc { "This back yard doesn't actually belong to your friend, even if there's a door leading to it. It's owned by some neighbor he hasn't even met yet. Both houses stand side by side, one to the north, the other to the south. \nYou notice a doghouse standing alongside one of the fences which surround most of the area." } s_to friendshome in_to friendshome se_to oakstreet n_to { "And just how do you plan to introduce yourself? \n\I\"Oh, hi there, I'm a friend of that new neighbor you haven't met, please don't mind me while I rummage through your belongings!\"\i \nUnlikely." } cant_go { "Several fences, which you hear make good neighbors, surround this area. The only passage through them is to the southeast." } } !---------------------------------------------------------------------------- ! STREET, NEAR HOUSE !---------------------------------------------------------------------------- cl_room oakstreet "Oak Street, near the house" { long_desc { "You're now standing on the sidewalk of Oak Street. It's a quiet little street, much like every quiet little street you've seen in Cheapsville. Cars pass every few minutes, thrusting dust into the air. There's no one around; only a streetlight and a garbage bin are here to keep you company. \nThe street leads north toward a city park, and south to an intersection. You friend's new house stands to the west." } w_to friendshome in_to friendshome nw_to backyard n_to park s_to intersection cant_go { "You don't see anything worthwhile in that direction, and your time is precious." } !Here's my first "before" statement. Basically, any attempt by the player to use "smell" in this !particular location will be catched in here. before { location DoSmell { "The only thing which gets your nose's attention is the slight stench coming from the garbage bin." } } } !---------------------------------------------------------------------------- ! CITY PARK !---------------------------------------------------------------------------- cl_room park "Cheapsville City Park" { long_desc { "The soft grass of what seems to be the only city park in Cheapsville welcome you. It seems nice enough, with trees, benches, and the usual elements of a park. However, since the weather today isn't that great (the sky is completely grey), the only human being around seems to be that poor sap operating the hot dog stand. \nTo the south, Oak Street reminds you that suburban civilization is only a few steps away." } s_to oakstreet cant_go { "A stroll in the park could be nice, but you still intend to win that little bet." } before { location DoSmell { "Hmmm... Hot dogs..." } } } !---------------------------------------------------------------------------- ! INTERSECTION !---------------------------------------------------------------------------- cl_room intersection "Intersection of Oak & Main" { long_desc { "Oak Street ends here, reaching Cheapsville's Main Street. Even though it's Monday, the whole place remains pretty calm. You can see why your friend picked this town - you can't get any quieter without living on a farm. \nThe most interesting building in the area is the Cheapsville City Bank, which stands proudly on the opposite side of Oak. \nMain Street runs east-west. You can also go north, back on Oak Street." } n_to oakstreet s_to citybank in_to citybank w_to schoolyard e_to outsidelibrary cant_go { "There doesn't seem to be anything interesting in that direction." } } !---------------------------------------------------------------------------- ! BANK !---------------------------------------------------------------------------- cl_room citybank "Cheapsville City Bank" { long_desc { "Whoa! It's been ages since you saw an actual city bank. And apparently, today isn't your lucky day to see one: at this hour, they're closed. The windows are, anyway. And by the time they open, your little wager will be long over. \nOn one side of the open area is an ATM. On the other is the receptionist's desk, complete with receptionist." } n_to intersection out_to intersection cant_go { "Most of the bank is closed at this hour, and therefore you can't go there." } } !---------------------------------------------------------------------------- ! SCHOOLYARD !---------------------------------------------------------------------------- cl_room schoolyard "School yard" { long_desc { "Oh look, an elementary school! Isn't that nice? It means your friend's got quite a good location to raise a family.\n Bunches of kids are playing and laughing all around the school yard. Either it's recess, or they're having some special \"go play outside morning\".\n The school stands to the south, while Main Street extends both eastward & westward." } e_to intersection w_to { "You take a quick peek in that direction. There doesn't seem to be a lot of buildings, for a while at least. It might be better to stick to this part of town instead." } s_to { "Going inside the school? Well, you're a little too old to pass incognito, and you don't really want to scare anyone." } !Another trick - reusing the behavior of another property. in_to { return s_to } cant_go { "There doesn't seem to be anything interesting in that direction." } } !---------------------------------------------------------------------------- ! STREET, OUTSIDE LIBRARY !---------------------------------------------------------------------------- cl_room outsidelibrary "Main Street, Outside Public Library" { long_desc { "Main Street extends east and west from here. Aside from a few houses, the only building in the area is the public library, which lies on the north side of the street." } w_to intersection e_to outsidebowling n_to publiclibrary in_to publiclibrary cant_go { "There doesn't seem to be anything interesting in that direction." } } !---------------------------------------------------------------------------- ! PUBLIC LIBRARY !---------------------------------------------------------------------------- cl_room publiclibrary "Public Library" { long_desc { "This isn't the largest library you've seen, of course. But it seems well furnished enough: novels, kids' books, biographies, dictionaries, encyclopedias, and other sorts of library materials. \nThe door leading outside is to the south. Near it is the librarian, sitting at her desk." } s_to outsidelibrary out_to outsidelibrary cant_go { "There isn't a way out in that direction." } before { location DoSmell { "The sweet aroma of old paper fills the building." } } } !---------------------------------------------------------------------------- ! STREET, OUTSIDE BOWLING ALLEY !---------------------------------------------------------------------------- cl_room outsidebowling "Main Street, Outside Bowling Alley" { long_desc { "Ah, finally! After all the niceness and cozyness of this little town, you've found a clear sign of modern corruption: the bowling alley. And it's already open, lucky you! The entrance stands to your south. You can also escape this place by following Main Street." } s_to bowlingalley in_to bowlingalley w_to outsidelibrary e_to { "You take a quick peek in that direction. There doesn't seem to be a lot of buildings, for a while at least. It might be better to stick to this part of town instead." } cant_go { "There doesn't seem to be anything interesting in that direction." } } !---------------------------------------------------------------------------- ! BOWLING ALLEY !---------------------------------------------------------------------------- cl_room bowlingalley "Bowling Alley" { long_desc { "This place might be open, but it's fairly empty at this time of the day. A few enthusiastic bowlers are practicing for their next tournament, and that's about it.\n Your sharp eyes do notice something interesting, though: a door marked \"STORAGE - EMPLOYEES ONLY\", slightly ajar." } n_to outsidebowling out_to outsidebowling in_to storageroom cant_go { "There isn't a way out in that direction." } } !\DESIGN COMMENT: You might have noticed that "in" is the only way to reach the storage room. I wanted to do that as a demonstration that you don't HAVE to use cardinal directions. However, veteran players are likely to find that weird. After all, that darn door's gotta be somewhere, right?\! !---------------------------------------------------------------------------- ! STORAGE ROOM !---------------------------------------------------------------------------- cl_room storageroom "Storage Room" { long_desc { "This storage room would be spacy, if it wasn't completely filled with boxes and boxes of now-useless stuff. Only a few narrows paths allow you to walk across the room.\n Something in the corner of the room catches your eye almost immediately: an old IBM XT, sitting in all its glory on a dusty table." } out_to bowlingalley cant_go { "The room isn't \Uthat\u big. If you want to exit, just say so." } }