!% -S

!=============================================================================
Constant Story "Rock'Em Sock'Em Robots";
Constant Headline
       "^An Interactive Boxing Match^
        By Benjamin Mullins.^";
Constant MAX_SCORE = 100;
Constant AMUSING_PROVIDED;

Include "Parser";

Object  LibraryMessages
 with  before [;
               Ask, Tell:
                       if (noun == player)
                       "That's said to be a sign of mental illness.";
               Attack:
                       "Violence is the answer to this one, but it's best to
                       direct it appropriately.";
               Cut:
                       "That is Wristslitter's function.";
               Dig:
                       if (noun == player)
                       "Such self-absorption is unbecoming.";
               Jump:
                       "Impossible. Your legs have no joints.";
               Listen:
                       "The audience is making far too much noise to hear
                       anything specific.";
               Mild:
                       print "You restrain yourself to a minor curse word,
                       ever mindful of the fact that there are "; style bold;
                       print "children present"; style roman; print " at this
                       wholesome bloodsport match.^";
                       return true;
               Pray:
                       deadflag = 5;
                       print "You fall to your knee-equivalents in prayer.
                       ~O Lord,~ you cry, ~forgive my sins against you, and
                       save my immortal soul.~^^
                       The red robot, overcome by your faith, falls to the
                       floor as well, his eyes filled with tears. ~This
                       fighting is wrong! Does it not say in Luke 6:29, ";
                       style underline; print "'And unto him that smiteth
                       thee on the one cheek offer also the other; and him
                       that taketh away thy cloak forbid not to take thy coat
                       also'?~^^"; style roman;
                       print "Your faith moves the crowd, who all drop to
                       their knees as well and pray for salvation from Jesus
                       Christ. The show of faith and brotherly love causes
                       you to weep openly. You embrace the red robot. ~Let's
                       go have a Bible study!~ you shout. The crowd roars its
                       agreement.";
                       return true;
               Sing:
                       "You play a MIDI of ~Shave and a Haircut~.";
               Sleep:
                       "You always make sure you're fully charged before a
                       match.";
               Smell, Taste:
                       "You have no olfactories.";
               Sorry:
                       "The red robot does not accept your apology.";
               Strong:
                       "Real robots do not use such language.";
               Swim:
                       "But you might rust!";
               Take:
                       if (lm_n == 2)
                               "You wish.";
               Think:
                       deadflag = 6;
                       "You analyze the situation, formulating plans of
                       attack and carefully considering any openings the red
                       robot might give you. While you're doing this, the red
                       robot whacks you in the head.";
               VagueGo:
                       "You are attached to the floor of the ring. There is
                       no escape for you.";
               WaveHands:
                       <<WaveTo crowd>>;
               Miscellany:
                       if (lm_n == 19)
                               "A few dents and dings from the previous
                               rounds mar your gleaming blue exterior.";
       ];

! Take a swing at Red. Roll a d100, and if the number generated is 30+, choose
! a phrase to print, then hit. Otherwise, Red parries.
[ AttackRed num;
       if (random(100) >= 30) {
               num = random(3);
               print "You land a ";
               switch (num) {
                       1: print "devastating blow";
                       2: print "vicious uppercut";
                       3: print "spectacular roundhouse";
               }
               print " on the red robot's jaw!^";
               HitRed();
       }
       else
               print "The red robot parries your blow!^";

];

! Yay! We hit. Increment Red's HP counter. If it's already at 2 hits and this
! hit takes it up to 3, we win. Print the normal win message and end the game.
[ HitRed;
       if (red.hits_taken == 2) {
               score = score + 99;
               deadflag=4;
               print "^You deal the final blow to the red robot, sending his
               head flying upwards. You wouldn't think it possible if you
               couldn't hear it, but the crowd begins to cheer even more
               loudly than before. The red robot's manager looks on in horror,
               quickly jumping into the ring to push his client's head back
               into place.^^
               You're quickly ushered out of the arena and to safety as the
               fans begin to mob the ring. You're taken to a waiting limo.
               Your manager is already waiting inside, grinning broadly.^^
               ~Nice work, Blue. I had faith in you the entire time.~ You try
               to thank him, but he's too excited to listen. ~I just got off
               the phone with a few contacts of mine -- y'know, in the
               breakfast gears business and stuff -- and it's lookin' very
               good for you. I tell you, a match this big, you'll be gettin'
               the biggest endorsement deal there ever was. We're both going
               to be rich! Let's go out to celebrate!~";
               return true;
       }
       (++(red.hits_taken));
];

! Red hitting us works the same way as we hitting red. Only difference is that
! we use a global variable to track our hit points.
Global blue_hits_taken = 0;

