npc

std
PRELIMINARY 
OBJECT
	/std/npc


LAST UPDATE
	Mateese, 06-Aug-96 21:00 MET


SYNOPSIS
	#include <npc.h>
	#include <search.h>
	inherit "/std/npc";

	    OR

	clone_object("/std/npc");

DESCRIPTION

	The several modules are:
	  /std/npc/body     : Health and death.
	  /std/npc/chat     : Question, Answers and Mumbles.
	  /std/npc/cmds     : Miscellanous commands.
	  /std/npc/putget   : Handling of things.
	  /std/npc/view     : Sensing of things.


DESCRIPTION - /std/npc/body
	This module implements the extended health functions and
	attributes of NPCs. Most of all, it adds alcohol, food and
	drink to the body.

	If the NPC is drunk, it heals faster. On the other hand, if
	it's hungry or thirsty, it heals slower. If it's nearly
	starving or drying out, it's HP are continually reduced, down
	to a minimum value of 10.


	Following attributes and properties are builtin:

	  int A_MAX_ALCOHOL  "MaxAlcohol"
	  int A_MAX_DRINK    "MaxDrink"
	  int A_MAX_FOOD     "MaxFood"
	    The max amount of alcohol, food or drinks the npc may
	    have.

	  int A_ALCOHOL      "Alcohol"
	  int A_DRINK        "Drink"
	  int A_FOOD         "Food"
	    The current amount of alcohol, food or drinks the npc
	    currently had.
	    Food and drink may go negative, where they hinder any
	    healing process.

	  int A_DEG_ALCOHOL  "DegAlcohol"
	  int A_DEG_DRINK    "DegDrink"
	  int A_DEG_FOOD     "DegFood"
	    The degeneration rate of A_ALCOHOL, A_DRINK and A_FOOD,
	    measured in 1/100 points per heartbeat.
	    These are initialized to ALCOHOL_DEG, DRINK_DEG and
	    DEG_FOOD from /sys/health.h .

	  int A_RATE_ALCOHOL  "RateAlcohol"
	    The added regeneration rate the NPC has when being drunk.
	    This value is added to its intrinsig A_RATE_HP/A_RATE_SP.
	    It is initialized to ALCOHOL_RATE from /sys/health.h .

	  int AddAlcohol (int strength)
	  int AddDrink   (int strength)
	  int AddFood    (int strength)
	    Change the amount of A_ALCOHOL, A_DRINK and A_FOOD by
	    <strength>. Result is the value by which the amount was
	    actually changed. So if the intended change would exceed
	    the MAX_-value, nothing is changed and 0 is returned.

	  void DoDigest ()
	    To be called from heartbeat, this function changes A_FOOD
	    and A_DRINK accordings to its A_DEG-rates, and also deals
	    with the HP reduction for starving or drying-out livings.
	    If the attribute values fall below 0, suitable messages
	    are printed.
	    For interactive livings, the HEART_HEAL heartbeat is
	    started.
	    The function has no effect when called for a wizard or a
	    ghost.


	These functions are redefined:

	  int QueryRegHP()  A_REG_HP
	  int QueryRegSP()  A_REG_SP
	    According to the levels of A_ALCOHOL, A_DRINK and A_FOOD,
	    the actual A_REG-rate is modified.
	    If the lifing is drunk, A_RATE_ALCOHOL is added.
	    If the lifing is hungry or thirsty, A_RATE_HP resp.
	    A_RATE_SP is subtracted.
	    The modified rate is then returned.

	  void Death()
	    Called in the moment of death, this function calls the
	    lfun second_life() in the NPC. If this function does not
	    exist or returns 0, the inherited Death() is called which
	    will destruct the NPC.

	  void heart_beat()
	    The heart_beat function extends the normal inherited
	    heart_beat() by the alcohol handling.
	    If the NPC is drunk, messages are written on occasion, and
	    the degeneration of A_ALCOHOL is handled.
	    For interactive beings, DoDigest() is called.
	    Note: for non-interactive beings, you have to call
	    DoDigest() yourself.


	The module is initialised in

	  void create ()


	These functions are assumed as being available in other
	modules:
	  std/living/heart	 : DropHeart(), GetHeart(), CheckHeart()


