!------------------------------------------------------------------------- ! $Id: lloyd.inf,v 1.1 2000/08/20 17:31:43 neilc Exp $ ! lloyd.inf -- A component of the Inform 6 port of Ditch Day Drifter ! ! The file contains the source code for Lloyd, the friendly insurance ! robot and his insurance policy. ! ------------------------------------------------------------------------- ! ------------------------------------------------------------------------- ! ! -- Table of Contents -- ! ! LLOYD (7) ! ! status property (N) ! Lloyd's status constants (O) ! ! Lloyd (7.1) ! attributes, parse_name (7.1a) ! status (7.1b) ! description (7.1c) ! describe (7.1d) ! daemon (7.1e) ! orders (7.1f) ! life (7.1g) ! act (7.1h) ! react_before (7.1i) ! greet (7.1j) ! insurance policy (7.1.1) ! five-dollar bill (7.1.2) ! ! ------------------------------------------------------------------------- ! (7) LLOYD ! (N) status property Property status alias number; ! (O) Lloyd's status constants Constant not_encountered 0; Constant selling_insurance 1; Constant following_you 2; ! (7.1) Lloyd Object lloyd "Lloyd" InsuranceOffice ! (7.1a) ! Lloyd is transparent so that the player can see the policy that ! he is offering. has proper transparent animate ! has general if he has already done ! something interesting this turn, and no ! more unimportant messages from Lloyd should ! be printed. with parse_name [ wd num_matched; wd=NextWord(); while (wd == 'lloyd' or 'friendly' or 'insurance' or 'robot' or 'officer' or 'polyester' or 'suit') { ! Match "insurance robot" or "insurance officer" but not "insurance", ! which probably refers to the insurance policy. This fixes a bug if (wd == 'insurance') { if (NextWord() == 'robot' or 'officer') num_matched=num_matched+2; else return num_matched; } else { num_matched++; wd=NextWord(); } } return num_matched; ], ! (7.1b) ! Lloyd exists in three states, the first of which is that you haven't ! met him yet. status not_encountered, ! (7.1c) ! The description is only printed when the player examines him. description "Lloyd the Friendly Insurance Robot is a strange combination of the traditional metallic robot and an insurance salesman; over his bulky metal frame is a polyester suit.", ! (7.1d) ! The describe property is called any time that Lloyd is in the room when ! a ##Look action occurs. describe [; new_line; if (self.status == selling_insurance) "Lloyd is here, offering you an insurance policy for only one dollar."; else "Lloyd the Friendly Insurance Robot is here."; ], ! (7.1e) ! Once Lloyd's daemon is started (by his life routine, below), it runs ! every turn, even if Lloyd is not currently in scope. Thus, it has to be ! careful not to print any text unless Lloyd is in the same room as the ! player. That isn't a big concern In Ditch Day, because Lloyd is ! dogged about following the player around after his daemon is started. daemon [ self_loc player_loc; switch (self.status) { selling_insurance: ! If Lloyd has already acted this turn, don't do anything except ! unset his general attribute. if (self has general) { give self ~general; return; } ! If Lloyd isn't in scope, don't do anything. if (~~ TestScope(self)) return; ! daemon routines have to remember to print one (and only one) new- ! line character before printing any text. It is also good style ! to print another one before returning. new_line; switch (random(5)) { 1: "Lloyd waits patiently for you to make up your mind about the insurance policy."; 2: "Lloyd watches you expectantly, hoping you will buy the insurance policy."; 3: "Lloyd shows you the insurance policy again. ~Only a dollar,~ he says."; 4: "Lloyd looks at you intently. ~What can I do to make you buy this insurance policy right now?~ he asks rhetorically."; 5: "Lloyd reviews the policy to make sure it looks just right."; } following_you: ! These values will be used many times below, but not changed. ! So evaluate once, and use multiple times. self_loc=parent(self); player_loc=parent(player); ! Lloyd is in the same room with the player, so just do some ! random thing (unless it's a dark room... see below.) if (self_loc == player_loc || player_loc == bed) { if (self has general) { give self ~general; return; } ! Saves me the trouble of sticking a "^" in front of every ! string, below. new_line; if (OffersLight(real_location) == 0) { ! We're in the dark here... if (location == thedark) "You can hear Lloyd bumbling mechanically about in the darkness."; ! The player just turned out the lights... else "In the dark, Lloyd immediately runs into something. ~Thanks a lot!~ he calls. ~That's sure to leave a scuff mark."; } ! The player just turned on the lights... else if (location == thedark) "Lloyd whirrs a mechanical sigh of relief. ~Thank goodness that's over,~ he says. ~My 'darkness' programming got accidentally erased last week during an awesome insurance seminar.~"; switch (random(5)) { 1: "Lloyd watches attentively to make sure you don't hurt yourself."; 2: "Lloyd hums one of his favorite insurance songs."; 3: "Lloyd gets out some actuarial tables and does some computations."; 4: "Lloyd looks through his papers."; 5: "Lloyd checks the area to make sure it's safe."; } } ! The following else-if structure prints special messages for ! certain movement situations. For instance, if a player climbs up ! the rope Lloyd should also scramble up the rope. else { new_line; if (player_loc == railcar) print "Lloyd hops into the rail car, showing remarkable agility for such a large mechanical device."; else if (self_loc == railcar) print "Lloyd hops out of the rail car."; else if (self_loc == PitBottom && player_loc == PitTop) print "Amazingly, Lloyd scrambles up the rope and joins you."; else if (self_loc == PitTop && player_loc == PitBottom) print "Lloyd descends smoothly down the rope and joins you."; else if ( (self_loc == Tunnel12 && player_loc == Tunnel7) || (self_loc == Tunnel7 && player_loc == Tunnel12)) print "Somehow, Lloyd manages to squeeze through the crawl."; ! Lloyd has a few interesting reactions to stuff lying around ! Ditch Day. The general attribute of an apposite object is ! used to make sure Lloyd only reacts once to each situation. else if (player_loc == Quad && Quad hasnt general) { give Quad general; print "Lloyd follows you. When he sees the apparent radioactive waste spill, he is quite alarmed. After a moment, though, he deduces that the spill is a staged part of the Ditch Day festivities, and he calms down."; } else if (player_loc == Storage && Storage hasnt general) { give Storage general; print "Lloyd enters the storage room. Upon seeing the guard, he rolls over and starts giving his insurance pitch. After a moment, he notices the guard is unconscious. ~It's just as well,~ he confides. ~Security work is awfully risky, and his rates would have been quite high.~"; } else if (location == thedark) print "Lloyd blunders in after you. ~Hey! Who turned out the lights?~"; else if (player_loc == ExplosiveLab) print "~Explosive Lab!~ blurts Lloyd, rolling into the room. ~Erm, let's not tarry.~"; else print "Lloyd follows you."; move self to player_loc; new_line; rtrue; } ! This code should never be reached. default: "Lloyd looks confused and insecure. Apparently his programming doesn't cover this situation."; } ], ! (7.1f) ! Lloyd, despite being amiable, is uncooperative. orders [; Give: if (noun == policy && second == player && self.status == selling_insurance) { give self general; "~You have to pay for it first,~ Lloyd explains."; } ! Let not understood words pass through. They will be intercepted by ! the "##Answer" life rule, later on. NotUnderStood: rfalse; ! Reroute the order "Lloyd, hello" to a greeting. Hello: return self.greet(); default: give self general; "~I'm sorry, that's not in your policy.~"; ], ! (7.1g) life [; Answer: if (noun == 'hello' or 'hi' or 'greetings' or 'salutations') return self.greet(); "~I'm sorry,~ says Lloyd. ~Human phrasing is often difficult for me to comprehend. After all, I'm not AI complete.~"; Ask: give self general; switch (second) { 'policy': "~Your policy perfectly fits your needs, according to my calculations,~ Lloyd says. ~I'm afraid it's much too complicated to go into any detail right now, but you have my assurances that you won't be disappointed.~"; default: "~I'm sorry,~ says Lloyd. ~Human phrasing is often difficult for me to comprehend. After all, I'm not AI complete.~"; } Attack: give self general; if (self.status == selling_insurance) "~Hey!~ shouts Lloyd. ~If you don't want the policy, you don't have to buy it. There's no reason to be belligerent.~"; "~Careful,~ says Lloyd, worriedly. ~You might damage one of your heavily insured appendages on my shiny metallic exterior.~"; Give: give self general; switch (noun) { five_dollars: "Lloyd looks at you, confused. ~I've already sold you all the insurance you need!~"; one_dollar: ! See the pay grammar and actions ["verbs.inf":10.13]. If the ! player indicated what they are paying for, it will be saved in ! the 'buy_obj' global variable. Lloyd can check it, and print a ! refusal if the player tries to buy anything but the policy. If ! it is blank, Lloyd assumes you are buying the policy. if (buy_obj == self) "~I'm not for sale,~ says Lloyd."; if (buy_obj ~= 0 && buy_obj ~= policy) { print "~I'm not selling "; ThatOrThose(buy_obj); ",~ explains Lloyd."; } ! After you buy the policy, Lloyd follows you around. self.status=following_you; remove one_dollar; move policy to player; "Lloyd graciously accepts the payment, and hands you a copy of your policy. ~You might wonder how we keep costs so low,~ Lloyd says. ~It's simple; we're highly automated, which keeps labor costs low; I run the whole company, which keeps the bureaucratic overhead low; and, most importantly, I follow you everywhere you go for the duration of the policy, ensuring that you're paid on the spot should anything happen, which means we don't have to waste money investigating claims!~"; darbcard: ! Give the player a 'good try' response if they try to buy the ! policy with the DarbCard. if (self.status == selling_insurance) "Lloyd looks at you apologetically. ~So sorry, I must insist on cash,~ he says."; else "Lloyd doesn't appear interested."; default: "Lloyd doesn't appear interested."; } Kiss: give self general; if (self.status == following_you) "~That definitely isn't in your policy,~ says Lloyd, fending you off."; "~Er, okay, if it will help you make up your mind to buy this policy,~ says Lloyd, shrugging his metal shoulders.^^Kissing a robot doesn't turn out as exciting as might have hoped."; Show: give self general; switch (noun) { policy: "~Insurance is truly fascinating,~ says Lloyd."; one_dollar: if (self.status == selling_insurance) "Lloyd looks at it eagerly. ~Yes, that will do nicely,~ he explains."; five_dollars: "~Oh, yes,~ he says excitedly. ~Your policy will make you a rich man someday, I'm sure.~"; flask, original_ln, bottled_ln: "~That stuff looks dangerous,~ warns Lloyd. ~I hope you know what you're doing.~"; bottle: if (parent(bottled_ln) == bottle && bottle hasnt open) "~Get rid of that thing!~ exclaims Lloyd."; } ], ! (7.1h) ! ------------------------------------------------------------------------- ! Lloyd's act property is never called by the parser. It is called by code ! in various objects scattered throughout the game, with an apposite object ! for the argument. These are often reactions that would have been ! impractical to code with a react_before or react_after property. ! ------------------------------------------------------------------------- act [ obj; give self general; switch (obj) { ! Called when the bottle explodes in the player's vicinity. bottle: print "^^"; if (self.status == following_you) print "I'm sure that Lloyd is even now paying out a big lump sum for your early demise. However, that is of little use to you now.^"; ! Called when bottle explodes in the safe and Lloyd is present. bank_safe: print "^^Lloyd throws himself between you and the vault. ~Please be careful!~ he admonishes. ~The payment for Accidental Death due to Explosion is enormous!~"; ! Called after the strange machine button is pushed by the player. machine: if (five_dollars hasnt moved) { give five_dollars moved; ! the 'move' command doesn't give 'moved'. move five_dollars to player; print "^^Lloyd rolls over and looks at your thumb. ~That looks awful,~ he says as you jump about, holding your thumb. Lloyd produces a thick pile of paper and starts leafing through it. ~Temporary loss of use of one thumb... ah, yes, here it is. That injury pays five dollars.~ Lloyd puts away his papers and produces a crisp new five dollar bill, which you accept (with your other hand)."; } else print "^^Lloyd looks at you apologetically: ~I don't want to sound patronizing, but you knew it would do that. I'm afraid I can't accept a claim for that injury, as it was effectively self-inflicted.~ He looks at you sadly. ~I do sympathize. That must be quite painful,~ he understates."; ! This becomes part of the 'win' message. Called when the ship ! launches and Lloyd is present. launch_button: print "^^Lloyd heads for the door. ~Sorry,~ he says. ~I can't go with you. Your policy specifically excludes coverage during missions in deep space, and, frankly, it's too risky for my tastes. Besides, I don't appear in 'Deep Space Drifter.'~ Lloyd waves goodbye, and rolls out of the spaceship."; ! Called by the description property of the insurance office. InsuranceOffice: self.status=selling_insurance; StartDaemon(self); print "^^As you walk into the office, a large metallic robot--very much like the traditional sci-fi film robot, but wearing a dark polyester business suit--zips up to you. ~Hi, I'm Lloyd the Friendly Insurance Robot,~ he says in a mechanical British accent. ~You look like you could use some insurance! Here, let me prepare a policy for you.~^^Lloyd scurries around the room, gathering papers and studying charts, occasionally zipping up next to you and measuring your height and other dimensions, making all kinds of notes, and generally scampering about. After a few minutes, he comes up to you, showing you a piece of paper.^^~I have the perfect policy for you. Just one dollar will buy you a hundred thousand worth of Insurance!~ He watches you anxiously."; ! This code should never be reached. default: print "^^Lloyd stares in a stupidly mechanical manner, not knowing what he is supposed to be doing."; } ], ! (7.1i) react_before [; ! Lloyd interprets a general ##Hello actions as if it were directed at ! him. Hello: return self.greet(); Listen: ! In stock Inform, lloyd's react_before property isn't called in the ! dark. The InScope entry point ["entrypts.inf":8.3] forces Lloyd ! into scope in the dark. if (noun == 0 or self && location == thedark) { give self general; "It sounds like Lloyd is thinking dark thoughts."; } ! Lloyd will prevent a few dangerous acts, to help characterize him. default: if ((action == ##Drink && noun ofclass LiquidNitrogen && location ~= thedark) || (action == ##Enter && noun == pit) || (noun == bed or pit && action == ##JumpOn or ##JumpInto or ##JumpOver)) { give self general; "In sudden alarm, Lloyd stops you: ~You could get seriously injured pulling a stunt like that.~"; } ], ! (7.1j) ! There are quite a few different ways for the player to say hello to ! lloyd, so, to avoid duplicating code, they all call this routine. ! ! Here are all the possible ways: ! ! 1. LLOYD, HELLO ! Results in an order to Lloyd to perform the ##Hello action. ! ! 2. SAY HELLO TO LLOYD ! Results in the Answer action, and runs Lloyd's life routine with ! action set to ##Answer and noun set to 'hello'. ! ! 3. HELLO ! Calls the ##Hello action. ! ! The ##Hello action and grammar: ["verbs.inf":10.6]. greet [; if (self.status == following_you) "Lloyd looks at you strangely for a moment, comes to some sort of conclusion about carbon-based life-forms, and finally makes a shrugging motion: ~Hi. Nice weather we've been having.~"; else "~Hello,~ says Lloyd, ingratiatingly."; ], ; ! (7.1.1) insurance policy Crawlable ->-> policy "policy" with name 'insurance' 'policy', description [; print "The policy lists the payment schedule for hundreds of types of injuries. The list is far too lengthy to go into in any detail here, but rest assured, "; if (self in lloyd) "it looks like an excellent deal."; else "you're highly satisfied with what you got for your dollar. You feel extremely well protected."; ], ; ! (7.1.2) five-dollar bill Crawlable five_dollars "five-dollar bill" with name 'fiver' '5//' 'five' 'dollar' 'dollars' 'five-dollar' 'bill' 'money', ;