[ AttackBlue num;
       if (random(100) >= 30) {
               num = random(3);
               print "The red robot lands a ";
               switch (num) {
                       1: print "devastating blow";
                       2: print "vicious uppercut";
                       3: print "spectacular roundhouse";
               }
               print " on your jaw!^";
               HitBlue();
       }
       else
               print "You parry the red robot's blow!^";
];

[ HitBlue;
       if (blue_hits_taken == 2) {
               deadflag=3;
               "^As the red robot's fist connects with your face, you feel
               your head begin to jerk upwards. You don't have long to feel
               sorry for yourself; you black out shortly afterward.";
       }
       (++(blue_hits_taken));
];

Global match_started = false;
Global france_visited = false;

Include "VerbLib";

!=============================================================================
! The game objects

Object  ring "Round Five"
 with  name 'ring' 'arena' 'stadium' 'auditorium' 'floor',
       description "You are standing in the ring of one of the greatest
                   robot boxing stadiums in the entire world. Thousands of
                   screaming fans have packed the arena to see your match.
                   It's time for the fight to end it all.",
       cant_go "You are attached to the floor of the ring. There is no escape
               for you.",
  has  light;

Object -> red "red robot"
 with  name 'robot' 'red' 'opponent' 'foe' 'enemy',
       description "The red robot is the reigning champ of robotic boxing. No
                   one expected you to hold your own against him, but you're
                   no pushover; you've given him a run for his money.",
       initial "The red robot stares at you intently.",
       article "the",
       hits_taken 0,
       waited_a_turn false,
       before [;
               Attack:
                       if (match_started == false) "You have to wait for
                       the match to start, or else you'll be disqualified.";
                       else {
                       AttackRed();
                       return true;
                       }
               Burn:
                       "Those kinds of robot fights were outlawed years
                       ago.";
               Cut:
                       "This is boxing, not a duel.";
               Dig:
                       "You don't dig the red robot at all. He is your
                       eternal foe.";
               Distract:
                       "You point and shout, ~Hey, look! Behind you!
                       Something cool!~^^
                       It doesn't work.";
               Get:
                       if (match_started == false) "You have to wait for
                       the match to start, or else you'll be disqualified.";
                       else {
                       AttackRed();
                       return true;
                       }
               Push, Pull:
                       "How unsporting!";
               Swing, Throw, Drop:
                       "Those sorts of moves are strictly prohibited.";
               SwitchOff:
                       <<Cheat>>;
               Take:
                       "You don't swing that way!";
               WaveTo:
                       "The red robot just looks at you. What a jerk!";
       ],
       life [;
               Ask, Talk, Tell:
                       "The red robot ignores you completely. How rude.";
               Give:
                       if (noun == croissant)
                       "He doesn't want it. Has he no respect for the power
                       of croissant?";
               Kiss:
                       deadflag = 3;
                       print "You think to yourself, ";
                       style underline; print "this violence is senseless.
                       Why can't blue robot and red robot coexist in
                       harmony?"; style roman;
                       print " You reach out to embrace your red brother.
                       Unfortunately, it appears he does not share your
                       pacifist views. While you're vulnerable, he pummels
                       you mercilessly.^";
                       return true;
       ],
       each_turn [;
               StartDaemon(self);
       ],
       daemon [;
               if (match_started == true) {
                       if (red.waited_a_turn == true)
                       AttackBlue();
                       else red.waited_a_turn = true;
               }
               else StopDaemon(self);
       ],
  has  animate male;

