! ----------------------------------------------------------------------------
! ADNAME - This Inform library provides a system of 'adnames', words which may
! be used to refer to objects without themselves implicating that the
! object name has been typed. For example, you'd want "GET TOILET
! PAPER" to choose the toilet paper, but you wouldn't want "GET
! TOILET" to, especially if there was also a toilet in scope.
! Adnames are typically adjectives or other describing words (in the
! above example, "TOILET" is the adname of the toilet paper). If you
! want to give an object an adname, make it of class "adnc" and give
! it the "adname" property. This property, like "name", takes a list
! of dictionary words. Caution: unlike name, which is a special case,
! adname names are in single quotes.
!
! This library provides a solution similar to the answer to example
! 60 in the Inform Designers' Manual, except that groups of identical
! objects are handled correctly. There is also (for flexibility) no
! requirement that adnames come before names.
!
! Example object coffin_stand "coffin stand"
! class adnc
! with
! name "stand",
! adname 'coffin' 'wooden',
! description "You can refer to this smart wooden coffin \
! stand as 'coffin stand', but 'coffin' on its \
! own will mean the coffin itself.",
! has
! static;
!
! Include this library before you define your objects.
! (c) Andrew Clover, 1995, but freely usable. Release 1.
! Compatible with Inform 5.5, library 5/12.
! ----------------------------------------------------------------------------
Property adname;
Class adnc
with
adname 0,
parse_name
[;
return AdnameParser(self); ! Calling another routine like
! this avoids excessive code
! duplication, and allows you
! to extend an object's parse_
! name routine whilst still
! calling the adname parser.
];
[ AdnameParser adobj w n i j a b succ fail;
if (parser_action==##TheSame)
{
w= parser_one.&adname;
n= (parser_one.#adname)/2;
i= parser_two.&adname;
j= (parser_two.#adname)/2;
for (a= 0: a<n: a++)
{
fail= 1;
for (b= 0: b<j: b++)
if ((w-->a)==(i-->b))
fail= 0;
if (fail==1)
return -2;
}
for (a= 0: a<j: a++)
{
fail= 1;
for (b= 0: b<n: b++)
if ((w-->b)==(i-->a))
fail= 0;
if (fail==1)
return -2;
}
return 0; ! This bit adapted from the parser
! - check all words in adname of
! parser_one to see if they occur
! in adname of parser_two, then
! vice-versa. If either case is
! false, we say the objects are not
! the same (the player may type a
! word that distiguishes then); if
! both are true, we give the parser
! a crack at seeing if they're
! different (by looking at the name
! property).
}
else
{
n= 0;
succ= 0;
fail= 0;
while (fail==0)
{
fail= 1;
w= NextWord();
for (i= 0: i<(adobj.#adname)/2: i++)
{
if (w==adobj.&adname-->i)
fail= 0;
}
for (i= 0: i<(adobj.#name)/2: i++)
{
if (w==adobj.&name-->i)
{
fail= 0;
succ= 1;
}
}
n++;
}
if (succ==1)
return n-1;
else
return 0; ! This is the bit of code executed
! normally (when the parser isn't
! trying to resolve identical
! objects). We just check that
! every word typed is in the adname
! or name property, and say that
! the phrase matches the object if
! any words are in the name.
}
];