Constant Story "Bloodline";
Constant Headline "^An Interactive Coming-of-age^Copyright (c) 1998 by
   Liza Daly.^First time players should type ~about.~^^";

Include "parser";
Include "verblib";

! Properties

!Property follow_dir 0;
Property treasure_number;
Property player_number;
Property start_treasures;

Constant total_players 3;

Global num_moves = 25;

! Attributes

Attribute rollable;

! Class definitions

Class Human
has    animate proper;

Class   Clothes
with   before
       [;
        Disrobe, Drop, ThrowAt: "As if!  You're only 13!";
       ];

Class   Treasure
with   before [;
        Take, Drop: "Patience. You can only take or lose the
           treasures as the game proceeds.";
        Examine: print_ret "One of the ten game treasures. It looks
               just like a small plastic replica of ", (a) self, ".";

       ],
       list_together "~treasures~";

Class Piece
with   before[;
        Take: "You can't remove the pieces from the board while the
           game is in play!";
        Push: "That's not the way to play.";
       ];


! Object definitions

Object Basement "In the Basement"
with   description [;
           if (self hasnt visited)
           {
               print "Jenny's basement has been the site of some of
                   the most important developments in your life.
                   It's the first place you sipped beer. It's the first
                   place you saw a porn magazine (even though Jenny
                   insisted her dad reads them for the articles). And
                   tonight, it might be the setting for your first
                   kiss. If only you knew whether Randy liked
                   you...^^";
           }
           "The basement is perfect for slumber parties - it's big, it's
           carpeted, it's got a TV, and best of all, a separate door
           to the outside that can be opened without her parents
           waking up. Mid-party, the room is covered in sleeping
           bags, emptied junk food containers, and teenagers. Stairs
           lead up to the rest of the house.";
       ],
       out_to [;
           <<Open Backdoor>>;
       ],

       u_to [;
           if (self hasnt general)
           {
               give self general;
               "Jenny grabs your arm. ~Are you crazy? You'll wake up
               my parents!~";
           }

           else
           {
               "Jenny's right. There's nothing interesting up there,
               anyway.";
           }
       ],


has    light static;

Object -> Carpet "carpet"
with   name "carpet" "floor",
       description "Shag.",
has    static scenery concealed;

Object -> Stairs "stairs"
with   name "stairs" "steps",
       description "They go up, Ray.",
       before [;
        Climb: <<Go u_obj>>;
       ],
has    static scenery concealed;


Object  -> Backdoor "door"
with   name "door",
       description "It leads out to Jenny's garage, and from there to
           the street.",
       before [;
        Open: "Leave in the middle of the game? Hardly.";
       ],
has    static scenery openable concealed;

Object -> Bags "sleeping bags"
with   name "bags" "sleeping bags" "sleeping",
       description "They're everywhere. You dropped yours not far
           from Randy's, but you've lost sight of them both.",
       before [;
        Take: "Save the clean-up for tomorrow.";
        Enter: "It's still way early for that.";
       ],
has    enterable static scenery concealed;

Object -> Teens "teenagers"
with   name "teens" "teenagers" "guests" "friends" "kids",
       description "Most of the people in your relatively small
           class, and almost all your friends.",
has    pluralname static scenery animate;


Object  -> Pam "Pam"
with   name "Pam",
       description "Pam is like your best friend in the whole
           world. She's way prettier than you, so she's usually got
           boys just falling all over her. As a result, you take her
           advice on guys seriously. Tonight, she's engrossed in
           flipping her hair at Billy over by the TV.",
       life [;
        Kiss: "Admittedly, the thought has crossed your mind.";
        default: "Pam is way into her conversation with Billy, although
           she's pulled herself out of it a few times to talk to you.";
       ],
has    animate proper scenery;

