OBJECT
/std/thing
LAST UPDATE
Mateese, 12-Apr-98
SYNOPSIS
#include <properties.h>
inherit "/std/thing";
DESCRIPTION
This is the general class for all LPC-objects used in
OSB. From /std/base it inherits its general purpose
property mechanism and extends it by a row of builtin
properties and the possibility to move around.
Besides the builtin properties described below, things
normally feature following (mostly soft) properties:
mixed P_AUTOOBJECT "AutoObject"
If the thing should be autoloading, the property has to be
set to a non-zero value. The value itself is stored over
logout and restored then again.
object P_EQUIPPED "Equipped"
When set, it determines the carrying object of which this
thing is considered an equipment.
If a thing is carried by it's P_EQUIPPED object, it no
longer reacts on 'all' commands, but only on the 'really
all'-type.
string P_EXTRALOOK "Extralook"
If set, the string is included after the P_LONG
description into the carriers description.
string P_INFO "Info"
string P_VERSION "Version"
You can put your name and a version number here.
mixed P_MAGIC "Magic"
Describes a magic item.
Needs further specification yet.
int P_SIZE "Size"
This prop gives a rough estimate of the relative size of
an object.
Allowed values are defined in /sys/properties.h as
PSIZE_GENERIC = 0: this object fits alls sizes
PSIZE_SMALL = 1: this object is a small one
PSIZE_NORMAL = 2: this object is of its typical size
PSIZE_LARGE = 3: this object is a large one
This is not an absolute value. Both a knife and a bihander
would qualify as 'PSIZE_NORMAL' as long as as human can
handle them. For a dwarf both would be too large to be
handled, for a giant too small. The function
'CompareSize()' in /std/thing/description helps with
comparisons.
The top level file defines these functions:
void create ()
Initialises the thing, calls base::create().
int clean_up (int ref)
Performs the clean_up handling by calling
moving::clean_up().
void init ()
Might add commands and do other entrance specific stuff.
For now, this is here just for consistency.
--- /std/thing/description ---
string * P_IDS "Ids"
A list of ids the thing has to acknowledge.
string * P_ADS "Ads"
A list of optional adjectives to be applied to the ids
when parsing a id() call.
When set, both P_IDS and P_ADS are mapped to lower case, and
all sequences of spaces are shrunk to just one space. It is
however legal to have P_IDS or P_ADS with embedded spaces.
string * P_CLASS_IDS "ClassIds"
string * P_CLASS_ADS "ClassAds"
Similar to P_IDS and P_ADS, but these describe generic
features of a thing.
A torch would the specific identification 'heavy torch',
and the generic identification 'burnable thing'.
string (*) P_LONG "Long"
Contains the long description of the thing.
This can be either a single string, or an array of two
strings, the first for the normal 'look at', the second
for the closer 'examine'.
string P_SHORT "Short"
Return the short description of the thing.
This must be a single-lined string, starting with a
lowercase letter and ending without newline.
If the string is set to 0, the thing is invisible.
string P_READ_MSG "ReadMsg"
The text which describes what the players sees when it
'reads' the thing, or a closure returning the text.
It can be 0.
string P_NOISE "Noise"
A description of the noise the thing emits, or 0.
string P_SMELL "Smell"
A description of the smell the thing emits, or 0.
mapping P_SUB_DETAILS "SubDetails"
A mapping holding the descriptions of details on the
thing. Indices are the detail ids, values are the
description strings, resp. arrays of two strings
(look and examine description).
The details are identified as "<detailid> on <thing>"
and "<detailid> of <thing>".
mapping P_SUB_READMSGS "SubReadMsgs"
A mapping holding the messages of readable details on
the thing. Indices are the detail ids, values are the
message strings.
The details are identified as "<detailid> on <thing>"
and "<detailid> of <thing>".
To ease the specification of sub details and readmessages,
auxiliary functions exist:
void AddSubDetail(string|string * det, mixed descr, void|mixed exa)
void AddSubDetail(string|string * det, mixed * descrs)
Add the subdetail <det> to the thing and describe it with
<descr>. If <exa> is specified, this is the description used for
"examine"s. Both descriptions may be combined into one array.
If <det> is given as array, the description(s) are set for each
of the single details.
It is possible to specify the <descr> as closure. In this case
this closure is called on need to return the description string.
It may also return an array with the "look"- and the "examine"-
description strings. The closure is called with the <det> string
as argument.
void RemoveSubDetail(string|string * det)
Remove the detail description(s) for <det>.
void AddSubReadMsg(string|string * key, mixed msg)
void RemoveSubReadMsg(string|string * key)
Similar to the Add/RemoveSubDetail() functions.
string P_NOBUY "NoBuy"
If set to a non-zero value, the thing can't be bought from
a shop.
If the value is a string, it is used as failure message.
string P_NOSELL "NoSell"
If set to a non-zero value, the thing can't be sold to
a shop.
If the value is a string, it is used as failure message.
int P_VALUE "Value"
The value of the thing.
string P_INFO "Info"
A string to contain a short technical description of the
thing and its author.
string|closure P_HELP_MSG "HelpMsg"
A string containing a short informational text about the
object (or room). It is queried by the player 'help' command.
Instead of a string, a closure may be used as value.
Upon query, the closure is executed and has to return the
informational text to be displayed.
If a player ask for help on an object with not P_HELP_MSG
set, a BUG report is generated. This can be avoided by
setting the P_HELP_MSG to the empty string (default for rooms).
In this case, the player will see a default text.
To ease the specification of ids and ads, auxiliary functions
exist:
string * AddId (string|string * id)
Adds <id> to P_IDS and returns the new value of P_IDS.
<id> may an array of strings as well.
string * RemoveId (string|string * id)
Removes <id> to P_IDS and returns the new value of P_IDS.
<id> may an array of strings as well.
string * AddAdjective (string|string * ad)
string * RemoveAdjective (string|string * ad)
string * AddClassId (string|string * id)
string * RemoveClassId (string|string * id)
string * AddClassAdj (string|string * ad)
string * RemoveClassAdj (string|string * ad)
Similar.
To support 'unit'- or 'detail'-operations, the each call to
id() (re)sets these read/only properties:
string P_LAST_ID "LastId"
The last recognized id string.
string P_LAST_VERB "LastVerb"
The command verb of the last successful id().
object P_LAST_PLAYER "LastPlayer"
The command giver of the last successful id().
This data should be stored in the CmdData stack in the current player.
If the object defines details (normal and readable), they are
recognized in strings of the form "<detailid> on <thing>" and
"<detailid> of <thing>". The detailid is stored in the player
command data under the key "<filename_of_object>:subid".
Long(), ExaLong() and Read() check this entry to return the correct
text.
The identification function itself is
int id (mixed try_id)
and checks for both specific and class id.
int class_id (mixed try_id)
just checks the class id (but allows combination with
'specific' adjectives).
Internally the id-matching mechanism operates using regular expressions: the given ids and adjectives are compiled into a pattern, which is
then used in id() and class_id() for the actual matching. This all
happens automatically. Any change in the ids or adjectives erases
the associated pattern, which is then recreated anew at the next
call to id() or class_id(). For debugging purposes, the pattern are
accessible through properties on their own:
string P_CLASS_PATTERN "ClassPattern"
The regexp pattern used to match the class ids and adjectives.
When 0, the next call to class_id() recreates the pattern.
string P_ID_PATTERN "IdPattern"
The regexp pattern used to match the normal ids and adjectives
as well as the class ids and adjectives.
When 0, the next call to id() recreates the pattern.
The player objects do not query the physical description
properties directly, but instead using these functions:
string Long (void|string what)
Returns the long description for a 'look at', either for
the object or for a detail.
This does never include any data from content or exits or
whatsoever.
string ExaLong (void|string what)
Returns the long description for an 'examine', either for
the object or for a detail.
If none is specified, "You see nothing special.\n"+Long(what)
is returned.
This does never include any data from content or exits or
whatsoever.
string Short (void|string what)
Returns the short description.
Default is P_SHORT.
string InvShort (void|string what)
Returns the Short() description capitalized;
or the empty string for invisible objects.
This is used for overall inventory listings.
string Noise (void|string what)
Returns the noise description. Default is P_NOISE.
string Smell (void|string what)
Returns the smell description. Default is P_SMELL.
string Read (void|string what)
Returns the read description, either of the object
or of a readable detail. Default is P_READ_MSG.
The argument 'what' is either 0 if the player issued a general
perception command (like 'look') or a string containing the
object "<thing>" of a directed perception command (like 'smell
<thing>').
The value returned by these functions is in fact not just the
property value, but instead the property value extended by the
extra data (if any). The single extra data for these functions
must be strings, which are concatenated to the value of the
property before the result is returned.
For the plain /std/thing these functions return just the
contents of the associated properties (plus the extra data).
This may not be valid for derived objects.
For compability, the argument 'what' is passed to the
underlying Query...() routines.
There is a function helping in dealing with P_SIZE matters:
int CompareSize (int|object with)
Compare the P_SIZE of the object with the given size
<with>, resp. with the P_SIZE of the object <with>.
Results are:
< 0: this object is smaller than <with>
= 0: this object is of same P_SIZE as <with>
> 0: this object is larger than <with>
The Extra Data is stored as a single mapping
mapping P_EXTRA_DESC "ExtraDesc"
with the single extra data sets indexed by their key values.
Each single data set must be a mapping, or a closure returning
a mapping.
The data set mapping then is primarily indexed by the property
names it has additional data for - for the descriptional
properties these data have to be strings.
Again, closures returning the actual data might be stored
instead of verbatim data.
Following functions help dealing with the extra descriptions:
void SetExtra (mixed key, mapping|closure data)
Store the <data> set for the <key> value in P_EXTRA_DESC.
mapping|closure QueryExtra (mixed key)
Return the data set for the <key> value from P_EXTRA_DESC,
or 0 if there is none.
void RemoveExtra (mixed key)
Remove the data set for the <key> value from P_EXTRA_DESC.
Single fields in one key's data set may be directly changed:
void SetExtraEntry (mixed key, mixed field, mixed data)
The entry indexed by <field> from the data set <key> in
P_EXTRA_DESC is set to <data>.
Example: SetExtraEntry("spraycan extra", P_SHORT, " (painted)");
void QueryExtraEntry (mixed key, mixed field)
Return the data indexed by <field> from the data set <key>
in P_EXTRA_DESC.
void RemoveExtraEntry (mixed key, mixed field)
Remove the data indexed by <field> from the data set <key>
in P_EXTRA_DESC.
--- /std/thing/restrictions ---
int P_WEIGHT "Weight"
The weight of the thing. One unit is one gramm (one
old-NF-unit are 1000 gramm).
int P_BRIGHT "Bright"
The amount of light the thing emits on its own.
int P_LIGHT "Light"
The amount of light the things emits in total (including
light from contents).
When set, the thing's P_BRIGHT is changed to reach the
given total-value.
For the light propagation, this function is used:
protected void emit_light (int l)
The object emits <l> more light. If the object has an
environment, its lfun light_from_inside() is called with
<l> as parameter, and increment P_LIGHT by <l>.
Do not call this function manually!
--- /std/thing/moving ---
The moving part implements a generic moving algorithm with
flexible success checking.
The lfun to call to move a thing is:
int move (string|object dest, void|int method, void|mixed data)
Move the thing into <dest> using <method> (default is
M_SILENT). <data> is additional according to <method>.
Result is a successcode.
For a detailed discussion of methods, results and extra data,
see /doc/concepts/moving.
Any of the manual moves (take, drop, put) can be prevented by
setting the according property to non-zero:
mixed P_NOGIVE "NoGive"
mixed P_NOGET "NoGet" also #defined to be P_NOTAKE
mixed P_NODROP "NoDrop"
These properties are not checked by move() but instead by the
initiating command function itself.
If the preventing non-zero value is a string, it is used as
the failure message to the player.
For interactive objects == players, P_NOGET is always non-zero.
/std/thing also implements the possibility of automatic
following.
The property
object * P_FOLLOWERS "Followers"
contains the list of objects which follow this thing.
For easier manipulation of the list exist the functions
object * AddFollower (object f)
object * RemoveFollower (object f)
which add or remove the given object from/to P_FOLLOWERS
and then return the new value of P_FOLLOWERS.
Everytime the thing moves by move(), the lfun
void follow (string|object dest, void|int method, void|mixed data)
is called with the arguments from the move() in every object
noted in P_FOLLOWERS.
On the other hand, if a thing sets
mixed P_NOFOLLOW "NoFollow"
to a non-zero value, it can't follow an other thing anymore
(calls to its follow() are silently ignored).
An additional property allows to identify 'followers', like
familiars, as such. However, it is task of the follower-programming
wizard to set this property, as the object can't do it on its
own.
mixed P_IS_FOLLOWER "IsFollower"
Value is non-zero if this object is (usually) following some
other object.
The value is automatically set by Set(P_FOLLOWERS) and
AddFollower() in the added objects, but it can't be reset
as automatically.
Note: if a thing follows a player, the thing is informed about
the players network status by calls by the player object to
the things lfun PlayerNetdead(int isdead). The function is
given 0 if the player revives from netdeath, and non-zero if
the player just went netdead.
int clean_up (int ref)
Overloads the default handling of /std/base.
The clean_up() handling is different from those of /std/base.
If the thing is
- if P_CLEAN_UP is zero, the object stays and the function
returns 1 to be asked again later.
- a blueprint with no environment or asked by its environment
to clean up, it walks through its inventory and calls
clean_up() with -1 as argument in each object.
If this causes all objects to self destruct, the thing
destructs as well and returns 0; else it remains and
returns 1.
- a clone with no environment, it tries to 'remove()' all
contained objects (using a deep_inventory()) and then
selfdestructs.
- a used blueprint, or anything not covered before, it stays
and returns 1 to be asked again later.
Things carried by players (netdead or not) never clean up.
BUGS
The P_LAST_* data should be stored in the current player's
CmdData stack.
INHERITANCE TREE
thing
|-std/base
|-std/thing/moving
|-std/thing/properties
`-std/thing/description
SEE ALSO
moving(C), properties(C), units(C), light(C), base(S)