DESCRIPTION - /std/npc/chat
	One important thing about livings is the ability to chat and
	to answer question.

	  int P_CHAT_CHANCE  "ChatChance"
	    A value in 0..100 giving the chance per heartbeat that
	    the living will say something.
	    Setting the value to something non-zero will (re)start the
	    call_outs to OneChat().

	  int P_ACHAT_CHANCE  "AChatChance"
	    A value in 0..100 giving the chance per combat round that
	    the living will say something.

	  mixed * P_CHATS  "Chats"
	    The collections of chats to be said over the time.
	    Each chat can be a string, which is just said, or a
	    closure, which is called to return the string to say (or 0
	    to be silent).

	  mixed * P_ACHATS  "AChats"
	    The collections of chats to be said during combat.
	    Each chat can be a string, which is just said, or a
	    closure, which is called with the current enemy as
	    argument to return the string to say (or 0 to be silent).

	The chatting is done using self-initiated call_outs to this
	function:

	  void DoChat ()
	    This function does one chat by selecting randomingly one
	    from P_CHATS and saying it.

	  void OneChat (int justSched)
	    If <justSched> is zero, one call to DoChat() is made.
	    In all cases, a call_out with an delay approbiate to
	    P_CHAT_CHANCE is scheduled to OneChat() to continue
	    chatting IF there is a living around to hear it.
	    If P_CHAT_CHANCE is zero, nothing is scheduled.

	  void DoAttackChat (object enemy)
	    This function issues an randomingly selected attack chat
	    from P_ACHATS to the room, if the P_ACHAT_CHANCE permits.
	    It is called directly by the combat heartbeat.

	These functions ease the initialization of the chats:

	  void InitChats (int chance, mixed *strs)
	    Sets P_CHAT_CHANCE to <chance> and P_CHATS to <strs>.

	  void InitAChats (int chance, mixed *strs)
	    Sets P_ACHAT_CHANCE to <chance> and P_ACHATS to <strs>.


	The living is also able to react on things it hears using 'talks'.
	Everything it hears is parsed to be one of this forms:

	  '<who> <type><match> <what>'
	  '<who> <type><match><what>'
	  '<who> <type><match>'
	  '<who> <type> <match> <what>'
	  '<who> <type> <match><what>'
	  '<who> <type> <match>'

	<type> and <match> are predefined (default is the empty string ""),
	<who> and <what> are parsed from the message heard.

	So every talk is described by <type> and <match>, and if a
	parse was successful, the <who> (and possible <what>) are
	given to an 'talkfun'ction in a 'talkobject' to process.

	  string P_TALK_MATCH  "TalkMatch"
	    An array of <match> strings.

	  string P_TALK_TYPE   "TalkType"
	    An array of <type> strings.

	  mixed  P_TALK_FUN    "TalkFun"
	    An array of function designations.
	    Each can be the string with a function name, or a closure.

	  int	 P_TALK_DELAY  "TalkDelay"
	    An array of integers defining the delay between the match
	    of a talk and the call to its function. 0 means no delay.

	  mixed  P_TALK_OBJ    "TalkObject"
	    The talk object to call the talk function in.
	    It can be given as string with the object name, or as
	    actual object.
	    Talks for which a closure is set as function, ignore the
	    talkobject.

	  void void InitMatch ( mixed  *fun  , string *type
			      , string *match, object ob   )
	    Sets P_TALK_FUN from <fun>, P_TALK_TYPE from <type>,
	    P_TALK_MATCH from <match> and P_TALK_OBJ from <obj>.

	  mixed TestMatch (string str)
	    Match the given <str> against all set talks and return the
	    result of the talkfunction call (or 0).


	Finally, the living can react on questions.
	This is implemented as a command 'ask' bound to the function
	fask().
	The answers (and the default 'shrug message') can be set as
	strings or as closures. In the latter case, the closure is
	evaluated when needed with the questioned keyword as argument
	and has to return the actual answer.
	A third possibility is to set the answer/shrugmessage to an
	array of two strings - the first is sent to the player asking,
	the second the the environment. As 0 or "" entries are
	ignored, 'silent' asking is possible (only the asking player
	hears the answer).

	  mapping P_QUESTIONS  "Questions"
	    A mapping containing the answers, indexed by the key
	    strings in a question.
	    To ease initialisation, the property may be _set_ using a
	    flat array of: ({ <question>, <answer>, <question>,
	    <answer>... }), whereas each <question> may be a single
	    string, or an array of strings which then all get the same
	    answer.

	  void AddQuestion (string q, mixed a, void|int silent)
	    Add an answer <a> for the question <q>.
	    Setting <silent> to non-zero is an easy way to specify
	    'silent' answers:
	       AddQuestion("foo", "bar", 1)
	    is equivalent to
	       AddQuestion("foo", ({ "bar", 0 }))

	  mixed P_SHRUG_MSG   "ShrugMsg"
	    The default answer given if a living does not know the
	    answer to a question. As the answers, this may be a string
	    or a closure. If not set, "<name> shrugs helplessly." is
	    used as default.

	Each question must be unique!
	The function called for a question 'asked', is

	  int fask (string str, void|int inh)
	    Accept a question of type 'ask <living name> about <q>'
	    and write the answer if <q> is one of the set questions in
	    P_QUESTIONS.
	    <living name> must be of course the asked living.
	    If the command fails, a decent failure message is set
	    using notify_fail().
	    If <inh> is non-zero, the function returns a special
	    code on failures instead of the normal 0:
	      ASK_OK	    : question understood and answered
	      ASK_NO_ARG    : <str> is missing
	      ASK_CANT_PARSE: <str> is not of the required format,
			      or <living name> does not denote this
			      living
	      ASK_SHRUG     : question understood, but no answer was
			      provided.
	    By overloading fask() and using these codes more complicated
	    questions can be added.

	The following standard functions are used to implement talks
	and questions:

	  void catch_tell (string str)
	    This will get all the messages from outside.
	    If no talk object is set, or the living hears itself,
	    nothing is done.
	    Else the <str> heard is passed to TestMatch().
	    Recursion is prevented using a semaphore scheme and a
	    buffer.

	  void ResetSema ()
	    Reset semaphore and buffer of catch_tell().
	    Use this in emergencies only!

	  void init ()
	    If questions are set, the command 'ask' is bound to
	    fask().

	These functions are assumed as being available in other
	modules:
	  /std/thing/description : norm_id()
	  /std/living/description: QueryName()