Object -> Billy "Billy"
with   name "Billy",
       description "Billy is so not your type, but Pam likes him so
           you have to be nice. Besides, he's pretty okay, although
           you'd prefer if he were paying more attention to Pam than
           that stupid slasher movie on TV.",
       life [;
        Kiss: "Like wouldn't Pam just kill you? Besides, he's no
           Randy.";

        default: "No way. Talking to another guy when you're
           completely trying for Randy is just so bad.";
       ],
has    animate proper scenery;

Object -> Sarah "Sarah"
with   name "Sarah",
       description [;
           if (self hasnt general)
           {
               give self general;
               "Oops! You totally forgot she wasn't here anymore. Her mom
               gave her this stupid curfew and she had to leave hours
               ago. Totally lame, right?";
           }
           else
           {
               "Er, hello? She's not here anymore!";
           }
       ],
       life [;
        default: "You're talking to someone who left the party hours
           ago. Totally weird.";
       ],
has    animate proper scenery;

Object -> TV "television"
with   name "tv" "television" "tele" "movie" "slasher" "film" "show",
       description [;
           print "Jenny put a slasher movie in with the volume
               off. Every time you look, something totally gross
               happens.^^";
           switch(random(5))
           {
            1: "Onscreen, an actress has just been served a pizza
               topped with human eyes! Yech!";
            2: "Ew. A crazed man in the film seems to be chainsawing off
               his own hand.";
            3: "In this scene, a man in a trenchcoat hands a woman
               some flowers, and then begins chasing her with a giant
               knife.";
            4: "In the movie, limbs are flying everywhere.";
            5: "There's some action now involving a shower, an
               electric steakknife, and an entire sorority, but you
               have to turn away.";
           }
       ],
has    static scenery concealed;



Object -> Food "junk food"
with   name "junk food" "food" "trash" "soda" "soda cans" "cans"
           "popcorn",
       description "Wreckage from the party. Empty bags of popcorn,
           sticky soda cans. It'll all have to be cleaned up tomorrow.",
       before [;
        Take: "Wait until morning. There's more important things on
           your mind now.";
        Eat: "Like, gross.";
       ],
has    pluralname scenery concealed;


Human -> Randy "Randy"
with   name "Randy" "Randy Garri" "Garri",
       player_number 2,
       start_treasures 4,
       description [;
           if (self hasnt general) {
               give self general;
               print "^You gaze longingly at Randy for a moment. God,
               he's cute. If you don't get to kiss him or something
               tonight, you'll just die.";
           }
           else {
               print "You can't help but stare again. He is just so hot.";
           }
           if (children(self) )
           {
               print "^^He's playing the game and holding ";

               WriteListFrom( child(self),
                             FULLINV_BIT + ENGLISH_BIT + RECURSE_BIT
                             );
           }
           ".";
       ],

       life [;
        Show, Give:
           if (noun == Note)
           {
               "Woah! That'd be like totally stupid! What are you
               smoking?!";
           }
           if (noun == Card)
           {
               "Personal crisis aside, you are supposed to at least
               pretend to beat him.";
           }


           if (noun ofclass Treasure)
           {
               "This game doesn't work that way.";
           };
        Kiss: "Woah, not yet! What if he doesn't like you?";
        default: "You're way too entranced in his eyes.";

       ],
has    animate proper;


Human  -> Jenny "Jenny"
with   name "Jenny" "Herschel" "Jenny Herschel",
       player_number 3,
       start_treasures 1,
       description [;
           print "Sarah put Jenny's hair in braids earlier, and then
           used a whole can of hairspray to get them to stick off the
           top of her head. It looks completely stupid, but then that's
               what slumber parties are for.";
           if (children(self) )
               {
               print "^^She's absorbed in the game, holding ";

               WriteListFrom( child(self),
                             FULLINV_BIT + ENGLISH_BIT + RECURSE_BIT
                             );
               ".";
           }
           new_line;
           rtrue;

       ],

       life [;
        Kiss: "Admittedly, the thought has crossed your mind.";
        Show, Give: "There's nothing in your possession you'd want
           her to see.";
        default: "There's no reply. She's completely distracted
           between watching the game and keeping an eye out for her
           parents.";
       ],
