/* This is a demo of TADS 2.2 features. */

#include <adv.t>
#include <std.t>

modify global
 file = 0
 name = 0
  sex = 0
 rabbitdone = nil
;

// This first demo shows how to use the new save to file/restore from file
// features in TADS 2.2.  It will ask your name initially, and then every
// time after that, greet you by name.  Oh yes, it also finds out your sex
// and gives you a proper title.

linit: function
{
 global.file := fopen('save.sav', 'r');
 if (not global.file) {
     "\b\bSay, I see we have a first timer here tonight.  What's your name?";
       global.name := nil;
       global.sex := nil;
       while (global.name = nil) {
        "\n>";
        global.name := input();
       }
       "Great, welcome to the demo, \^<<global.name>>.  Are you <m>ale or
       <f>emale?";
       while (global.sex <> 'm' and global.sex <> 'f') {
        "\n>";
        global.sex := input();
       }
 global.file := fopen('save.sav', 'w');
       if (fwrite(global.file, global.name) or fwrite(global.file,
       global.sex)) {
         "Error writing to disk.  Possibly a full disk.";
         quit();
         abort;
       }
       fclose(global.file);
       intro();
 }
 // Now for a repeat player, we load up their name and greet them.
 else {
 fseek(global.file, 0);
 global.name := fread(global.file);
 fseek(global.file, ftell(global.file));
 global.sex := fread(global.file);
 if (global.sex = nil or global.name = nil) {
    "File error.  Please delete save.sav and restart. ";
    quit();
    abort;
 }
 // Now we've loaded it up, let's greet the user.
 "\bWelcome back, ";
 if (global.sex = 'm') "Lord ";
 if (global.sex = 'f') "Lady ";
 say(global.name);
 ".  I trust you are well rested after your vacation.\b";
 incscore(1);
      }
}
;

intro: function
{
 "\b\bThis is a demo. I repeat, this is only a demo.  This demo is a test of
the TADS 2.2 system.  If it had been an actual game, this message would have
been followed by an announcement of where to go and what to do.\b\b\b";
}
;

startroom: room
 sdesc = "The Start"
 ldesc = "This is an empty room, filled with useless cobwebs and dust.
       There are rooms to the west, north, and east."
  west = MagicRoom
  east = PolymorphRoom
 north = PointerRoom
;

// Magician's hat demo.  This part of the demo shows an example of the
// new dynamic creation and destruction capabilities of TADS.

MagicRoom: room
 sdesc = "Magic Room"
 ldesc = "This room is filled with old magic tricks, trunks, bunks, and
       gunks.  None of these are useful to you in any way of course, since
       this is only a demo and not a REAL game. "
 east = startroom
;

MagicHat: clothingItem
 noun = 'tophat' 'hat'
 adjective = 'magic' 'magician\'s'
 sdesc = "top hat"
 location = MagicRoom
 ldesc = "Hmm, funny, but you suddenly know that you can pull an infinite
       number of rabbits out of this hat.  Do this by typing 'pull hat',
       since I don't want to muck about with disambiguation."
 verDoPull(actor) =
 {
       if (self.worn) "Not while wearing it.";
 }
 doPull(actor) =
 {
       local rabbit;

   rabbit := new Rabbit;  // Wham, a rabbit is born.
   rabbit.moveInto(Me.location);
   "You reach in, pull out a rabbit, and dump it on the ground. ";
 }
;

Rabbit: item
 noun = 'rabbit' 'bunny'
 adjective = 'bunny'
 plural = 'rabbits'
 isEquivalent = true
 sdesc = "fuzzy rabbit"
 ldesc = "A cute little bunny rabbit, learning to multiply...HeY! This is a
       family demo!  Go elsewhere to do that sort of thing, rabbit. "
 verDoTake(actor) = {}
 doTake(actor) =
 {
    "You pick up the rabbit and stuff it squealing back into the hat. ";
    if (not global.rabbitdone) {
      incscore(1);
      global.rabbitdone := true;
    }
    delete self;  // Hey Mike, try typing 'again' after 'get rabbit'.
 }                // Gives an error since the original rabbit is gone,
                  // yet there are still valid rabbits there.
;

// The polymorph is an example of what can be done with the dynamic
// vocabulary changing now availlable in TADS.  You can have changeable
// creatures with states that exist only in one form or another.  Very nifty.

