! AskTellOrder by Irene Callaci ([email protected])
!
! The BeforeParsing() routine included below reparses the player's input,
! converting:
!
!               ASK/TELL THE NPC TO DO SOMETHING
! into
!               NPC, DO SOMETHING
!
! so that your NPC's orders routine can handle it. No modification to the
! grammar for ASK or TELL is required.
!
! BeforeParsing() is an Inform entrypoint, so include it after Verblib but
! before Grammar.
!
!       Irene Callaci    -      [email protected]
!       March 12, 1999
!
! Updates:
! 1. Added a switch to allow ASK NPC ABOUT <topic>, where <topic> includes the word 'to',
!    such as ASK COP ABOUT WITNESSES TO THE ACCIDENT -- January 5, 2000
! 2. Truncate input before retokenising -- January 5, 2000
! ---------------------------------------------------------------------------

[ BeforeParsing i j k w skip inc;
       i = 0; j = 0; k = 0; w = 0; skip = 0; inc = 0;

       ! Find verb_wordnum (usually 1, but not when the command is NPC, VERB THE <OBJECT>)
       for (i = 2 : i <= num_words : i++)
       {       w = NextWord();
               if (w == comma_word) break;
       }
       if (wn >= num_words) wn = 1;

       for (i = parse->2, j = 2 : j < i : j++)
       {       w = NextWord();
               switch (w)
               {       'ask', 'tell':
                               ! First, count any blank spaces at the beginning of input
                               for (i = 2 : i < buffer->1 : i++)
                               {       if (buffer->i == ' ') skip++;
                                       else break;
                               }

                               ! Next, count the number of letters in the first word (ASK or TELL)
                               skip = skip + WordLength(wn - 1) + 1;

                               ! Now get the next word. If it's an article, count the number of
                               ! letters it contains so we can overwrite it later. If we don't do
                               ! this, we end up with invalid input like: THE NPC, VERB
                               w = NextWord();
                               if (w == 'a//' or 'an' or 'the')
                               {       skip = skip + WordLength(wn - 1) + 1;
                                       w = NextWord();
                               }

                               ! Now we've reached a likely spot for the NPC's name. Because NPCs can
                               ! have more than one name (CHARLIE SMITH, for example), we loop until
                               ! we find the word "to" or some other word that signals the start of
                               ! the actual command.
                               while (w ~= 0)
                               {       ! We need to know how long the NPC name is so that we can skip over
                                       ! it later without overwriting it.
                                       inc = inc + WordLength(wn - 1) + 1;
                                       w = NextWord();
                                       switch (w)
                                       {       'about':
                                                       ! Stop reparsing here to avoid problems with ASK COP ABOUT WITNESSES TO THE ACCIDENT (otherwise, the 'to' below will trigger an NPC order)
                                                       rfalse;
                                               'to':
                                                       ! Find the word "to" in the input and replace it with a
                                                       ! comma followed by a blank (to erase the "o").
                                                       for (i = skip + inc + 1 : i <= (buffer->1) + 1 : i++)
                                                       {       if (buffer->i == ' ' && buffer->(i+1) == 84 or 116 && buffer->(i+2) == 79 or 111 && buffer->(i+3) == ' ')
                                                               {       buffer->(i+1) = 44;             ! ascii code for comma
                                                                       buffer->(i+2) = ' ';
                                                                       break;
                                                               }
                                                       }

                                                       ! Move the NPC's name and everything following it to the
                                                       ! left, overwriting as we go.
                                                       for (i = 2 : i <= (buffer->1) + 1 : i++)
                                                               buffer->i = buffer->(i + skip);

                                                       ! Truncate the command and retokenise the input.
                                                       buffer->1 = (buffer->1) - skip;
                                                       Tokenise__(buffer, parse);
                                       }
                               }
                       default:
                               rfalse;
               }
               break;
       }
];