DESCRIPTION - /std/npc/cmds
	This module implements several miscellaneous commands: vis,
	invis.

	Where necessary, a separate 'action' function is available
	beside the normal command function bound to the verb.

	The command functions, which are called from player/NPC
	commands parse the arguments, are:

	  int finvis (string arg)
	    Implements 'invis'.

	  int fvis (string arg)
	    Implements 'invis'.


	The command functions are bound to the actions in this
	function, which has to be called during create():

	  void add_npc_cmds()


	These functions are assumed as being available in other
	modules:
	  /std/living/attributes: QueryAttr(), SetAttr().


DESCRIPTION - /std/npc/putget
	This module implements the take/get, put, drop and give
	commands. Available are both the simple command functions as
	well as the 'real' action functions.

	  mixed * DropTake (string verb, mixed what, int mode)
	    Drop (<verb> == "drop") or take (<verb> == "take") the
	    objects <what> using <mode>.
	    The NPC can drop just those things carried somewhere, and
	    take just those things not carried on top-level.
	    <what> may be a single id-string, an object, or an array of
	    objects and id-strings. The objects for the id-strings are
	    Search()ed using SEARCH_MULTI. If the bitflag
	    PUTGET_REALLY is set in <mode>, wielded/worn equipment
	    items are handled automatically.
	    If the bitflag PUTGET_SILENT is not set in <mode>, the
	    function issues appropriate messages.
	    Result is 0 if the things to move haven't been found
	    (notify_fail() is set then), or on success either a simple
	    (but possibly empty) array of the things moved.
	    If the bitflag PUTGET_FULL is set in <mode>, the success
	    result is an array of five sub-arrays:
	      object * res[PUTGET_OK]:
	        The objects moved.
	      object * rec[PUTGET_NODROP]: 
	        The objects unmoved because of a P_NODROP/P_NOGET setting.
	      object * rec[PUTGET_NOMOVE]:
	        The objects unmoved because of a missing move() lfun.
	      object * rec[PUTGET_NOLEAVE]:
	        The objects unmoved because they couldn't leave their
	        environment.
	      object * rec[PUTGET_TOOHEAVY]:
	        The objects unmoved because they didn't fit into their
	        destination.


	  mixed * GivePut (string verb, mixed what, mixed to, int mode)
	    Give (<verb> == "give") the objects <what> to the living
	    <to> or put (<verb> == "put") the objects into the thing
	    <to>, using <mode>.
	    The NPC can give/put the things it carries somewhere, but
	    also the things lying in the room around him.
	    Though, the latter are taken first (after giving the
	    carried items away) using DropTake("take",...), and are
	    then given away by a scheduled call_out() to GivePut().
	    <what> may be a single id-string, an object, or an array of
	    objects and id-strings. The objects for the id-strings are
	    Search()ed using SEARCH_MULTI. If the bitflag
	    PUTGET_REALLY is set in <mode>, wielded/worn equipment
	    items are handled automatically.
	    <to> can be an object or an id-string, the latter being
	    searched as a single object.
	    <mode> and result are like DropTake(), except that objects
	    which were taken first are already included as
	    '_OK'-objects.


	  mixed * EquipLayoff (string verb, mixed what, int mode)
	    Equip (<verb> == "equip") or unequip (<verb> == "layoff")
	    the living with/of the objects <what> using <mode>.
	    The NPC can equip itself just with those things carried on
	    skin, but unequip of any object in the vicinity.
	    <what> may be a single id-string, an object, or an array of
	    objects and id-strings. The objects for the id-strings are
	    Search()ed using SEARCH_MULTI. If the bitflag
	    PUTGET_REALLY is set in <mode>, wielded/worn equipment
	    items are handled automatically.
	    If the bitflag PUTGET_SILENT is not set in <mode>, the
	    function issues appropriate messages.
	    Result is 0 if the things to move haven't been found
	    (notify_fail() is set then), or on success either a simple
	    (but possibly empty) array of the things moved.
	    If the bitflag PUTGET_FULL is set in <mode>, the success
	    result is an array of five sub-arrays:
	      object * res[EQUIP_OK]:
	        The objects handled.
	      object * rec[EQUIP_NOEQUIP]: 
	        The objects not handled because they already were
	        equipment, or aren't the NPCs equipment.
	      object * rec[EQUIP_FAIL]:
	        The objects which ignored the setting of P_EQUIPPED.


	Access to these functions is made easy using the following
	following functions, which are also recommended for everyday
	use.

	  mixed * Drop (mixed what, int mode)
	  mixed * Take (mixed what, int mode)
	  mixed * Give (mixed what, mixed to, int mode)
	  mixed * Put (mixed what, mixed to, int mode)
	    Parameters and result see DropTake() and GivePut().

	  mixed * Equip (mixed what, int mode)
	  mixed * Layoff (mixed what, int mode)
	    Parameters and result see EquipLayoff().


	The action functions are bound to a set of command functions,
	which are called from player/NPC commands and parse the
	arguments.
	Each of the functions allows the specification of a list of
	objects (e.b. "torch, beer from bag and car") for the objects
	being moved. As usual, they return non-zero on success.

	  int fdrop (string arg)
	    Implements 'drop <thing(s)>'

	  int ftake (string arg)
	    Implements 'take <thing(s)>', which is also aliased to
	    'get <thing(s)>'.

	  int fgive (string arg)
	    Implements 'give <thing(s)> to <someone>'.

	  int fput (string arg)
	    Implements 'put <thing(s)> into <something>'.

	  int fequip (string arg)
	    Implements 'equip [with] <thing(s)>'.

	  int flayoff (string arg)
	    Implements 'lay [aside|down] <thing(s)>'.

	The command functions are bound to the actions in this
	function, which has to be called during create():

	  void add_putget_cmds()


	The module features several auxiliary functions which help in
	constructing the messages or parsing the data.
	
	This auxiliary function is quite helpful when constructing the
	messages, but its a bit complex to understand:

	  mapping sortObjsByEnv (object * what, object me, object * &envs)
	    This function is given the list <what> of objects which
	    are to moved around, the 'default environment' <me>, and a
	    references to variable <envs> to store computed data.
	    The function sorts the given objects by their environments
	    and returns the result: keys are the various environments,
	    data for each key is an array of the objects from this
	    environment. 
	    <envs> is then the list of environments, starting with
	    <me> (given that <me> contains one of the objects as well).

	  string makeFromMsg ( object        me
                             , mapping       bags
                             , object      * envs
	                     , void|object * what
                             )
	    This function is given a sorted-by-environmens list of
	    objects in <bags> and <envs> (as computed by
	    sortObjsByEnv()) and the 'default environment' <me>.
	    Result is a string describing the objects, being
	    of the form "(from <env1>) <thing1>, <thing2> and
	    <thing3>, (from <env2>) <thing4>, <thing5> and
	    <thing6>...". The contents of <me> come first and are not
	    prepended with '(from ...)'. If several things have a
	    matching short description, they are abbreviated to
	    '<thing>(<count>)'. The string does not end with a
	    newline.
	    The optional argument <what> may be used to restrict the
	    output data to those objects of <bags> which are also
	    given in <what>.


	The following auxiliary function implements the 'take before
	give away' functionality:

	  private mixed * takeBefore ( closure action
                                     , string verb, mixed what, mixed to
                                     , int mode) 
	    The function calles Take() with <what> and <mode> as
	    arguments and returns its result.
	    Additionally, if at least one of the given things <what>
	    had been taken, a call_out() is scheduled for <action>
	    with <verb>, the list of taken things, <to> and <mode> as
	    arguments, delay is 1 second.


	These functions are assumed as being available in other
	modules:
	  /std/living/description: Search(), QueryName()