PolymorphRoom: room
 sdesc = "The Polymorph's Lair"
 ldesc = "The room is empty, except for the polymorph.  The passage leads
       back to the west. "
 started = nil
 enterRoom(actor) =
 {
   if (not self.started) {
    Polymorph.start;
    self.started := true;
   }
    pass enterRoom;
 }
 west = startroom
;

Polymorph: item
 namelist = ['rock' 'fluff' 'sausage' 'doll' 'clock' 'bomb']
 desclist = ['A rock.' 'A normal old fluff.' 'A small brown
       sausage.' 'A child\'s doll.' 'A ticking clock.' 'An atomic bomb,
       complete with a button to push.']
 noun = 'polymorph'
 oldnum = 0
 sdesc = "polymorph"  // Any thoughts how to make this change too?
 location = PolymorphRoom
 verDoEat(actor) = {}
 doEat(actor) =
 {
   if (self.oldnum <> 3) {
     "Yuck, you can't eat that!\n";
   } else {
     "There is a tiny scream as you eat the polymorph.  Murderer.\n";
     unnotify(self, &change);
     incscore(1);
     self.moveInto(nil);
   }
 }
 buttonThere =
 {
    if (self.oldnum <> 6) return(nil);
    return(true);
 }
 start =
 {
    local h;

    h := rand(length(self.namelist));

    "\bSuddenly, you see the rock ";
    if (self.location = Me) { " you posses "; } else { " nearby "; }
    "transform, through a series of eyetwisting maneuvers, into a ";
    say(namelist[h]);
    "!\b";
    addword(self, &noun, namelist[h]);
    oldnum := h;
    notify(self, &change, 4);
 }
 change =
 {
    local h;

    h := rand(length(self.namelist));
    if (self.location = Me.location or self.location = Me)
    {
    "\bSuddenly, you see the ";
    say(namelist[oldnum]);
    if (self.location = Me) { " you posses "; } else { " nearby "; }
    "transform, through a series of eyetwisting maneuvers, into a ";
    say(namelist[h]);
    "!\b";
    addword(self, &noun, namelist[h]);
    delword(self, &noun, namelist[oldnum]);
    oldnum := h;
    }
    notify(self, &change, 4);
 }
 ldesc = { say(self.desclist[oldnum]); "\n"; }
;

// The polymorph's button.  A simple hack that just gets the job done.

Button: floatingItem, fixeditem
 noun = 'button'
 isListed = nil
 ldesc = "A large, tempting, candy-like button."
 locationOK = true
 location = { return(Polymorph.location); }
 verDoPush(actor) =
 {
       if(not Polymorph.buttonThere) "I don't see any button here.\n";
 }
 doPush(actor) =
 {
    "Brilliant work, Sherlock.  The bomb explodes, splattering you all
    over the walls. ";
    die();
    abort;
 }
;

// PointerRoom has a basic example of a new, simpler notation for doSynonym
// etc.

PointerRoom: room
 sdesc = "An office"
 ldesc = "This office is sparsely furnished, yet elegant."
 south = startroom
;

// Swiped directly from M. Roberts.  Blame it on him. :)

desk: fixeditem
 isListed = true
 noun = 'desk'
 ldesc = "The desk has a drawer in it. "
 sdesc = "desk"
 location = PointerRoom
 doOpen -> deskDrawer
 doClose -> deskDrawer
;

deskDrawer: openable, fixeditem
 noun = 'drawer'
 adjective = 'drawer'
 isopen = nil
 ldesc = {
  "The drawer is "; if(self.isopen) "open. "; else "closed. ";
 }
 verDoOpen(actor) = { if (global.score < 3) {
   "It appears your score is not high enough to open it. "; }
 }
 location = desk
;

Note: item
 noun = 'note' 'paper'
 sdesc = "yellowed note"
 ldesc = { self.doRead(Me); }
 location = deskDrawer
 verDoRead(actor) = {}
 doRead(actor) = {
  "You scan the page.  It says:\b
 \t\"Well, it appears you have examined all the stuff in my short demo of\n
 \tTADS 2.2.  I neglected to use any of the new C operators like \>\> or\n
 \t|=.  I also neglected to use the new conditional compilation features\n
 \tlike #define and #ifdef.  But in any event, I have made an attempt to\n
 \tcover my favorite additions to TADS.  Filfre to demonstrate your own.\"\b
 Hmm.  An odd note.  I guess it means that this is....\b
 \t\ \ \ \ \ \ \ \ \ \ \ THE END.\b";
 }
;