has    animate proper transparent;


Object -> Game "game of Bloodline"
with   name "game" "board" "bloodline",
       article "the",
       description [;
           print "It's a simple game, once you get the hang of
               it. Collect the treasures, and make it to the ~finish
               line~ first. Each turn, you can either roll the dice
               and move your piece, or draw a card.^^The current game
               position has ";
           if (num_moves > 9)
           {
               "Jenny very far away from the finish line, on
               the mauve square, Randy's piece on the silver
               circle, seven spaces away, and your piece closest
               - only five spaces away.";
           }

           else
           {
               "Jenny out of the game, Randy's piece on the bronze
               triangle (one space from the end), and your piece only
               five spaces away.";
           }


       ],
       before[;
        Receive: "All the pieces needed for the game are already on
           the board.";
        Take: "No way. The game's not over yet.";
       ],

       daemon [;
           num_moves = num_moves - 1;
           switch(num_moves)
           {
            24: "^Jenny leans forward over the game board, considering
               her next move.";
            22: move Note to player;
               "^Pam gets up from the group near the TV and comes
               over to you. ~Read this and don't show it to anyone!~
               She hands you a note, winks, and returns to the group.";
            19: "^Jenny sighs, and leans over the game board. ~Okay, I'm
               going to draw a card.~";
            18: move Dice to Randy;
               move child(Jenny) to Randy;
               "^Jenny picks up a card, turns it over slowly, and then
               groans. ~Shit.~^^Randy peeks over her shoulder, first brushing
               his hair out of his eyes in a way that's totally
               adorable. ~Rockin'!~ he exclaims. ~I'll take that, Jen.~
               He takes her last treasure gleefully.";
            17: "^Randy is sorting his treasures. He looks up and
               stares at you for a long, wonderful moment. ~Looks
               like it's just us now,~ he says to you.^^Oh my God!";
            14: "^Jenny, out of the game but still watching, looks
               annoyed. ~Hurry up, Randy. I wanna know what
               happens.~";
            13: "^Randy rolls his eyes. ~I'm hurrying!~ You glare at
               Jenny. How dare she!";
            11: "^~Okay,~ Randy says finally. ~I'm gonna roll for
               it.~";
            10: "^Randy tosses the dice. They come up double
               three's.";
            9: "^~Excellent!~ Randy moves his piece forward. He's only
               one away from the finish line.";
            8: move Dice to Player;
               "^Randy hands the dice to you. ~Your turn,~ he says, as
               your fingers touch briefly.^^Pam sidles up to
               you. ~Let him win!~ she whispers. ~Guys hate it when
               girls beat them.~ Before you can answer, she's gone
               back to the group.";
            6: "^Jenny pokes you with one slippered foot.";
            4: "Jenny throws a potato chip at you, which you pick out
               of your hair. ~Hurry up, stupid!~";
            2: "^Randy coughs politely. Uh oh. He's getting pissed at
               you.";
            1: print "^Both Jenny and Randy have totally lost patience with
               you.^^~Oh, just forget it,~ Jenny says. ~She's not even paying
               attention.~^^They get up and join the rest of the
                   group. Randy throws you a look of total
                   disgust.^^";
               deadflag = 3;

           }
       ],
has    supporter;


Piece   -> -> Jenny_Piece "Jenny's game piece"
with   name "piece" "Jenny^s piece" "Jenny^s" "game piece" "Jenny^s
           game piece",
       description [;
           if (num_moves > 18) {
               "Jenny's piece is on the mauve square - far, far from
               the finish line.";
           }
           else
           {
               "Jenny's out of the game, remember?";
           }
       ],
has    proper;