Object -> crowd "crowd"
 with  name 'crowd' 'people' 'folks' 'audience' 'fans' 'girl' 'woman' 'man',
       description "The audience is packed into every available seat in the
                   stadium, with plenty more sitting in the aisles. They're
                   watching you intently, and making quite a commotion.",
       article "the",
       before [;
               Attack:
                       "You'd better not. Your manager is still making
                       payments on the loan he had to take out to pay the
                       settlement from the last time.";
               Burn:
                       "You forgot to bring your flamethrower.";
               Cut:
                       "INSERT WITTY REJOINDER HERE";
               Dig:
                       "You dig the audience members that cheer for you,
                       anyway.";
               Distract:
                       "Nothing doing. They've all come here for a fight,
                       and they're not going to be distracted.";
               Take:
                       "Save it for after the match, Romeo.";
               WaveTo:
                       print "You give the audience a smile and a wave, to
                       the excited cheers of your fans. You imagine they'll
                       all be telling their friends when they get home,
                       ~Blue waved at ";
                       style underline; print "me"; style roman; print "!~^";
               Win:
                       "No, the robot. Not the crowd.";
       ],
       life [;
               Ask, Talk, Tell:
                       "You shout something to the audience, but they can't
                       hear you over all the racket in the stadium.";
               Give:
                       if (noun == croissant) {
                               remove croissant;
                               "You throw the croissant to a young lady in
                               the audience. She is overcome with joy and
                               begins screaming to her friends about her new
                               treasure.^^
                               Being famous is awesome.";
                       }
                       "You shouldn't have any other items to give. This is a
                       bug.";
               Kiss:
                       print "You're not doing "; style underline;
                       print "that"; style roman; print " again.^";
                       return true;
       ],
       each_turn [;
               print (string)
               random("^A little girl in the front row bellows with rage.
                       ~The robot requires additional pummeling! Continue!~^",
                       "^The crowd screams with pleasure.^",
                       "^The audience roars with approval.^",
                       "^A man in the audience yells, ~Knock his block off,
                       Red!~^",
                       "^A woman seated behind you yells, ~Go Blue! Kill that
                       red bastard!~^",
                       "^The crowd holds its breath in anticipation of your
                       next moves.^");
       ],
  has  animate scenery;

Object  croissant "croissant"
 with  name 'croissant' 'bread' 'roll' 'food' 'snack',
       description "A warm, flaky croissant, engineered for tastiness. It was
                   given to you by a kindly French baker.",
       before [;
               Burn:
                       "How can you even think of doing such an injustice to
                       this marvelous croissant?!";
               Cut:
                       "That is the duty of a lowly kitchen bot.";
               Dig:
                       "The baker is glad you like it.";
               Drop:
                       deadflag = 8;
                       "You throw the croissant to the floor and stamp on it
                       in disgust. You barbarian!";
               Throw, ThrowAt:
                       remove croissant;
                       "You throw the croissant to a young lady in the
                       audience. She is overcome with joy and begins
                       screaming to her friends about her new treasure.^^
                       Being famous is awesome.";
       ],
       after [;
               Eat:
                       score = score + 1;
                       "You are filled with the terrible power of French
                       baked goods!";
       ],
  has  edible;

Object  bell "bell" ring
 with  name 'bell',
       before [;
               Examine:
                       "It rings when the match starts. That's about all
                       there is to it.";
               default:
                       "Leave the bell alone.";
       ],
       time_left,
       time_out [;
                       match_started = true;
                       "^The bell rings! The match has started!";
       ],
  has  scenery;

!=============================================================================
! Entry point routines

[ Initialise; location = ring;
 StartTimer(bell, 3);
 print "Four rounds have gone by. You and the red robot have stayed neck
        and neck for the lead, with two wins each. The robot that emerges
        victorious in the fifth round will become Champion of Robotic Boxing,
        with all the praise and adulation that title implies.
        ^^Also, you get a pretty sweet endorsement deal from a leading gear
        manufacturer.
        ^^The final round is about to begin. Get out there and win!^^";
];

[ DeathMessage;
       if (deadflag == 3) print "Your head has popped up";
       if (deadflag == 4) {
               print "Your opponent's head has popped up";
               deadflag = 2;
               ! We change the deadflag to 2 so it will print the AMUSING
       }
       if (deadflag == 5) print "Nothing practical results from your prayer";
       if (deadflag == 6) print "You have overanalyzed the situation";
       if (deadflag == 7) print "You have broken a child's heart";
       if (deadflag == 8) print "You have insulted the French";
       if (deadflag == 9) print "You have been disqualified";
       if (deadflag == 10) print "You have disassembled the game file";
];

[ Amusing;
       "Have you tried...^^
       ...praying?^
       ...hugging the red robot?^
       ...throwing the match?^
       ...cheating?^
       ...thinking?^
       ...magic word XYZZY?";
];

!=============================================================================
! Standard and extended grammar

Include "Grammar";

[ AboutSub;
       print "I wrote this ~game~ mostly for the sake of learning the Inform
       programming language. It was coded during the end of January and the
       beginning of February, 2005. There are 8 ways to end the game. Try to
       collect them all (without reading the AMUSING)!^^
       The game concept was created waaaaay back in November of 2004, when we
       were in the middle of IF Comp 2004. There was some talk in my IRC
       hangout about how an awful lot of the games focused on combat that
       year. So Randolph, credited below, cracked a joke about a Rock 'Em
       Sock 'Em Robots IF game. When I finally got around to learning Inform,
       I remembered the joke, and decided to actually make the game.^^
       This game is freeware.^^
       Comments and criticisms may be directed to: benmullins@@64gmail.com^^
       Special thanks to:^";
       style bold; print "Chris Battey"; style roman; print " (for testing)^";
       style bold; print "John Campbell"; style roman; print " (for testing
       and programming advice)^";
       style bold; print "Michael Martin"; style roman; print " (for
       more testing and programming advice)^";
       style bold; print "Ian Urbina"; style roman; print " (for testing)^";
       style bold; print "Randolph Wang"; style roman; print " (for coming up
       with the idea in the first place)^";
];

