| !\--------------------------------------------------------------------------- | |
| Following is a fairly nifty telephone class for users of Hugo v.2.2 that | |
| will allow you to implement any number of telephones in a game without | |
| having to write a mountain of code for each one. I'm providing step-by-step | |
| instructions, but they're pretty brief. You may find everything difficult | |
| to understand at first. It's really not that difficult, considering what | |
| a bitch telephones can be to code, but the best thing would probably be to | |
| slap my code into a fresh SHELL.HUG file, change "emptyroom" to "apartment," | |
| take care of whatever other minor details need to be taken care of, and | |
| then compile and play around with the thing. You won't hear any actual | |
| conversations, of course, since you won't have written them yet, but you'll | |
| at least have some idea what kind of beast you're dealing with when it comes | |
| time to write them. Anyway, without further ado: | |
| The first thing you need to do is type in some new verb definitions particular | |
| to telephone usage: | |
| ---------------------------------------------------------------------------\! | |
| verb "dial", "call" | |
| * DoVague | |
| * object DoDial | |
| verb "answer" | |
| * DoVague | |
| * object DoAnswer | |
| verb "hang" | |
| * "up" DoHangup | |
| * "up" object DoHangup | |
| \!-------------------------------------------------------------------------- | |
| Then, before you forget, provide the default verbroutines corresponding to | |
| the verbs you just defined. (If you're new to Hugo, or don't already have | |
| some set place in your source where you like to put these, put 'em at the | |
| end). | |
| --------------------------------------------------------------------------\! | |
| routine DoAnswer | |
| { "Sure. Ok, buddy. Whatever." | |
| } | |
| routine DoDial | |
| { "You can't dial that." | |
| } | |
| routine DoHangup | |
| { if phone_obj in location : Perform(&DoHangup, phone_obj) | |
| elseif not object : "There's nothing here to hang up." | |
| else : "You can't hang that up." | |
| } | |
| !\-------------------------------------------------------------------------- | |
| Next, back up toward the beginning of your code, type or paste in the | |
| following new variables and attribute. (If you're not sure where to put | |
| these, put 'em right after the lines that link in the Hugo library.) | |
| Here's what these new critters are for: | |
| "someone_on_line" is a variable intended to be used as a true/false | |
| switch. In your own code, when you write your actual phone call events, | |
| you will want to set this switch to true to signify that someone is actually | |
| on the other end of the phone. If you fail to set this switch, when the | |
| player answers or picks up the phone, he will be told that there's no one | |
| there. Also, you will need to manually set it to false in the case where the | |
| player stays on the line throughout the entire conversation so that the | |
| other party finishes and hangs up first. In the case where the player hangs | |
| up in the middle of a conversation, my code sets it to false automatically. | |
| "phone_number" holds the object number of the phone number being dialed. | |
| I've implemented telephone numbers as actual game objects, since that's so | |
| much easier than trying to parse input strings of numbers and dashes. This | |
| method has its drawbacks, but all in all it's not so bad. More about this | |
| later. | |
| "phone_obj" holds the object number of the particular telephone being used. | |
| This is necessary because there is only one handset object, which must be | |
| passed around from phone to phone as needed. We'll see how to do this | |
| in a moment. | |
| Finally, "off_hook" means just what it says: it indicates whether the | |
| handset is currently on or off the telephone's hook. Generally speaking, | |
| unless you really start fiddling with the phone class code, it's not one you | |
| need to worry about. You will, however, want to check this attribute when | |
| you do your "ring" events, since phones that are off the hook shouldn't ring | |
| (and the call shouldn't come through at all). | |
| NOTE: It is not possible with this code for a player to walk away and leave | |
| a receiver off the hook. If a phone is not hung up (i.e. if it is off_hook), | |
| it's because the player is standing there holding it. | |
| ---------------------------------------------------------------------------/! | |
| global someone_on_line | |
| global phone_number | |
| global phone_obj | |
| attribute off_hook | |
| !\-------------------------------------------------------------------------- | |
| Ok. Remember how I just said you need to set "phone_obj" so that the | |
| handset object gets moved around properly? How you do this will depend | |
| upon your story. If you have more than one phone in a room, it'll be up | |
| to you to figure it out. However, if you're not going to have more than a | |
| single phone in any given room, put lines like the following in the main() | |
| routine, so that your phones are checked and handled every turn (you | |
| should end up with one "if" or "elseif" line for each location that has a | |
| phone in it, with phone_obj set to the phone that's in it): | |
| ---------------------------------------------------------------------------\! | |
| if location = apartment | |
| phone_obj = red_phone | |
| ! elseif location = airport | |
| ! phone_obj = white_phone | |
| ! etc... | |
| move hook to phone_obj ! don't change these three lines | |
| if receiver not in player | |
| move receiver to hook | |
| !\-------------------------------------------------------------------------- | |
| Wow. Now you get to see the actual class definition. Aren't you excited? | |
| ---------------------------------------------------------------------------\! | |
| class phone "telephone_class" | |
| { | |
| is open, platform | |
| nouns "telephone", "phone" | |
| article "a" | |
| long_desc { "It's just an ordinary telephone. "; | |
| if self is off_hook | |
| "The receiver is off the hook." | |
| else : "" | |
| } | |
| before { object DoAnswer { if self is off_hook | |
| "The phone is already off the hook." | |
| elseif not someone_on_line | |
| { self is off_hook | |
| move receiver to player | |
| receiver is not hidden | |
| "You pick up the phone, but there's no | |
| one on the line." | |
| } | |
| else | |
| { self is off_hook | |
| move receiver to player | |
| receiver is not hidden | |
| AnswerThePhone() | |
| } | |
| } | |
| object DoGet { if self is off_hook | |
| "The phone is already off the hook." | |
| elseif not someone_on_line | |
| { self is off_hook | |
| move receiver to player | |
| receiver is not hidden | |
| "You pick up the phone." | |
| } | |
| else | |
| Perform(&DoAnswer, self) | |
| } | |
| object DoListen { if self is not off_hook and someone_on_line | |
| "The phone is ringing." | |
| elseif self is not off_hook | |
| "The phone is silent." | |
| elseif someone_on_line | |
| "The other party is speaking to you." | |
| else | |
| "You hear a dial tone." | |
| } | |
| object DoHangup { if self is not off_hook | |
| "The phone is already hung up." | |
| else | |
| { self is not off_hook | |
| move receiver to hook | |
| receiver is hidden | |
| someone_on_line = false | |
| "You hang up the phone." | |
| } | |
| } | |
| object DoDial { if self is not off_hook | |
| "You'd better pick up the phone first." | |
| elseif someone_on_line | |
| "That would be rude." | |
| else | |
| { if phone_number = glorias_number ! AN EXAMPLE | |
| "You dial 555-1212." | |
| else | |
| "You dial randomly until an operator comes | |
| on the line telling you to cut it out." | |
| } | |
| } | |
| xobject DoPutIn { if object = receiver | |
| Perform(&DoPutIn, receiver, hook) | |
| else : return false | |
| } | |
| xobject DoGet { if object = receiver | |
| Perform(&DoGet, receiver, hook) | |
| else : return false | |
| } | |
| } | |
| } | |
| !\-------------------------------------------------------------------------- | |
| Next come the receiver and hook. Note that the receiver is of the attachable | |
| class. This will prevent the player from moving off to another location | |
| while he's holding it. He'll also get a nice little inventory description | |
| telling him that the receiver he's holding is attached to the telephone, | |
| which impresses the hell out of people from Estonia. | |
| ---------------------------------------------------------------------------\! | |
| attachable receiver "telephone receiver" | |
| { is hidden | |
| in_scope { if phone_obj in location : return player | |
| else : return 0 | |
| } | |
| nouns "receiver", "handset" | |
| article "a" | |
| attached_to { return phone_obj } | |
| attached_desc "attached to" | |
| long_desc { if phone_obj is not off_hook: "The receiver is on the hook." | |
| else : "The receiver is off the hook." | |
| } | |
| before { object DoGet { Perform(&DoGet, phone_obj) } | |
| object DoDrop, DoHangup { Perform(&DoHangup, phone_obj) } | |
| object DoListen { Perform(&DoListen, phone_obj) } | |
| } | |
| } | |
| scenery hook "phone hook" | |
| { is open, platform | |
| nouns "hook", "cradle" | |
| article "the" | |
| long_desc { if phone_obj is not off_hook: "There's a receiver on the hook." | |
| else : "The hook is empty." | |
| } | |
| before { xobject DoPutIn { if object = receiver | |
| Perform(&DoDrop, receiver) | |
| else : "You can't put that on the hook." | |
| } | |
| xobject DoGet { if object = receiver | |
| Perform(&DoGet, receiver) | |
| else : "That's not on the hook." | |
| } | |
| object DoPush { if phone_obj is off_hook | |
| { if someone_on_line | |
| { someone_on_line = false | |
| "You press the cradle, breaking the | |
| connection." | |
| } | |
| else : "You press the cradle." | |
| } | |
| else : "The receiver is in the way." | |
| } | |
| } | |
| } | |
| !\-------------------------------------------------------------------------- | |
| Finally, an actual telephone object which inherits from the phone class | |
| defined above. If you want sixteen phones in your game just make sixteen | |
| objects similar to this one and put 'em where you want 'em (remembering, | |
| of course, to do the necessary housekeeping in the main() routine for each | |
| one). | |
| ---------------------------------------------------------------------------\! | |
| phone red_phone "red telephone" | |
| { | |
| in apartment | |
| adjectives "red" | |
| short_desc { "A red telephone hangs beside your bed." } | |
| } | |
| !\-------------------------------------------------------------------------- | |
| The following has been broken out of the phone class before() | |
| routine for convenience's sake. If you go back up and look, it is simply | |
| called whenever a phone is successfully answered (i.e. when a phone is | |
| picked up and there's someone on the line). How you code up all your | |
| telephone conversations will depend upon the number and nature of them, so | |
| I can't give any detailed guidance here, but in any case it will be | |
| easier to keep track of everything if you don't try to do it in the | |
| before() routine. | |
| ---------------------------------------------------------------------------\! | |
| routine AnswerThePhone | |
| { "You answer the phone." | |
| } | |
| !\-------------------------------------------------------------------------- | |
| Lastly, phone numbers. Following is a rough example showing how to | |
| implement them as game objects. Again, if you're into pain, feel free to | |
| dump this approach and parse the input strings yourself. Oh? You're still | |
| here? Well, then, throw this little guy into your code, compile it, and | |
| run your game. Type "call <or dial> 555-1212 <or any of the other names>" | |
| and you'll see quickly enough what you need to do to make it fit your | |
| own story. | |
| Remember the "phone_number" variable I talked about before? Look at DoDial | |
| below and you'll see what it's good for. We want the phone to be checked | |
| first to see if it can be dialed, so we're going to call the phone class' | |
| DoDial routine where all that is done. But we also need to pass the phone | |
| number (object). The simplest, least confusing way to "pass" the number in | |
| this case is to use a global variable, and so that's the reason for | |
| "phone_number". This method also gives us access to the number (object) at | |
| any time we might need it in other routines, so all in all its not a bad | |
| use of a global. | |
| --------------------------------------------------------------------------\! | |
| object glorias_number "Gloria's number" | |
| { is known | |
| in_scope { return player } | |
| nouns "555-1212", "5551212", "number" | |
| adjectives "gloria's" | |
| before { object DoDial { phone_number = self | |
| Perform(&DoDial, phone_obj) | |
| } | |
| object DoLook { "Gloria's number is 555-1212." } | |
| object { "You can't do that with Gloria's phone number." } | |
| } | |
| } | |
| !\--------------------------------------------------------------------------- | |
| That's it! Enjoy! | |
| This document is provided as-is, with no warranty whatsoever express or | |
| implied, by Cardinal Teulbachs, Archbishop of Frith. It is also copyright | |
| (c) 1996. | |
| ---------------------------------------------------------------------------\! | |
Xet Storage Details
- Size:
- 14.8 kB
- Xet hash:
- 6934dff0157925b27e89cb5a26a548f6ef3771ff432569e25d1bec756578ff6d
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.