Piece   -> -> Randy_Piece "Randy's game piece"
with   name "piece" "Randy^s piece" "Randy^s" "game piece" "Randy^s
           game piece",
       description [;
           if (num_moves > 9)
           {
               "Randy's piece is on the silver circle, seven spaces
               from the finish line.";
           }
           else
           {
               "Randy's piece is only one space away from the end of
               the game.";
           }
           ],
has    proper;

Piece   -> -> Player_Piece "your game piece"
with   name "piece" "my piece" "mine" "my" "game piece" "my game piece",
       description [;
           print "Your piece is five spaces away from the finish
               line. ";
           if (num_moves > 9 && num_moves < 18)
           {
               "If Randy does really well on his turn, he might be
               able to finish.";
           }
           else
           {
               "With the card in your hand, you can win
               instantly.";
           }
           new_line;
           rtrue;

       ],
has    proper;


Treasure T1 "hairy chicken"
with   name "hairy" "chicken" "hairy chicken" "treasure",
       treasure_number 1,
       description " ";

Treasure T2 "prosthetic ear (left)"
with   name "prosthetic" "ear" "left" "prosthetic ear",
       treasure_number 2,
       description " ";

Treasure T3 "corned mutton"
with   name "corned" "corn" "mutton" "corned mutton",
       description " ";

Treasure T4 "vial of plague"
with   name "vial" "plague" "vial of plague" "ebola",
       description " ";

Treasure T5 "sea cucumber"
with   name "sea" "cucumber",
       description " ";

Treasure T6 "useful rock"
with   name "rock" "useful",
       description " ";

Treasure T7 "critical reference manual"
with   name "critical" "reference manual" "reference" "book",
       description " ";

Treasure T8 "mad cow"
with   name "mad" "cow" "moo",
       description " ";

Treasure T9 "dirty duck"
with   name "dirty" "duck",
       description " ";

Treasure T10 "overripe banana"
with   name "overripe" "banana",
       article "an",
       description " ";

Object Card "game card"
with   name "card" "game card",
       description "One of many special game cards, with Bloodline
           logo on one side and its meaning printed on the
           other. It reads, ~Move six spaces forward.~
           Throwing down this card from your position means you
           could instantly win the game.",
       before [;
        Take: "Jenny looks at you funny. ~You can only have one card
           at time. Which you'd know if you were listening to the
           rules instead of babbling to Pam again.~";
        Drop: if (num_moves > 8) "It's not your turn yet, dummy.";
           else
           {
               if (self hasnt general && Dice hasnt general) {
                   give self general;
                   "Wait. If you drop this, you'll like possibly ruin
                   any chance with Randy because he could totally
                   hate being beaten by a girl. But if you do let him
                   win, you're just promoting the
                   stereotype of girls being stupid.^^This
                   sucks! You don't know what to do.";
               }
               else {
                   deadflag=4;
                   "You put down the winning card, and ceremoniously move
                   your piece to the last square.^^As if on cue,
                   there's a sudden quiet moment in the movie on
                   TV. Pam leaves her place next to Billy and gapes
                   at you in disbelief. Jenny, seemingly unsurprised,
                   begins packing up the game and seems to be
                   congratulating you. You're not listening at all,
                   though.^^All you can do is stare at Randy. He
                   looks at you and makes this completely fake smile.
                   ~Hey, good game.~^^
                   Larry Beckman (gross!) suddenly appears behind him and
                   punches him in the shoulder. ~Yo - let's go
                   throw some eggs off the roof.~^^Randy looks at
                   you with an expression you just know is total
                   disgust. ~Yeah,~ he says to Larry, as Larry
                   disappears out the door with a fresh
                   carton. Getting up, Randy says to you, ~Uh, see ya
                   later.~^^Right. Not if you don't just jump off the
                   planet first.";
               }

           }

       ];

Object Instructions "instructions for Bloodline"
with   name "instructions",
       description [;
           <<Help>>;
       ];

