phone.t -- a TADS module for implementing telephones by Amir Karger (karger@post.harvard.edu) Last check-in: $Date: 1999/12/26 23:27:02 $ ******************** Pre-Introduction ******************** Feel free to copy and use this module. I would be happier if you would make changes by using modify or replace within your files rather than changing phont.t. I would be even happier if you let me know about it, so that I could make the module better and rerelease it. If you must make changes, please mark them as such, for clarity's sake. In other words, it's public domain, but please play nice. Note: This module is alpha, which means the docs are alpha squared. ******************** Introduction ******************** phone.t is a module for creating and using telephones in TADS. This module requires Suzanne Britton's chatter.t. If you're implementing a phone, it makes sense to use more sophisticated talking techniques than are standard in TADS. phone.t needs TADS 2.5.1 or higher. The mini-game test.t has some phones in it. test.scr is a test input script, and test.out is the corresponding output. In this doc, "caller" and "receiver" will be used to describe an actor (e.g., Me) who calls another actor. ******************** Game Play ******************** There are three ways to call someone. You can dial a number (DIAL 333) or a string (DIAL "555-1212"). If you know their phone number, you can dial an actor by name (DIAL JOE). Note that TADS can only handle integers up to 2147483647, which means 18005551212 will (silently!) fail. In that case, you can use a string. If you call someone on the phone, then you can speak to them as if they were in the same room. That is, you can use ASK, TELL, HELLO, and SAY. You can also use the new verbs added by chatter.t, like GOODBYE, APOLOGIZE, and YES and NO. But something like "show book to Joe" will still yield "I see no joe here." If the phone rings, you can pick it up with GET THE PHONE or ANSWER THE PHONE. At the end of the conversation, HANG UP. ******************** Global Variables ******************** The function init_phone creates global.actorList, which is just a list of the actors in the game. That way, you can say CALL MARY without getting a "I don't see any mary here" error. ******************** New verbs ******************** The verbs "answer" and "hang up" have been added. Answer will answer the phone when it's ringing. Hang up will hang up the phone when you're using it (whether or not you're currently talking to someone on it.) takeVerb and dropVerb have (hopefully) been modified correctly so that PICK UP PHONE and PUT DOWN PHONE will do what you expect. At least in theory, the verbs work for NPCs, so you can have an NPC pick up the phone, or hang up the phone if the PC gets them angry, say. ******************** Coding with phone.t ******************** The basic things you'll need to do to use phone.t are: - call init_phone from your init function - define some fixed_phone or mobile_phone objects. See the Classes section below) - set a few properties like (phone and Actor) phone_number, and actors' phone_hello properties. See the Actor and Phone properties sections below. There are a bunch of other things you can change to customize your game, as shown below. You'll probably also want to modify lots of the properties described in the chatter.t manual. ******************** Classes ******************** phone: the base class for telephones. It handles things like the verbs for calling or answering phones. fixed_phone: A fixed phone is a phone you can't carry around. CALL JOE will pick up the receiver and call. PICK UP PHONE will just pick up the phone, which means you'll get a dial tone. (Of course, if the phone was ringing when you picked it up, you'll be connected with whoever was calling). You can't leave the room when you're holding a fixed_phone. HANG UP and PUT DOWN PHONE are equivalent (Incidentally, fixed_phone is implemented using a single fixed item. There's no receiver item you can pick up, for example.) mobile_phone: (Warning! Mostly Untested!) You can carry a mobile phone around. If the phone is ringing and you're not holding it, ANSWER PHONE or PICK UP PHONE will take the phone before answering it. If the phone isn't ringing, PICK UP PHONE will just take it like a normal object, and ANSWER PHONE will give an error. ******************** Phone properties ******************** Properties you have to set/override: phone_number this phone's phone number valid_phone_num(actor, num) Valid phone numbers for this actor to call from this phone. E.g. checking for the number of digits in the number. Returns true for a valid number. Note that if you say "call joe" and you know joe's number is 333, the the number 333 has to pass this test. (This could, e.g., disallow making long-distance calls from a given phone.) Default: print "Invalid number. " and return nil valid_phone_str(actor, str) Valid phone numbers (in string form) to call from this phone. See comments about valid_phone_num above Default: print "Invalid number. " and return nil Properties you might want to set: wrong_number what will be printed out if the caller calls a valid number or string which doesn't have a corresponding phone. Note that you may or may not want to make this equal to the default phone.no_answer. Default: "There's no answer. " no_answer message when someone calls this phone and there's noone there Default: "There's no answer. " busy_signal message when someone calls this phone and it's being used Default: "The phone's busy. " dial_tone_daemon This daemon says "You hear a dial tone. " if you're on the phone and aren't connected with anyone. Properties used by the code that you might want to refer to: off_hook is this phone currently being used? Default: nil ringing phone object that's trying to connect to this phone, if any (Note: this is *not* just a boolean "is the phone ringing?") Default: nil speaker who's speaking on this phone? Default: nil partner which phone is this phone currently connected with? Default: nil (Be careful about *setting* these properties, as there are methods, like set_speaker and unset_speaker, which do that.) Note that every phone needs to have a location, because an actor only knows they're being called if a phone rings at their location. If you have an actor that the character never sees, but only speaks to on the phone, you need to make the phone a mobile_phone whose location is the actor. ******************** Actor properties ******************** Here are the new Actor properties. Most of them are nil e.g. when you're not on the phone. Properties you have to set: phone_number What's my (current) phone number, if any. This will often be set equal to the phone_number of the phone in my current location. Properties you might want to set: phone_known A list of Actors whose phone numbers you know. (Obviously, this is most important to set for the Me object.) You can only CALL JOE if Joe is in your phone_known list. Of course, you could reach Joe by randomly guessing (trying "dial 111", "dial 112"...) even if you don't know it. phone_hello What do I say when I pick up the phone? Default: "Someone picks up the phone. \"Hello?\" " phone_will_answer Will I pick up the phone if it rings in my location? Default: true Properties used by the code that you might want to refer to: my_phone What phone am I currently speaking on? Default: nil phone_partner Whom am I currently talking to on the phone? (= my_phone.partner.speaker) Default: nil (These properties, like phone.speaker, are set by methods, so be careful about changing them by hand.) By default, receiver.phone_answer calls receive_phone.doPhoneAnswer(self) and then outputs phone_hello. You could override phone_answer to say "Someone picks up the phone, says, \"Don't bother me!\n" and hangs up." and not connect.