[ CheatSub;
       if (match_started == false) "Don't get too hasty.";
       else {
       deadflag = 9;
       "With a grin, you reach forward and press the red robot's OFF button.
       You pummel him mercilessly until his head pops up. Your manager
       assured you that the judges wouldn't be able to tell it from any old
       knockout, but he was wrong. The judges quickly discover your foul
       play, and alert the authorities.";
       }
];

[ DistractSub;
       if (noun == player) "You never know what hit you.";
       "Who do you want to distract?";
];

[ GetSub;
       if (noun == player) "Yeah, you'll get you someday. Bastard.";
       "You quietly swear revenge.";
];

[ ThrowFightSub;
       deadflag = 7;
       print "You make only a token effort to defend yourself, allowing the
       red robot to pop your head up. It may not be a glorious way to go, but
       it is profitable. Your manager bet a ton of cash on the red robot, and
       you'll get your share of it, fair and square. There's a nice sprocket
       you've had your eyes on for a while, maybe a lube job.^^
       On your way out of the stadium, you are stopped by a small child.
       ~Why'd you lose, Blue? You never lose like that. You can't have lost
       like that.~^^
       Your ears burn with shame. ~Shut up, kid!~ you shout. You run to your
       waiting limo, and seat yourself. ";
       style underline; print "When did it even come to this,"; style roman;
       print " you think to yourself. "; style underline; print "I used to be
       a champ, and now I'm just trash."; style roman; print " You bury your
       face in your hands and sob.";
];


[ TalkSub;
       if (noun == nothing)
               "Who do you want to talk to?";
       if (noun == player)
               "It's said that that is a sign of mental illness.";
];

[ ThrowSub;
       if (noun == player)
               "You can't even lift yourself.";
];

[ WalkthroughSub;
       "Try punching the robot, perhaps.";
];

[ WaveToSub;
       if (noun == player)
               "Oh, come now. Are you just entering silly, implausible
               commands to see if I anticipated them? For shame, sir and/or
               madam!";
];

[ WinSub;
       "That's the general idea, yes.";
];


[ XyzzySub;
       if (france_visited == true) "Your magical powers are spent.";
       else {
       france_visited = true;
       move croissant to player;
       print "You close your eyes in deep concentration and intone the magical
       word XYZZY...^^
       You open your eyes and find yourself in a bakery in beautiful Paris!
       The baker smiles at you and presses something into your palm.^^~";
       style underline; print "Merci,"; style roman; print "~ you say.^^~";
       style underline; print "De rien,"; style roman; print "~ the baker
       replies.^^
       The spell wears off, and you find yourself back in the boxing
       ring.^";
       }
];

[ ZrblmSub;
       "Nothing heamy results from your zrblm.";
];

Verb meta 'about' 'credits'
       *                               -> About;

Verb 'cheat'
       *                               -> Cheat;

Verb 'defeat'
       * noun                          -> Win;

Verb 'distract'
       * noun                          -> Distract;

Verb 'have'
       * 'at' noun                     -> Attack;

Verb 'kung'
       * 'fu' noun                     -> Attack;

Verb 'leeg' 'leeging'
       *                               -> Mild
       * topic                         -> Mild;

Verb 'lose'
       *                               -> ThrowFight;

Verb 'talk'
       *                               -> Talk
       * 'to' noun                     -> Talk;

Verb 'rock' 'sock' 'pummel' 'r0xx0r'
       * noun                          -> Attack;

Verb meta 'walkthrough' 'help' 'hints'
       *                               -> Walkthrough;

Verb 'win'
       *                               -> Win;

Verb 'xyzzy'
       *                               -> Xyzzy;

Verb 'zrblm'
       *                               -> Zrblm;

Extend only 'bother' replace
       * noun                          -> Distract;

Extend only 'get' replace
       * multi                         -> Get;

Extend 'give'
       * creature 'what' 'for'         -> Attack;

Extend 'show'
       * creature 'what' 'for'         -> Attack;

Extend only 'throw' replace
       * multiheld                     -> Throw
       * noun                          -> Throw
       * 'the' 'fight'/'match'         -> ThrowFight
       * 'fight'/'match'               -> ThrowFight;

Extend 'wave'
       * 'to'/'at' noun                -> WaveTo;

!=============================================================================