Object Note "note from Pam"
with   name "note" "paper",
       description [;
        if (self hasnt general)
        {
            print "You unfold the note from Pam, and read it, eyes
                widening:^";
        }
        print "~Alison talked to Larry, who had gym with
            Tommy Russell, who ate lunch with Ally, who asked Randy
            about you and he said he thinks he LIKE LIKES
            you!~^";
        if (self hasnt general)
        {
            print "^You can barely breathe. Now all you
                have to do is not screw up...^";
            give self general;
        }
        rtrue;
    ];

Object Dice "pair of dice"
with   name "die" "dice",
       description "Just an ordinary pair of dice, suitable for
           rolling.",
       before [;
        Roll:
           if (num_moves > 8)
               "Duh. It's not your turn yet.";
           else
           {
               if (self hasnt general && Card hasnt general)
               {
                   give self general;
                   "You hesitate. You can win at any moment with the
                   card in your hand. Letting Randy win just to
                   satisfy his male ego and give you a better shot at
                   him is just way un-feminist. Aunt Janet would just
                   shit.^^You really aren't sure what to do. Randy is
                   staring at you expectantly.";
               }
               else
               {
                   deadflag = 5;
                   "~I'm gonna roll,~ you say. Pam looks up from the
                   TV and gives you an excited thumbs-up.^^
                   You toss the dice. Everyone around the game board
                   leans over expectantly.^^
                   Double twos! You try to look disappointed - it's
                   not enough for you to cross the finish line. Randy
                   reaches for the dice but Jenny stops him. ~Don't
                   prolong the inevitable. You totally won, just like
                   you always do.~ Randy grins at her - he's got just
                   the best teeth!^^
                   Jenny, seemingly unsurprised,
                   begins packing up the game and seems to be
                   congratulating him. You're not listening at all,
                   though.^^All you can do is stare at Randy. He
                   looks at you with a huge, gorgeous smile.
                   ~Hey, good game.~^^
                   Larry Beckman suddenly appears behind him and
                   taps him on the shoulder. ~Yo - let's go
                   throw some eggs off the roof.~^^Randy looks at
                   you and you're so sure he's winking knowingly.
                   ~Yeah,~ he says to Larry, with obvious sarcasm.
                   Getting up, Randy says to you, ~Hey... see ya
                   later.~^^And you know you will.";
               }

           }
       ],

has    rollable;

Human   Tracy "Tracy"
with   description [;
           switch(random(4))
           {
            1: "Self-consciously, you play with your hair.";
            2: "Ergh, dry lips. You try to lick them surreptiously.";
            3: "Gross. These jeans make you look like a total blob.";
            4: "You briefly brush your face, feeling for a
               break-out.";
           }
       ],
       add_to_scope Dice instructions,
       player_number 1,
       number,
       start_treasures 5;

! Initial objects

Clothes Jeans "blue jeans"
with   name "jeans" "bluejeans" "blue jeans",
       description "They're worn, baggy and comfortable. Exactly what
           you wouldn't have chosen if you'd known Randy would be
           here.",
has    clothing;

Clothes Shirt "t-shirt"
with   name "shirt" "t-shirt",
       description "Your standard issue Gap pocket tee.  In green.",
has    clothing;

! Begin subroutines