DESCRIPTION - /std/living/skills.
	The plain standard living implements a very static version of
	skill system, the npc is a bit more advanced as it is able to
	recompute its skills on demand. However, the number of uses is
	still irrelevant.

	The skills are initialized using the function

	  int SetSkill (string name, int value)
	    Set the attribute <name> to <value> and mark this skill
	    <name> for recomputation.

	The effective values of skills are queried using
	
	  int EffectiveSkill (string name)
	    Return the effective value of the skill <name>.

	EffectiveSkill() uses the value set by SetSkill() (or assumes
	0 as default) and computes the true effective value from it.
	The result is also internally stored to speed up further
	requests.

	Recomputations may be enforced by a call to

	  void RecomputeStats()
	    Mark all skills for recomputation (as if their stats have
	    changed).

	Further calls to EffectiveSkill() will then recompute the
	effective values from the attribute setting.

	The other functions

	  int UseStat (string name, void|int diff)
	  int UseSkill (string name, void|int diff)
	  int ApplyStat (string name, void|int diff)
	  int ApplySkill (string name, void|int diff)

	are those of /std/living/stats.


	Automatic recomputation is performed by

	  void reset()
	    Call RecomputeSkills().


	These functions are assumed as being available in other
	modules:
	  /std/living/attributes: QueryAttr(), SetAttr()


