CONCEPT
search
UPDATE
Mateese, 14-Nov-94 - 02:00 MET
SYNOPSIS
#include <search.h>
living->Search(what, mode)
living->SearchM(what, mode, pred)
container->Locate(what, mode, also)
DESCRIPTION
One of the bigger problems in LPMud is the proper retrieval of
objects of which only their id-string is given.
The traditional solution uses the efun present() in
combination with the lfun id() for this purposes, but it has
its severe limitations.
This mud implements a more powerful scheme of object
identification, using the lfuns id(), Search(), SearchM() and
Locate():
id()
is as usual called with a string as argument and has to
return non-zero if the string identifies the object.
Search() resp. the simul_efun search()
is available in livings only and performs a search for the
specified object(s) from the viewpoint of the living.
SearchM() resp. the simul_efun searchm()
is available in livings only and applies Search() on
several arguments, folding the results into a neat data
field.
Locate() resp. the simul_efun locate()
is available in all container-like objects and returns
those contained object(s) which match the given identification.
For non-wizards, invisible objects are not found.
Additional simulated efuns offer additional help:
- sort_findings() implements the most common treatment of
the results of SearchM().
- foundp() checks if a given object was found by SearchM().
- strip_a(), strip_article(), add_a() strip or add articles
from a string.
- norm_id() removes surplus spaces from id-strings.
This combo of functions is powerful enough to parse constructs
like 'all bags in chest', 'every torch outside' or 'my gem'.
id() matches just a simple adjective/id compound, called 'id',
like 'tool' or 'yellow flower'. Not all possible adjectives of
an object need to be specified, but all specified adjectives
must be valid.
Locate() matches 'simple things', which may be one of these
constructs:
'[the] ground'
'[the] floor'
'[the] here'
This refers to the object itself, unless its a living.
'floor' is only recognized by inside rooms.
'[a|an|the] <id>'
One or all objects matching this <id>, the article is
optional.
'[the] <number>. <id>'
'[the] <number>th <id>'
'[the] <verbose ordinal> <id>'
'[the] <id> <number>'
The <number>th object matching this <id>.
<verbose ordinal> are the ordinals 'first', 'second' up to
'twelveth'. The article is optional.
'all', 'everything'
All contained objects.
'[the] <plural-id>', 'all <plural-id>', 'every <id>'
All objects matching <id>, but each group considered an
entity (SEARCH_MULTI only).
'<count> <plural-id>'
As before, but additionally <count> is parsed and returned
(SEARCH_MULTI|SEARCH_COUNT only).
'<matched plural> except <matched id>'
'<matched plural> but <matched id>'
Using the constructs so far, this can select a whole group
with exceptions, like 'every yellow torch except the
second'.
'really <any of the above constructs>'
As above, but this time also wielded, worn and equipped
objects may be matched as well.
Search() works on those <thing>s (both singular and plural)
and handles the cooperation of the living with its
environment. It recognizes these constructs:
'outside'
Matches the current environment.
'<thing>'
The <thing> is searched according the search 'mode'.
'<thing> in <bag-thing>'
'<thing> from <bag-thing>'
'<thing> on <bag-thing>'
First <bag-thing> is/are searched, then <thing> is
searched in the found <bag-thing>s.
'my <thing>'
'my <thing> in <bag-thing>'
'<thing> in my <bag-thing>'
Searches <thing>/<bag-thing> just in the living itself
(not in SM_LOCATE mode).
'<thing> here'
'<thing> here in <bag-thing>'
'<thing> in <bag-thing> here'
Searches <thing>/<bag-thing> just in the livings surrounding
(not in SM_LOCATE mode).
'<any of the above constructs> outside'
Redefines the 'livings surrounding' as being one
environment farther outwards, and searches just there.
All in all, Search() is a complete replacement for present(),
the latter should thus not be used for real objects.
SearchM() extends Search() to handle lists of identifications.
Especially it recognises the constructs:
'<thing>'
'<thing> and <thing>'
'<thing, thing, ... , <thing>'
'<thing, thing, ... , <thing> and <thing>'
and calls Search() for each of the listed <thing>s.
DESCRIPTION -- Search
Search() is implemented in /std/living/description and just
calls the simulated efun search().
lfun: mixed Search (mixed what, int mode)
efun: mixed search (object this, mixed what, int mode)
<this> is the living, from which viewpoint the search happens,
or if SM_LOCATE is specified, the container within the
search shall happen.
<what> may be an object, an id-string, or an id-string
exploded by its spaces. If it is an object, the result is
either the object itself (if it is contained), or 0.
<mode> specifies where the living should search. Outside of
its inventory it must be able to see, unless SM_IGNLIGHT
is set.
Search() parses <what> to search the thing it specifies.
Sequences of spaces in <what> are considered as being just one
space.
If <what> contains the sequence 'my ' anywhere, the search
is narrowed to SEARCH_INV only (and 'my ' is removed from
<what).
Similar, if <what> contains the sequence ' here', the search
is narrowed to SEARCH_ENV only.
Is <what> is just 'outside', the immediate surrounding is
returned as result.
After this, <what> is checked against the constructs
'<what> in <subwhat>' resp. '<what> from <subwhat>'. If one of
both matches, <what> and <subwhat> are appropriately set.
Normally, SEARCH_ENV & co consider the immediate surrounding
of the livings as 'the' environment. But if <what> ends with
' outside' and the immediate environment is transparent
enough, 'the' environment is pushed one env outwards and the
search is narrowed to SEARCH_ENV only.
At this point, the real search starts, in the order as the
search <mode> determines.
In each searched container ('the' environment or the living
itself), Locate() is called to locate <what>. If something was
found and <subwhat> was specified, the located <what> are
considered itself containers and are called to Locate() <subwhat>.
The result (either Locate(<what>) or <what>->Locate(<subwhat>))
returned (more or less complete) as result.
Results:
0
no matching object was found.
<obj> (SM_OBJECT only)
({ <obj> }) (other modes)
a single object was specified and found.
({ <obj>, <obj>, ... <obj> })
The specified singular id matched a whole class of objects.
([ FOUND_SINGLE: ({ <obj> ... <obj> }) (SM_MULTI only)
, FOUND_CLASS : ({ <obj> ... <obj> })
, FOUND_MULTI : ({ <obj> ... <obj> })
, FOUND_NUMBER: <integer> ])
A plural id was specified and matched those objects of
FOUND_MULTI. If a count was specified (SM_COUNT only), it
is stored as FOUND_NUMBER.
FOUND_SINGLE and FOUND_CLASS contain non-plural matches,
which may happen, if one search has to find objects from
several containers ('get gems from all bags').
DESCRIPTION -- Locate()
Locate() is implemented in /std/room/restrictions and just
calls the simulated efun locate().
lfun: mixed Locate (mixed what, int mode, object * also)
efun: mixed locate (object this, mixed what, int mode, object * also)
<what> may be an object, an id-string or the id-string
exploded by spaces. If it is an object, the result is either
the object itself (if it is contained), or 0. If the player
can't see in the container and SM_IGNLIGHT is not set in
<mode>, the result is 0 as well.
For non-wizards, invisible objects are not found.
<also> (if specified) is a list of objects to be considered
part of <this> own inventory.
The results follow the same convention as those of Search().
Locate() searchs the thing <what> in the container. Sequences
of spaces in <what> are considered as being just one space.
Unless <what> starts with the keyword 'really', only those
objects may be found which are neither worn nor wielded.
If <what> is empty, 'all' or 'everything', the whole content
(modulo 'really') is returned, even if <mode> contains
SM_OBJECT.
If the container contains an object, which matches on
present(<what>, ...), this object is always included in the
result. For SM_OBJECT, it becomes _the_ result.
For the normal search mode, all contained objects are matched
against <what> and the list of matching objects is returned.
For SM_MULTI, Locate() tries to depluralize <what> into
one of these constructs: 'all <things>', 'every <thing>' or
'<things>'. The depluralizing of '<things>' is a simple
removal of a trailing '-s' resp. '-es'.
If SM_COUNT is specified as well, Locate() also tries to parse
a count '<number> <things>'.
The depluralized id is matched again against all contained
objects, and the thus created list is compared with the list
of the singular match. Objects contained in both lists are
considered 'ambiguous' and are collected in a separate list.
The compound of all three lists is then the result.
Note that the depluralizing done for SM_MULTI is quite
primitive.
Locked containers, or containers with a transparency below
SEARCH_MIN_TRANSP may refuse the location of things from
searchers outside.
DESCRIPTION -- Search Mode
An important value (besides the object identification itself)
is the search 'mode'. This is an integer consisting of several
bitflags and a small number, all ored (operator |) together.
The field 'SEARCH_WHERE' holds a small number determining
where the living should search for items:
- SEARCH_ENV_INV (0): first in its environment, then in its
inventory.
- SEARCH_ENV (1): just in its environment.
inventory.
- SEARCH_INV (2): just in its inventory.
inventory.
- SEARCH_INV_ENV (3): first in its inventory, then in its
environment.
Normally the functions get the singular id-string of an object
and search all objects matching this id-string. Result is then
the (possibly empty) array of the objects found. This
behaviour may be modified using bitflags:
- SM_OBJECT: result is the first object found matching
the id, or 0 if none was found.
- SM_MULTI: the given id may also describe multiple
objects ('all torches') or plurals at all ('bags').
- SM_COUNT: an additional flag to _MULTI, which enables
the parsing of the '<count> <plural_id>' construct in
Locate().
(SM_CMULTI is an alias for SM_MULTI|SM_COUNT)
- SM_REALLY: when set, Locate() needs the keyword 'really'
to locate worn or wielded objects.
- SM_IGNLIGHT: when set it determines that the
searching living need not to be able to see the objects
being searched (handles both light and blindness).
Searches in the inventory are always possible 'blind'.
- SM_LOCATE: when set it forces search()/searchm() to search
just in the given object <this>, effectively
implementing a hotted up <this>->Locate().
DESCRIPTION -- SearchM
SearchM() is implemented in /std/living/description and just
calls the simulated efun searchm().
lfun: mixed SearchM (mixed what, int mode, closure pred)
efun: mixed searchm ( object this, mixed what, int mode
, void|closure pred)
<this> is the living, from which viewpoint the search happens,
or if SM_LOCATE is specified, the container within the
search shall happen.
<what> may be an object, an id-string or an id-strings. If it
is an object, the result is either the object itself (if it is
contained), or 0.
<mode> specifies where the living should search. Outside of
its inventory it must be able to see, unless SM_IGNLIGHT
is set.
<pred> is a filter function which has to take an object as
first argument and which has to return non-zero if the object
should be considered for finding at all.
SearchM() parses <what> (resp. each entry of <what> if it is
an string array) for "," and " and " and generates thus a flat
array of id-strings to search. search() is then called for
each of these id-strings. The objects found are filtered
through the <pred>icate (default is 'accept all') and
collected. If an id-string could not be matched to an object,
the id-string is remembered and will be returned later.
If the <mode> is SM_OBJECT, the result is an array of objects
(and id-strings for those not found).
Else, the found objects are folded into an result array of
four result-arrays:
string *result[FOUND_IDS]
The id-strings which could not be located.
object *result[FOUND_SINGLE]
Those objects which could be unambiguously identified.
object *result[FOUND_CLASS]
Objects which matched a class id-string.
These are sub-organized into arrays for each class-match.
object *result[FOUND_MULTI]
Objects which matched a plural id-string.
These are sub-organized into arrays for each plural-match,
with each sub-array starting with parsed integer count (or
0 if there was none).
int result[FOUND_SPECS]
How much distinct object specifications have been processed
successfully.
It is guaranteed that the FOUND_SINGLE objects to not appear
in the other result-arrays.
If there is no data for one of the result types, the
associated entry is set to 0.
SEE ALSO
perception(C), foundp(SEFUN), sort_findings(SEFUN)