[ Initialise i j k l;
   ChangePlayer(Tracy);
   location = Basement;

   objectloop(i ofclass Treasure)
   {
       while (l ~= 1)
       {
           j = random(total_players);
           objectloop(k ofclass Human)
           {
               if (k.player_number == j && children(k) <
                   k.start_treasures)
               {
                   move i to k;
                   l=1;
               }
           }
       }
       l=0;

   }

   move Shirt to player;
   give Shirt worn;
   move Jeans to player;
   give Jeans worn;
   move Card to player;
   StartDaemon (Game);
   give Game ~openable;
   move Dice to Jenny;
   "^^Jenny snapped her gum - audible even over the screams coming
   from the TV. ~Okay, like, shut up. I'm going to read the opening
   of the game...~^^Randy cut her off. ~Do we need to hear this
   again?~^^~Way!~ She rolled her eyes for
   effect. ~She hasn't played before,~ Jenny nodded at you, ~so just
   sit there and shut up. It's not like you won't win anyway.~ Randy
   settled back, and Jenny cleared her throat
   theatrically.^^~'In his will, Baron von Frufenhortz left behind an
   enormous fortune to whichever of his ruthless relatives could
   capture the most of ten magical treasures he'd hidden in his
   Transklovanian castle. In this game, you will use cunning, daring
   and luck to outwit your opponents in the search for the treasures,
   and the race to bring them to the finish line. The game proceeds
   as each player rolls dice or plays special cards...'~^^
   Pam slid in behind you, whispering in your ear. ~I know why
   you're playing this stupid game.~ You tried to swat her away, but
   she was insistent. ~It's because Randy likes it, and you like
   Randy.~^^You remember blushing furiously. ~Shut up!~ you
   hissed. ~I'm trying to listen to the rules.~^^Pam
   laughed. ~There's only one rule you need to know - boys HATE when
   girls like us beat them.~ She cackled and disappeared.^^
   Now, almost an hour later, the board game has worn out all
   but the most determined players. You've done well, which is
   surprising, since Pam's words and Randy's hot bod were the only
   things on your mind as you've played through the game of...^^^^";

];

[ Deathmessage;
   if (deadflag == 3)
   {
       print "You are a complete freak to all guys";
   }
   if (deadflag == 4)
   {
       print "Randy will hate you forever";
   }
   if (deadflag == 5)
   {
       print "You are totally going to make it tonight";
   }

];

[ XyzzySub;
   "Like, what a nerd.";
];



[ RollSub;

   if (noun hasnt rollable)
       "That isn't something you can roll.";
   else
   {
       print_ret "You roll ", (the) noun;
   }
];

[ PlaySub;
   if (noun == Card)
   {
       <<Drop Card>>;
   }

   else
   {
       print_ret "You don't know how to play ", (the) noun;

   }
];

[ AboutSub;
   "~Bloodline~ is a work of interactive fiction produced for the
   1998 IF Mini-Competition (sponsored by Lucian ~Lucian~ Smith).
   Thanks, LP!^^
   Questions, bug reports, and miscellaneous paper products
   should go to Liza Daly (gecko@@64retina.net). Thanks to Matthew
   Amster-Burton, Mark Musante and Lucian for beta-testing, and thanks to the
   denizens of the MUD for the treasure suggestions.^^
   Visit ifMUD: You don't need the sleep. (http://fovea.retina.net:4001/)^^
   Keep circulating the games.";
];

[ HelpSub;

   if (Instructions hasnt general)
   {
       give Instructions general;

       "~Hey, lemmie see that?~ you ask Jenny. She hands you the
       instructions for the game, which basically tell you what you
       already know:^^
       When it is a given player's turn, you can either play a card in
       your hand, draw a new card, or roll the dice to advance your
       player piece.^^
       ~Thanks, Jenny.~  You return the instructions to her.";
   }
   else
   {
       "When it is a given player's turn, you can either play a card in
       your hand, draw a new card, or roll the dice to advance your
       player piece.";
   }


];

[ SmileSub;

   if (noun) {
       if (noun == Randy)
       {
           "You flash Randy a dazzling smile, sure to win him over.";
       }
       else
       {
           "Save your pearly whites for Randy.";
       }
   }
   else
   {
       "You smile indiscriminately.";
   }

];




Include "grammar-mini";

Verb "roll"
   * noun                              -> Roll;

Verb "play"
   * noun                              -> Play;

Verb "xyzzy"
   *                                   -> Xyzzy;

Verb meta "about" "info"
   *                                   -> About;

Verb meta "help"
   *                                   -> Help;

Verb "draw"
   * noun                              -> Take;

Verb "smile" "grin"
   *                                   -> Smile
   * "at" noun                         -> Smile;