!   ObjNameA.h          An Inform Library Extention.
!                       by Michael Roy ([email protected])
!                       Tested on Inform 6.21 with Library 6/9 and
!                       Inform Bi-Platform 6.21 with Library 6/10
!                       But should work with other versions
!
!  To allow objects with "a" in their name properties to parse correctly,
!  instead of as the indefinite article (which would set indef_mode)
!  (So if you don't have an object with name "a", you don't need this.)
!
!  Note:  This only allows one "a" object per room.  If you need more,
!         change ObjWithA to an array and the make relevant changes. Most
!         of the information about setting ObjWithA mention belowed can
!         be bypassed if your game only contains one object of this type
!         by setting ObjWithA = to it in your Initialise and not changing
!         it at all later on.
!
!      To use:
!        Include this file after Verlib.h and before Grammar.h
!        Set the object's properties like in the example
!        object below.
!        *OR*, if you only have one such object just set ObjWithA equal to
!        it in your Initialise().  This method is probably easiest.
!        Make sure to change the name and description properties
!
! Example Object:  The A string from a cello
!
!Object A_String "a string"
!  with name "string"     !change this
!            "a" "a,word" !keep "a" and "a,word" in your code
!       descripton "It's the A string from a cello.", !change this
!       initial [; ObjWithA = self; ],
!       react_after [; Go: if (TestScope(self, player) == 0)
!                      ObjWithA = 0;
!                   ];
!
! If the object is contained inside of another object, the initial()
! should be put in the objects parent and changed so that it sets
! ObjWithA to the appropriate child.
!
! Revision history:  July 11, 2000:  1.0:  First Release
!                    July 19, 2000:  1.1:  Fixes large dictionary bug
!
! Questions or bugs?  Email me at the address given above.

! Ensure compatibility with glulx, which uses four-byte words.
#ifndef WORDSIZE;
   Constant TARGET_ZCODE 0;
   Constant WORDSIZE 2+TARGET_ZCODE;   ! avoid compiler warning
#endif;

Global ObjWithA = 0;

[ BeforeParsing a_word_loc next_word x y;
 !Don't bother checking if the room doesn't have an A-named Object
 if (ObjWithA == 0) return;

 !If the object is out of scope, the player can't refer to it
 if (TestScope(ObjWithA, player) == 0) return;

 a_word_loc = -1;

 !Check through the word stream for "a"
#ifdef TARGET_ZCODE;
 y = parse->1;
#ifnot; ! TARGET_GLULX
 y = parse-->0;
#endif; ! TARGET_
 while(wn <= y)
 {
   x = (WordAddress(wn))->0;
   if((WordLength(wn) == 1) && (x == 'a'))
   {
     a_word_loc = wn;
     break;
   }
   wn++;
 }
 wn++;

 !If a_word_loc is still -1, we didn't find any a words in parse
 if(a_word_loc == -1) return;

 !check the next noun as a reference to ObjWithA
 next_word = NounWord();
 if( UnsignedCompare(next_word, 128) ) !matched a noun
 {
   x = ObjWithA.&name; y = x + ObjWithA.#name;
   for( : x < y: x = x + WORDSIZE) !loop through the names
     if( x-->0 == next_word) !if the word after "a" is obj
     {
#ifdef TARGET_ZCODE;
       parse-->(a_word_loc * 2 - 1) = 'a,word'; !change the word
#ifnot; ! TARGET_GLULX
       parse-->(a_word_loc * 3 - 2) = 'a,word'; !change the word
#endif; ! TARGET_
       return; !the change replaces the "a" with one of the obj's names
     }
 }
 !if the next word didn't match or wasn't a noun, a is for the indef. art.

 return;
];