perception

concepts
CONCEPT
	perception

UPDATE
	Mateese, 09-Nov-94 - 15:00 MET

DESCRIPTION
	Perception in this context means the display of the physical
	appearance of the objects to the player object.

	Normally, all important data about an object is held in its
	properties, and queried using QueryProp() or Query<Name>().

	The only exception are the physical descriptions of the
	objects: Long, Short, Noise and Smell; both internal as
	external.
	Experience showed that the actual physical description of an
	object is often a derivate instead of a simple replicate of
	the property value.

	In acknowledge to this, the player object does not query these
	properties directly, but instead uses overlayed functions
	which take the basevalues (default is the assocaited property)
	and modify them (e.g. by adding extra data (see below) if
	necessary before returning them to the player object.

	The functions are:

	  string Long (void|string what)
	    Returns the long description for the normal 'look at'.
	    This does never include any data from contents, exits or
	    whatsoever.

	  string ExaLong (void|string what)
	    Returns the long description for the close 'examine'.
	    If no data is specified for this case, Long(what) is
	    returned with an introductory comment is returned.
	    This does never include any data from contents, exits or
	    whatsoever.

	  string Short (void|string what)
	    Returns the short description (not capitalized, no
	    trailing newline).
	    Invisible objects have to return 0.

	  string InvShort (void|string what)
	    Returns the capitalized short description;
	    or the empty string for invisible objects.
	    This is used for overall inventory listings (hence the
	    name).

	  string Noise (void|string what)
	    Returns the noise description.

	  string Smell (void|string what)
	    Returns the smell description.

	for the external descriptions, and

	  string IntShort    (void | string what)
	  string IntLong     (void | string what)
	  string ExaIntLong  (void | string what)
	  string IntSmell    (void | string what)
	  string IntNoise    (void | string what)

	for the internal ones.

	Short()/IntShort() returns a simple string: not capitalized
	and without trailing newline.
	All other functions return a string which is written by the
	player object 'as is' to the user.
	If an object has not a particular description, it is free to
	return '0' or the empty string "".

	The parameter 'what' describes, what type of 'view' the player
	took: if the user typed 'look', Long() would be called with 0
	as parameter. If the user typed 'listen to <foo>', Noise()
	would be called with "<foo>" as parameter.

	An additional set of functions exist for rooms and containers:

	  string Content (void|string what, void|int not_myself)
	    Return a listing of the inventory, prefixed by
	    P_PRECONTENT if set.
	    If <not_myself> is non-zero, this_player() is omitted from
	    the listed inventory.
	    The result is a multilined string, but may be "" or 0 for
	    totally empty rooms.

	  string Exits()
	    This returns a descriptional string (possibly consisting
	    of multiple lines) of all defined non-hidden exits.
	    It is of the form:
	      'There are <n> exits: <exit1>, <exit2>, ..., and <exitn>'.
	    Not contained are exits for which active doors exist which
	    return a QueryStatusString() or are not open.

	  string Doors()
	    This returns a descriptional string (consisting of
	    multiple lines) of all defined doors.
	    It is of the form:
	      'There are <n> doors:
	       <door status string 1>
		  ...
	       <door status string n>'.
	    Doors returning no QueryStatusString() or the empty
	    string "" are not listed.

	These functions are to be called by the player directly, not
	as part of (Int)Long().
	There is no inside/outside distinction for these, since they
	seldom differ. Refer to /obj/chest for an example how a
	Content() can be made inside/outside sensitive.


	Searching a thing is of course also modified by light. But as
	quite a lot of additional magic is implemented there as well,
	it is described in a separate doc.


DESCRIPTION -- extra descriptions
	Many ad-hoc changes of an objects description require just the
	addition of some text. Changing the underlying property for
	this is nearly overkill, so there's the possibility to store
	extra data. This also has the advantage that changes from
	outside are made easier.

	The data is stored on a per-key base: each modification
	(consisting of a mapping of strings, each tagged with the
	property it has to be added to) is stored under a key-value in
	the modified thing.

	Both the data entries per key and within one mapping may be
	closures instead of their intended values. If that is the
	case, the closure is executed prior to actually querying it,
	allowing dynamic extra descriptions.

	It is best explained with an example (using an idea invented
	by Ploi):

	A spraycan which can be used to paint graffities in whatever
	room one is. Spraying a graffity changes the long description
	of the room, and the smell (for the solvent residues).
	Internally, the spraycan just does
	  room->AddExtra( "spraycan graffity" // the key value
	                , ([ P_INT_LONG: "There are graffity at the walls.\n"
	                ,    P_SMELL: "A faint sweet smell hangs in the air.\n"
                          ])
                        );
        The mapping added as 'extra data' could also hold additional
        data for use of the spraycan only.

	To remove the graffities, a washcloth just has to do

	  room->RemoveExtra("spraycan graffity");

	
USAGE
	The most difficult problem is to decide, what has to go into
	the property, and what into the perceptional function.

	Imagine a metal shield, highly polished so that the sun
	reflects of its surface.
	The base value for P_LONG might be
	  "It is a large, round shield."
	and the Long() would add around noon the line
	  "The sun is reflecting from it's surface."

	Thus the shield would be at noon:
	  "It is a large round shield.
	   The sun is reflecting from it's surface."

	The creating wizard should be aware that the P_LONG might be
	changed during gameplay by external objects, e.g. by an enemys
	weapon to:
	  "It is a large, round shield.
	   Many battles left deep scarves and holes in it."
	Having the Long() saying something about the quality of the
	shield would lead to strange descriptions, as:
	  "It is a large, round shield.
	   Many battles left deep scarves and holes in it.
	   The sun is reflecting from it's perfect, polished surface."

	You see, the Long() should (in this case of a shield) either
	add something 'neutral' to the P_LONG, consider the object
	P_QUALITY, or just add a string if the P_LONG is the original one.


SEE ALSO
	search(C), object(S), properties(C), room(S), thing(S)