! -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
!  `floating_contents': a new system for handling floating objects in Inform;
!                       either complements or replaces `found_in'.
!  Giftware by Julian Arnold 1995 (Public Domain) Release 2.
! -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

! ===========================================================================
!  The following declares a new property, `floating_contents'.  This can be
!  thought of as `found_in' in reverse.  Thus, one might normally have object
!  definitions such as:
!    #OBJECT trees "trees"
!       with ...
!            found_in East_Woods  North_Woods  South_Woods  West_Woods,
!            ...
!    #OBJECT bushes "bushes"
!       with ...
!            found_in East_Woods  North_Woods  South_Woods  West_Woods,
!            ...
!
!  With the `floating_contents' property this becomes:
!    #OBJECT East_Woods "East woods"
!       with ...
!            floating_contents trees  bushes,
!            ...
!    #OBJECT North_Woods "North woods"
!       with ...
!            floating_contents trees  bushes,
!            ...
!    Et cetera, et cetera.
!
!  I have found that source using `floating_contents' is far easier to read
!  and keep track of than the equivalent using `found_in', particularly when
!  location definitions are in a different file to other object definitions.
!  `found_in' has the benefit of being able to be a routine, which
!  `floating_contents' may not be.  However, I have found this not to be a
!  very great problem in practice as routines are not often needed under such
!  circumstances. Otherwise, `floating_contents' has the same limitations as
!  `found_in'.  In any case I have included below two methods to set up
!  `floating_contents'.  The first will declare an additional property, but
!  allows the continued use of `found_in'.  There would then be no problems
!  with using, say, `found_in East_Wood' in the trees object and
!  `floating_contents trees' in the East_Wood object at the same time in
!  one's source.  The second actually replaces the `found_in' property with
!  `floating_contents' so no extra property space is taken up.  This will
!  also (marginally) speed up your game, as `found_in' necessitates searching
!  through all the objects in the game every turn, while `floating_contents'
!  on its own only considers the current location object and any "contained"
!  objects.  However, this method will preclude the use of `found_in' in your
!  source (or rather you can use it, it just won't work).  It might be
!  possible to change `MoveFloatingObjects' so `floating_contents' could be a
!  routine, but in such a case `floating_contents' would need very careful
!  management by the author, and its nature would negate any speed increase,
!  so I don't think it's worth doing.
! ===========================================================================


! ---------------------------------------------------------------------------
!  METHOD A:  use either `floating_contents' or `found_in' or both, but eats
!             up one property.
! ---------------------------------------------------------------------------

! These two declarations should be dropped into your source *before* you
! #INCLUDE "verblib";
#REPLACE MoveFloatingObjects;
#PROPERTY floating_contents;

! Then put this routine into your code wherever you normally keep #REPLACEd
! routines.
[ MoveFloatingObjects i k l m f_address c_address;
  for (i=selfobj+1: i<=top_object: i++)
  {   f_address=i.&found_in;
      if (f_address~=0 && i hasnt absent)
      {   if (ZRegion(f_address-->0)==2)
          {   if (indirect(f_address-->0)~=0) move i to location;
          }
          else
          {   k=i.#found_in;
              for (l=0: l<k/2: l++)
              {   m=f_address-->l;
                  if (m==location || m in location) move i to location;
              }
          }
      }
  }
  c_address=location.&floating_contents;
  if (c_address~=0)
  {   k=location.#floating_contents;
      for (l=(k/2)-1: l>=0: l--)
      {   m=c_address-->l;
          if (m hasnt absent) move m to location;
      }
  }
];

! That's it.  Now just remember the rules I've outlined above.


! ---------------------------------------------------------------------------
!  METHOD B:  use `floating_contents' only.  `found_in' will not work
!             properly, but at least no extra properties are used.
! ---------------------------------------------------------------------------

! This declaration should be dropped into your source immediately after you
! #INCLUDE "parser"; (BTW, it says in parser not to alias `found_in', but it
! seems to work in this case, perhaps because `floating_contents' does almost
! the same job)...
#PROPERTY floating_contents alias found_in;

! ...and this one *before* you #INCLUDE "verblib";
#REPLACE MoveFloatingObjects;

! Then put this routine into your code wherever you normally keep #REPLACEd
! routines.
[ MoveFloatingObjects k l m c_address;
  c_address=location.&floating_contents;
  if (c_address~=0)
  {   k=location.#floating_contents;
      for (l=(k/2)-1: l>=0: l--)
      {   m=c_address-->l;
          if (m hasnt absent) move m to location;
      }
  }
];

! Again that's it, just remember `found_in' no longer works.