DESCRIPTION - /std/npc/view
	This module implements the commands which provide the living
	with informations about its environment, namely look, examine,
	smell, listen, and the (matrix) inventory.
	Available are both the simple command functions as well as the
	'real' action functions.


	For the display of rooms, two properties are used:

	  int P_BRIEF   "Brief"
	    If non-zero, the living will see just the room's short
	    description upon entrance.

	  int P_OBVIOUS   "Obvious"
	    If non-zero, the living will see the list of obvious
	    exits.

	The basic functions are

	  mixed LookFor (mixed what, void|int impl)
	    This function searches the inventory and environment for
	    all objects matching <what>, which may be a string or an
	    array of strings.
	    Result is an array of strings, with the first string being
	    the message for <what>-specifications which match no
	    object. This first string may be empty or 0.
	    The following elements of the result (if any) describe the
	    various locations where which <what>s have been found.
	    All strings are wordwrapped and may contain several lines.
	    If <impl> is non-zero, the result is not the array but
	    instead the concatenation of all result strings.


	  string LookRoom ( void|int flags
	                  , void|object startroom
			  , void|string type)
	    Look at the surrounding room (or rooms if they are
	    transparent enough) and contents, and return the
	    description as string.
	    If <flags> contains the SENSE_MOVE flag, the function
	    assumes being called from the completion of a move and
	    checks the P_BRIEF before displaying the rooms long description.
	    If <startroom> is an object, it is the first room whose
	    description will be shown (if its one of the visibly
	    surrounding rooms of the living at all).
	    If <flags> contains the SENSE_SILENT flag, no message will
	    be issued to the livings surroundings.
	    <type> is the type of the look, either "look" (or 0) or
	    "examine".

	  void LookAfterMove (int method, void|mixed extra)
	    Take a look at the current room and tell it the living.
	    For learners and upwards, the description is preceeded by
	    the filename of the room.
	    This function is to be called after a move with <method>
	    and data <extra>. For the move methods M_GO, M_TELEPORT
	    and M_SPECIAL it is automatically called by move().

	  string SenseRoom (string type, void|object room)
	    Sense the surrounding room as <type> defines: "look",
	    "examine", "smell" or "hear". For the first two,
	    LookRoom() is called with <room> as <startroom>.
	    For the latter two, <room> (or the current environment) is
	    queried for the wanted information.
	    Result is the queried information (or a default string if
	    there is nothing to sense).

	  int Sense (mixed what, string type, int flags)
	    This function searches the inventory and environment for
	    all objects matching <what>, which may be a string or an
	    array of strings, and queries the information which <type>
	    specifies ("look", "examine", "smell", "hear", or "read").
	    If one singular <what> specification matches several
	    objects, just the first is queried.
	    The function is aware of details of the surrounding room.
	    Result is an array of strings, with the first string being
	    the message for <what>-specifications which match no
	    object. This first string may be empty or 0.
	    The following elements of the result (if any) contain the
	    various descriptions queried from the objects. If several
	    objects at the same place return the same description,
	    just one annotated description will appear in the result
	    array.
	    All strings are wordwrapped and may contain several lines.
	    If <flags> contains the SENSE_IMPL flag, the result is not
	    the array but instead the concatenation of all result
	    strings.
	    If <flags> contains the SENSE_SILENT flag, the act of
	    sensing will not be announced to the surrounding/looked at
	    livings.


	  string Inventory (int mode)
	    Return a single string with the inventory of the living.
	    If it doesn't have anything, "" is returned.
	    Each item's description starts with a leading "- " and may
	    be wordwrapped over several lines.
	    <mode> is a set of bitflags controlling how the result
	    looks like:
	      INV_FLAT: when set, just to top inventory items are
	        returned. Default is to return the items of carried
	        bags as well (with proper indentation).
	      INV_LONG: when set, each item is listed separately.
	        Default is to fold items of equal short description
	        into just one entry with a "[<count>]" following.
	      INV_NARROW: when set, the returned string is formatted
	        for a linelength of 38 characters. Default is a line
	        length of 78 characters.

	
	The action functions are bound to a set of command functions,
	which are called from player/NPC commands and parse the
	arguments.
	Each of the functions allows the specification of a list of
	objects (e.b. "torch, beer from bag and car") for the objects
	being moved. As usual, they return non-zero on success.

	  int fexamine (string arg)
	  int fexaminea (string arg)
	    Implements 'examine' and 'examine <thing(s)>'.
	    fexaminea() also checks the actual command verb for being
	    a correct substring of 'examine'.

	  int flook (string arg)
	  int flooka (string arg)
	    Implements 'look', 'look for <thing(s)>' 
	    and 'look [at] <thing(s)>'.
	    flooka() also checks the actual command verb for being
	    a correct substring of 'look'.

	  int flisten (string arg)
	    Implements 'listen' and 'listen [to] <thing(s)>'.

	  int fsmell (string arg)
	    Implements 'smell' and 'smell [at] <thing(s)>'.

	  int freadl (string arg)
	    Implements 'read <thing(s)>'.

	  int finventory (string arg)
	    Implements 'inventory [flat] [long] [list]'.

	The command functions are bound to the actions in this
	function, which has to be called during create():

	  void add_view_cmds()


	The module features a few auxiliary functions.
	
	This auxiliary function is quite helpful when checking
	light levels from commands:

	  int CheckLight ()
	    Check if the living can _not_ see in the <env>ironment (default
	    is the current environment), regarding a possible P_BLIND
	    setting.
	    Results:
	      < 0: it is too dark, result is the difference to A_IVISION.
	           If (1<<31) is returned, the living is blind.
	      = 0: the living can see.
	      > 0: it is too bright, result is the difference to A_UVISION.
	    Additionally, if the living can't see, an appropriate
	    notify_fail(..., NOTIFY_NOT_VALID) has been set.


	Another function is used to describe environments relative to
	the living (you will rarely need it):

	  mapping describeEnvs (object * envs, void|int str_by_obj)
	    <envs> is an array of environments to describe.
	    For each environment a description like 'carried in a bag'
	    or 'in a safe here' is computed.
	    If <str_by_obj> is zero, the result is a mapping, indexed
	      by the generated descriptions, with two entries per
	      description: first an array of objects which hold this
	      description, second an integer which is non-zero if this
	      described environment(s) are within the living.
	    If <str_by_obj> is non-zero, the returned mapping is
	     indexed by the environments, and the first indexed value
	     is the environments description. The second is again a
	     flag whether the described environment is been carried or
	     not.


	These functions are assumed as being available in other
	modules:
	  /std/living/description: CanSee(), CantSee(), Search(), SearchM()
	                           QueryName()
	  /std/npc/putget        : sortObjsByEnv()


CREDITS
	The matrix inventory in /std/npc/view was invented by Yaro
	(TubMud), the code was written 19-Mar-93..30-Aug-94 by Taube.


BUGS/TODO
	/std/npc/putget:
	  The extra 'Take' actions should be implemented using
	    Actions.


INHERITANCE TREE
	std/npc
	  |- std/npc/compat
	  |    `- std/living/compat
	  |- std/living/attributes
	  |- std/npc/body
	  |    `- std/living/body
	  |- std/living/chat
	  |- std/living/cmds
	  |- std/living/combat (old)
	  |- std/living/commands
	  |- std/living/description
	  |    |- std/thing/description
	  |    `- std/room/description
	  |- std/living/heart
	  |- std/living/moving
	  |- std/npc/putget
	  |- std/living/restrictions
	  |    `- std/container/restrictions
	  |	    |- std/thing/restrictions
	  |	    `- std/room/restrictions
	  |- std/npc/skills
          |    `- std/living/stats
	  |- std/npc/view
	  |- std/room/items
	  `- std/base


SEE ALSO
	attributes(C), combat(C), health(C), perception(C), search(C),
	skills(C), base(S), combat(S), thing(S), equipment(S), living(S)