Constant DEBUG;

Constant Story "TIME AND DWARVES";
Constant Headline "^An Interactive Demo^";

Replace Keyboard;
Statusline time;

Include "Parser";

Global game_clock = 5000;

!  This is just the parser's ordinary keyboard routine copied out,
!  except that I've deleted the "undo" code (can you UNDO in a
!  real time game?  Hmm) and that there's a marked difference in
!  the middle part...

[ Keyboard  a_buffer a_table  nw i w x1 x2;

   DisplayStatus();
   .FreshInput;

!  Save the start of the table, in case "oops" needs to restore it
!  to the previous time's table

   for (i=0:i<10:i++) oops_workspace->i = a_table->i;

!  In case of an array entry corruption that shouldn't happen, but would be
!  disastrous if it did:

  a_buffer->0 = 120;
  a_table->0 = 64;

!  Print the prompt, and read in the words and dictionary addresses

   L__M(##Prompt);
   AfterPrompt();

! ----------------------------------------------------------------------
!   Here's the interesting bit: an ordinary Inform-style keyboard read
!   except that TimeRunning() is called every 10 tenths-of-a-second,
!   i.e., once every second.
! ----------------------------------------------------------------------

   DrawStatusLine();
   a_buffer->1 = 0; a_table->1 = 0;
   @aread a_buffer a_table 10 TimeRunning -> i;

   ! (i holds true if TimeRunning() interrupted us, but we ignore this)

! ----------------------------------------------------------------------

   nw=a_table->1;

!  If the line was blank, get a fresh line
   if (nw == 0)
   { L__M(##Miscellany,10); jump FreshInput; }

!  Unless the opening word was "oops", return

   w=a_table-->1;
   if (w == OOPS1__WD or OOPS2__WD or OOPS3__WD) jump DoOops;
   return nw;

   .DoOops;
   if (oops_from == 0)
   {   L__M(##Miscellany,14); jump FreshInput; }
   if (nw == 1)
   {   L__M(##Miscellany,15); jump FreshInput; }
   if (nw > 2)
   {   L__M(##Miscellany,16); jump FreshInput; }

!  So now we know: there was a previous mistake, and the player has
!  attempted to correct a single word of it.
!
!  Oops is very primitive: it gets the text buffer wrong, for instance.
!
!  Take out the 4-byte table entry for the supplied correction:
!  restore the 10 bytes at the front of the table, which were over-written
!  by what the user just typed: and then replace the oops_from word entry
!  with the correction one.
!
   x1=a_table-->3; x2=a_table-->4;
   for (i=0:i<10:i++) a_table->i = oops_workspace->i;
   w=2*oops_from - 1;
   a_table-->w = x1;
   a_table-->(w+1) = x2;

   return nw;
];

Include "VerbLib";

Class  Dwarf
 has  animate proper
 with name "dwarf",
      move_me
      [ rfrom rto;
          if (random(10) == 1)
          {   rfrom = parent(self);
              if (rfrom == Blue_Room) rto = Red_Room; else rto = Blue_Room;
              if (player in rfrom)
                  print "^", (name) self,
                      " wanders off into ", (the) rto, ".^";
              if (player in rto)
                  print "^", (name) self,
                      " strolls in from ", (the) rfrom, ".^";
              move self to rto;
          }
      ];

Object Blue_Room "Blue Room"
 has  light
 with description
         "A blue-painted room, bare of furniture, with a
          corridor leading east.",
      e_to Red_Room;

Dwarf -> "Thorin";
Dwarf -> "Gimli";
Dwarf -> "Igneous";

Object Red_Room "Red Room"
 has  light
 with description
         "A red-painted room, bare of furniture, with a
          corridor leading west.",
      w_to Blue_Room;

Dwarf -> "Sleepy";
Dwarf -> "Dopey";
Dwarf -> "Doc";

[ TimeRunning o;

 !  Runs once per second of "real time"

 !  Every ten seconds, one minute of "game time" passes

 game_clock = (game_clock+1) % 14400;
 if (game_clock % 10 == 0)
 {   SetTime(game_clock/10);
     DisplayStatus();
     DrawStatusLine();
 }

 !  Every second, every dwarf has the opportunity to move

 objectloop (o ofclass Dwarf) o.move_me();
 rfalse;
];

[ Initialise;
 location = Blue_Room; SetTime(game_clock/10); DisplayStatus();
"^^^^^Welcome to the...^";
];

Include "Grammar";