OBJECT
/std/room
LAST UPDATE
Mateese@OSB, 98/07/11
SYNOPSIS
inherit "/std/room";
#include <config.h>
#include <properties.h>
#include <rooms.h>
DESCRIPTION
A room (to be interpreted in a physical sense) is an outer
encumbrance for an inner space into which objects can be
placed. Thus it features all the descriptional properties of a
normal thing, but in a special 'internal' variant.
The room needn't be totally enclosed: it's hull can have
holes, called 'exits', leading to other rooms. Each exit is
specified by the command the player has to give to move
through that exit.
Though serving an unlimited traffic is the most common
state of life for exits, there are situations in which exits
shall be closed for a certain time. This is done by placing
blocking objects, called 'doors', right before the exit and
catching the exit command if a trespass is to be denied.
Though the room itself is not directly involved into the
door-exit-handling, it imposes a defined protocol on legal
doors, and it holds a list of the currently active doors and
their states (see also door(S)). This list makes it possible
to adapt the room's description to the current door state.
A special demand for free spaces are that they need to be
lighted. Rooms are able to emit light on their own, but can
also connect to a weather-server (standard is NIGHTDAY,
defined in nightday.h) to get light from the sun.
--- std/room ---
The perceptional routines Long(), Short(), Smell()
and Noise() from /std/room/description are redefined here
to return the approbiate details given as arguments.
void create (void|int noreplace)
Calls the inherited create() functions of /std/base and
/std/room/restrictions.
It also calls /std/base:replace_pgm() if <noreplace> is
not specified or zero, so be alert when doing dynamic
rooms or to-inherit rooms just consisting of an create()!
string Long (void|string what)
Returns the internal long description, or that of the
detail <what> if given.
string ExaLong (void|string what)
Returns the internal long description under closer
examination, or that of the detail <what> if given.
string Noise (void|string what)
Returns the internal noise description, or that of the
detailed noise <what> if given.
string Smell (void|string what)
Returns the internal smell description, or that of the
detailed smell <what> if given.
string Read (void|string what)
Returns the internal read description, or that of the
detailed message <what> if given.
--- std/room/description ---
string P_INT_SHORT "IntShort"
string P_INT_LONG "IntLong"
The short and long description of the inner appearance.
Both properties are analogue to their P_SHORT/P_LONG
counterparts.
string P_INT_NOISE "IntNoise"
string P_INT_SMELL "IntSmell"
The smell and the noise noticable within the room.
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 retrieve the complete description of the whole room
(appearance and contents), use:
string GetIntDesc ( void|int nolong
, mixed exclude
, void|object player
)
Return a printable string describing the whole room and
its current contents excliding the current player (it is
at least the ""-string).
If <nolong> is not zero, the returned string does not
contain the P_INT_LONG.
The functions also inserts exits and doors if the player
is obvious mode.
<exclude> is one or more objects to be ignored in the inventory
listing, if given. If it is a closure, it is called for
each inventory object and has to return non-zero if the
object is to be excluded.
<player> denotes the living who queries the GetIntDesc()
and defaults to this_player().
string GetExaIntDesc ( mixed exclude
, void|object player
)
Like GetIntDesc(), this returns the long description suitable
for an examination, not just a simple look.
As the main difference to GetIntDesc() is in the long
description, the parameter <nolong> would be superfluous.
Get(Exa)IntDesc() allows an arbitrary string to be insert between
the room's own description and the list of contents:
string P_PRECONTENT "PreContent"
If set to a string, this is printed by GetIntDesc() just
prior to the list of contents.
The notion of outside-of-here (though important mostly for
Locate() and the look commands) may be modified using these
non-builtin properties:
string P_PREOUTSIDE "PreOutside"
If set to a string, it will be printed by the look
commands when recursing from the current room to its
outside. If not set, a default string will be used.
object P_OUTSIDE "Outside"
For object locations, this non-builtin(!) property denotes
the room which is to be considered 'outside'.
E.g. for a chair this would be the room outside the room
holding the chair.
If not set, environment() will be used.
The player objects do not query the physical description
properties directly, but instead using these functions:
string IntLong (void|string what)
Returns the internal long description.
string ExaIntLong (void|string what)
Returns the internal long description under closer
examination. If there is no special description for this,
"You see nothing special.\n"+IntLong(what) is returned.
string IntShort (void|string what)
Returns the internal short description.
string IntNoise (void|string what)
Returns the internal noise description.
string IntSmell (void|string what)
Returns the internal smell description.
string Content ( void|string what
, mixed exclude
, void|object player
)
Return a listing of the inventory, prefixed by
P_PRECONTENT if this set.
If <exclude> is given, it determines the objects not to be listed
in the inventory. If given at all, this_player() is always
ignored. If it is a closure, it is called for
each inventory object and has to return non-zero if the
object is to be excluded (see MakeExcl()).
<player> denotes the living who queries the Content()
and defaults to this_player().
The result is a multilined string, but may "" or 0 for
totally empty rooms.
object * MakeExcl (mixed exclude[, mixed add])
Auxiliary function, used by Content() to prepare the <exclude>
argument. This function is provided so that other people
can overload Content() more easily.
The function takes the <exclude> argument and makes it an
array of objects. <exclude> can be a closure, in which case
it is called for each inventory object and has to return
non-zero if the object is to be exluded. It can also be
a single object or an array of objects to be excluded.
If given, <add> is added to the created exclude array.
<add> can be a single object or an array of objects.
The final array is returned as result.
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>'). This is used on top level(!) to implement details.
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/room these functions return just the
contents of the associated properties. This may not be valid
for derived objects.
To mark a room as being part of a killzone, implement:
int QueryKillZone ()
This function has to return non-zero if the room is part of
a killing zone.
There mustn't be a 'SetKillZone()' function, and this must
be a hardcoded property!
Not really a description, the room may be marked as being
explorable (assuming that its accepted as such by the Quest
Department):
mixed P_EXPLORABLE "Explorable"
This property contains the value 1 if the mere entering of
the room counts as 'act of exploration',
or the name of the detail whose scrutinization counts,
or 0 if nothing is to be explored (or if its programmed
manually). Alternatively it contains an array of the
aforementioned values.
If you want details react just on a specific action,
prepend its string with "look:", "listen:", "smell:" or
"read:" (notice that the _verbs_ form the prefix!).
mixed AddExplorable (mixed new)
Add <new> to the current settion of P_EXPLORABLE.
<new> may be a single string or an array of strings.
int DoExplore (mixed arg)
Check if <arg> is explorable and call
this_player()->SetExplored() on success.
Result is 0 on failure and non-zero on success.
IMPORTANT: Explorable rooms must be checked in with the
/p/daemons/explorer controlling object.
Nightfall needs more explorable rooms and details, so don't hesitate!
--- std/room/restrictions ---
The restrictions part serves all those purposes where
information, light, data or objects flow in or out of the
room.
int P_INDOORS "Indoors"
A flag denoting if the room is indoors (!= 0)
or outdoors (== 0).
string P_SERVER "Server"
The object_name() of the weather server to use, if the room
is outdoors.
mixed P_OUTDOORS "Outdoors"
If 0, the room is an indoors room.
Else the value of the property denotes the weather-server
in charge for this room.
When set to a numeric value != 0, it is interpreted and
set as the default weather server NIGHTDAY.
This is no real property, but instead projected onto
P_INDOORS and P_SERVER.
mixed FilterWeatherData (object client, mixed *data, int newstate)
If the weather server notifies players and clients about
weather changes, it filters the weather <data> through all
environments of each <client>. <newstate> is the state the
server will upon completion of the notification.
The room may apply changes to the given <data> array and
return it (default is that no changes are done).
If it returns 0, nothing of the data will be displayed to
the client.
It is still up to the weather server to finally display
the data.
int P_BRIGHT "Bright"
The amount of light the room emits to the inside.
int P_INT_LIGHT "IntLight"
The total amount of light emitted within the room.
This is a sum of the rooms own brightness, the incoming
sunlight and the light the content emits.
When set, the P_INT_BRIGHT is modified to achieve the new
lightlevel.
For this property, the two calls have additional functionality:
int QueryIntLight (int nosun)
With <nosun> = 0, this returns just total amount of
light 'visible' emitted in the room.
If <nosun> is non-zero, the function returns the total
amount of light emitted withing the room w/o incoming
sunlight.
int SetIntLight (int l, int nosun)
This sets the total amount of light 'visible' in the
room (by modifying P_INT_BRIGHT).
If <nosun> = 0, <l> is the new total amount to
achieve.
If <nosun> is non-zero, <l> is the new amount of light
to be emitted independant of the sun (thus making
SetIntLight(n, 0) == SetIntLight(n-QuerySunLight(),1)).
int P_SUNBRIGHT "SunBright"
Determines the bright of the normal sun, default value
is MAX_SUNBRIGHT.
int QuerySunLight ( void )
Returns the amount of incoming sunlight (0 for indoor
rooms), as queried from the weather server.
If you want to have dimmed sunlight in your room (e.g. for
a forest) this is the function to overload.
The value returned is already scaled by P_SUNBRIGHT/MAX_SUNBRIGHT.
int P_CANSEE "CanSee"
If this property is set to non-zero, every living in the room
is able to see, not regarding the light.
The actual evaluation is done in the lfun CanSeeHere():
int CanSeeHere(void|object living)
Check if <living> can see even if the lighting is too dark
or too bright. Result is 1 if the living can always see,
and 0 if the normal light limits apply.
The default behaviour is to check the P_CANSEE property.
CanSeeHere() is called as part of the normal CanSee/CantSee()
processing in /std/living/description.
Note that after initialisation the room has an automatic lighting
of 75% of MAX_SUNBRIGHT. This lighting will vanish with any change
of P_INDOORS, P_OUTDOORS, P_INT_LIGHT or P_BRIGHT.
mixed * QueryDayData ()
If the room is an outdoors room, the StateData for the
current daystate is returned, else 0.
int QueryDayState ()
If the room is an outdoors room, the DayState is
returned, else 0.
string QueryDayDesc ()
If the room is an outdoors room, the description of the
current daystate is returned, else 0.
int P_MAX_WEIGHT "MaxWeight"
The max amount of weight the room may contain (note that a
pure room has no weight of its own!).
It may be set any time, but no lower than the current
contents weight.
It is set on creation to 2**30.
int P_MAX_INV "MaxInv"
The max number of items the room may contain.
If set to 0, any number is allowed.
int QueryWeightContent ( void )
Return the total weight of the objects within the room.
int MayAddWeight ( int w )
Return non-zero, if it is possible to change the actual
weight of the contents by <w>.
int MayAddItem ( )
Return non-zero, if it is possible to add another item to
the rooms inventory, as determined by P_MAX_INV.
void AddIntWeight ( int w )
Add weight <w> to the weight of the contents.
int P_TPORT "TPort"
Specifies what teleports are forbidden:
TPORT_NO : no teleporting is allowed
TPORT_IN : teleporting in is allowed.
TPORT_OUT : teleporting out is allowed.
TPORT_BOTH: all teleports are allowed.
The values are included from <magic.h>.
string P_TPORT_REASON "TPortReason"
This non-builtin(!) property may hold the reason why
teleporting is forbidden.
To forbid or allow the use of magic in a room, use:
mapping P_MAGIC_PROTECTION "MagicProtection"
This mapping is indexed by the types of magic (see
<magic.h>), and has to contain a "Sorry"-message for each
kind which is not allowed in this room.
string AddMagicProtection (int type, string message)
Forbid the use of <type> magic, and set <message> as the
text to print if someone tries to.
Result is the set string.
mapping ForbidAllMagic (void|string str)
Forbids the use of any magic. If <str> is given, it is
used as the message to print, else a default message is
set.
Result is the update P_MAGIC_PROTECTION.
string QueryIsMagicForbidden (int type)
Check if magic of <type> is forbidden. If not, return 0,
else the "sorry" string which would be printed.
The light propagation uses these functions:
protected void emit_intlight (int l)
The room emits <l> more light to its inside.
Call the lfun light_from_outside() for all contained
objects with <l> as parameter, and increment P_INTLIGHT
by <l>.
Do not call this function manually!
protected void light_from_inside (int l)
Some contained object emits <l> more light. Increment
P_INTLIGHT by this amount, and call
light_from_outside(<l>) for all other contained objects.
Do not call this function manually!
Searching an item in a room can be quite cumbersome, esp. if
the light has to be considered, so this has to be used:
object*|object Locate ( void|mixed what
, void|int mode
, void|object * also)
For a detailed documentation, see /doc/concepts/search.
An auxiliary function used by Locate() is
object * filterWornWielded (object * objs)
The function is passed a list of <objs> and returns a list
of those, which are neither worn nor wielded nor equipment.
In general, it has to return those objects which shall not
be subject of a generic 'fooey all' action.
To support the vision system, the room implements these
functions which are called as part of the show() and see()
simul_efuns:
object * GetViewers (void|object|object * excl)
This function returns an array of all objects in the room
which are able to see. By default these are all livings
with the right vision settings.
If specified, <excl> denotes one or more objects which are
to be ignored in the check. These objects are not
returned with the result.
int _view_filter (object elem)
This function is called for each checked <elem> in the
room by GetViewers(). It has to return non-zero if the
object can see.
By default these are livings with the proper vision
setting.
int filter_message( int class, string * msg )
This function, which is default not there, is used to filter
the messages of CMSG_ROOM that are sent to players in that
room. The function _MUST_ return a valid message class, if
the message should remain unchanged it has to return class.
The msg is an array consisting of two entries, the first is
the message for those who see in the room, the second the one
for those who see not (which might be 0). Important is that
always an array is passed to that function, even if MMSG_SEE
is not set. But, if MMSG_SEE is not set the second array parameter
is unused.
Common use might be to modify MMSG_SEE or to add MMSG_DISCARD.
object * display (string|string * msg, void|object|object* excl)
* OBSOLETE FUNCTION - USE msg_room (simul efun) instead! *
This function displays <msg> to all seeing objects in the
room, except those specified in <excl>.
<msg> may be one string for the 'seeable' message only, or
an array of two strings for both the 'seeable' and the
'non-seeable' message.
Result is an array of all recipients.
int _display_filter (object rec, mixed * msg)
* OBSOLETE FUNCTION - use filter_message instead! *
display() uses this function to allow special treatment
for selected clients. The function has to return non-zero
if it notified <rec> itself of the <msg>, else 0 (the
default).
<msg> is the message to display and is always an array,
and MUST NOT be modified, unless you make a copy.
When livings move into or out of the room, the room will
announce this. To do this, /std/room/restrictions defines own
notify_{enter,leave}-functions which do the announcement.
Also, if the living comes from somewhere using an other
weather server, it will get a description of the current sky.
The livings P_OUTDOORS will be updated as well.
If the living is invisible, nothing is announced to the room.
Livings normally use M_GO or M_TELEPORT, but some are moved
using M_SPECIAL.
M_SPECIAL make use of the <extra> arg, which is then a single
string or an array of strings (both may be empty).
Ideally, <extra> = ({ "<out_msg>", "<in_msg>", "<living_msg>" }),
though the room itself cares just for the first two ones.
Each of the messages may be just a string, used for visible
messages, or an message array for visible/non-visible messages.
If <extra> is just a string, it is taken for all visible messages.
If a living moves via M_GO or M_TELEPORT, <out_msg> and
<in_msg> are taken from its properties (M)MSGOUT and (M)MSGIN.
However, if <extra> is specified together with M_TELEPORT, the
messages are generated as for an M_SPECIAL move.
M_GO also allows the <extra>-Parameter to be used for the
visible moving messages. If specified, the
approbiate msg from it will be added to the general
enter/leave message as ' <msg>'. Thus a complete
enter-message would be "<name> <MSGIN> <extra_msg>.\n".
However, all messages must not end with ".\n".
For the initialisation, the lfun
void create(void)
is implemented here.
--- /std/room/details ---
It is possible to equip the room with lots of details without
the creation of an own object for each detail. Instead, the
room will 'fake' those objects.
Details are divided into 'normal' details for which the
information is stored in the room, and 'special' for which the
room gets the information by a call to an arbitrary function.
The details cooperate with /std/room/description:DoExplore()
to implement the explorer facilities.
Note: If there are doors known to the room, the detail 'doors'
will automatically be set to return a list of all visible
and active doors - when queried with GetDetail().
Note: If the details 'sky' or 'heaven' are not set, outdoor
rooms will return the current weather description.
For compatibility, this is done by a call to
string fsky(string str)
which returns the description. On this call, <str> is
set to the detail queried ("sky" or "heaven").
NOTE: The functions AddDetail, AddNoise, AddSmell, AddReadMsg are
mapped internally now to vitems (virtual items), even with
their remove-functions (RemoveDetail,...). For more
informations see 'man vitems'. One call to AddVItem can
replaced some single calls of the functions mentioned above.
Vitems are added with AddVItem() - see manual page of vitems!
You can do a lot of more than adding simple details with
vitems, but see for the manual page for more.
mapping P_DETAILS "Details"
All details of the room.
Keys are the detail-ids, the data is the description
string (or an array of two strings for the distinction
'look at' and 'examine'), or a function/closure returning
the actual description string/string array.
void AddDetail ( string|string *id
, string|string *|closure desc
, void|string exadesc)
Sets the description for the detail <id> to <desc>.
If <id> is an array of strings, each entry in that array
is taken as separate id, thus given a hole set of ids the
same description.
If both <desc> and <exadesc> are given as simple strings,
the detail will be set as ({ <desc>, <exadesc> }).
if <desc> is a closure, it is called with the detail looked
at as argument and has to return the description.
If <desc> is ({ "#call_other", <obj>, <funcname>, ...}),
it will be compiled into the appropriate closure and stored.
void RemoveDetail (string|string *id)
Removes the description for the one or more specified <id>s.
string|string* GetDetail (string id)
Return the description for the detail <id>, may it be
normal or special.If no such <id> was defined, 0 is
returned.
The same exists for noises:
mapping P_NOISES "Noises"
void AddNoise (string|string *id, string|closure desc)
void RemoveNoise (string|string *id)
string|string* GetNoise (string id)
and smells:
mapping P_SMELLS "Smells"
void AddSmell (string|string *id, string|closure desc)
void RemoveSmell (string|string *id)
string|string* GetSmell (string id)
and of course they can be read as well:
mapping P_READ_MSGS "ReadMsgs"
void AddReadMsg (string|string *id, string|closure desc)
void RemoveReadMsg (string|string *id)
string|string* GetReadMsg (string id)
Note: if the mapping set for the details/smells/... contains
arrays as keys, these arrays are flattened.
Thus, Set(P_DETAILS, ([ ({ "foo", "bar" }): "Nothing happens.\n"]))
is equivalent to Set(P_DETAILS, ([ "foo":"Nothing happens.\n",
"bar":"Nothing happens.\n" ]))
To perform the magic, the lfun
int id (mixed try_id)
is implemented here.
To make the details work, the GetXXX() functions have to be
combined with the IntLong()/IntSmell()/IntNoise() function on
top level (see std/room/description).
--- std/room/items ---
The room has provisions for easy creating and configuring of
items, and also offers a special treatment for money.
The items are created and moved into the room. Every reset all
items are checked, and depending on the refresh action
specified at creation several measures might be taken:
REFRESH_NONE
Nothing is done at all (the default).
REFRESH_DESTRUCT
If the item was destructed, it is recreated.
REFRESH_REMOVE
If the item was removed from the room, it is recreated.
REFRESH_HOME
If the item was removed from the room, it is put into the
room again, else it is recreated.
In fact, this is (REFRESH_DESTRUCT|REFRESH_MOVE_HOME).
REFRESH_ALWAYS
Combines REFRESH_DESTRUCT and REFRESH_REMOVE.
The aforementioned actions may be combined with one of the
following subactions (by |'ing the constants together).
REFRESH_MOVE_HOME
If the item was removed from the room, it is put into the
room again.
REFRESH_RESET
If the item exists, it's reset() is called.
REFRESH_PROPS
All properties of the item are reinitialized.
REFRESH_FUNC
A specified function is called upon refresh of an object.
If an item is newly created, it is done in this sequence:
- the item is cloned
- it's properties are set
- it is moved into the room
- item->Aloha() is called (see below)
mixed * P_ITEMS "Items"
The array of all item specifications.
Each entry describes one item and is itself an array with
these fields:
string|string* [RITEM_FILE]
The filename of the blueprint to clone, or an array
of filenames.
If the value is an array, the actual filename to clone
from is selected by random from the array. 0-entries
are valid and lead to the cloning of no item.
[Idea by Kassandra @ Morgengrauen].
Instead of the object_name, the/each entry may be a closure
which is then called to return the newly cloned.
int [RITEM_REFRESH]
The refresh actions.
mapping(*) [ ]
The mapping for initialization of the item's
properties. Alternatively, this can be an array of
mappings, if some of the item's properties need to be
initialised in a special order. Properties not mentioned here
are not changed.
This entry may be omitted.
string|closure [ ]
Function to call if the object was refreshed.
Arguments are: (<obj>, [RITEM_REFRESH], <nr>)
<obj> is the object refreshed, <nr> it's sequential number
counted from 0.
This entry may be omitted.
object [<n]
...
object [<1]
The actually created (n-1) items.
Note that the length of each entry varies.
object * AddItem ( string|string* file
, void|int refresh
, void|mapping|mapping* prop
, void|int n
, void|string|closure fun)
Add a <n> items (at least 1) cloned from the blueprint <file>
to the room and mark them for later refresh according to
<refresh>, with <fun> to call on refresh.
If <prop> is given, each newly created item will undergo
an item->SetProperties(<prop>).
Adding the item implies an initial 'refresh' of it.
Result is an array with the added items, or 0 if none
were added (resp. or if they were of the REFRESH_NONE type).
This array is a copy of the entry placed in P_ITEMS and
thus consists of:
({ filename, refreshmode, ..., 1st item, 2nd item, ... })
object * AddItem ( closure|closure* cfun
, void|int refresh
, void|mapping prop
, void|int n
, void|string|closure fun)
Same as the 'normal' AddItem, except that the filenames of
the objects are now indirectly determined by the specified
function(s) 'cfun'. These functions are called upon
creation of the item and have either to return the
filename of the object to clone, or have to clone the
object itself and return that.
void RemoveItem ( string *|string file )
Remove the data for <file> from P_ITEMS.
If <file> is a string, just the entry for <file> is
removed.
If <file> is an array of strings, all entries containing
at least all entries of <file> are removed.
Note that the function does not destruct the actual items.
For an easier initialization of an object, a pseudoproperty
exists:
mixed * P_ITEMS_REFRESH "ItemsRefresh"
Setting this property set P_ITEMS to the given data, and
performs an initial refresh of all items. Additionally,
all still-carried P_ITEMS already existing are destructed.
Note that the number of items to create is indirectly
given by the size of each of the item entries.
Result is P_ITEMS after the complete refresh.
This is a write-only property.
To equip a room with money, set the builtin property
mixed P_MONEY "Money"
to the desired value. This can be a simple integer, denoting
the absolute value to be given in standard coins, or a mapping
denoting each coin and its amount of (e.g. (["silver":12]) ).
The money is refreshed both when set and with each reset() by a
call to
int RefreshMoney()
which checks if the room contains less worth of money than set
in P_MONEY, creating additional money when needed. It does not
reduce the amount of contained money.
To perform the above tasks, the lfuns
void reset ()
void Aloha (int flag)
is implemented here. The Aloha() function (if called with a
negative argument) just calls reset(), which then will perform
the refresh. This is to make sure that a reset in the
outermost room will cause a 'deep reset' of all contained objects.
To give newly created items the opportunity for additional
setup, the lfun Aloha() is called in them after they have been
cloned _and_ moved into the room:
void Aloha (int flag)
Perform additional object specific setups.
'flag' is 0 if this is the first creation of the object
(as part of the AddItem()), it is positive if the object
is recreated because of an refresh, and it is negative if
the object needed no refreshment (put is member of the
P_ITEMS array).
Doors and combat equipment make heavy use of Aloha().
--- /std/room/exits ---
Rooms can have exits, which lead to other rooms. To make
creating obvious exits easy, there exist functions to handle
this. The roomfilenames can be absolute with leading "/", or
with leading "~", or with leading "+" for searching in the
current rooms domain, or relative (with leading '.') to be
searched in the directory of the current room.
Also exist the possibility of 'special exits': here no
destination filename is specified, but instead the names of a
function and its object, so the function is invoked to do the
moving.
The object filename may be specified in a relative notation as
well.
It is possible to mark an exit as 'checked': whenever it is
used (moving, opening doors, door blocking the way because
it's closed), the function CheckAction() is called and may
forbid the action. This is an alternative to using "special
exits" (exits with an user-provided function) to control
access to neighboring rooms.
mapping P_EXITS "Exits"
The mapping of all specified exits.
Key is the command, data is the following cluster:
mixed EXIT_DEST : the destination room, function name,
or function closure
mixed EXIT_OBJ : 0 or the functions object.
object EXIT_DOOR : the associated door object.
int EXIT_HIDDEN : flag if the exit is hidden. See HideExit()!
int EXIT_CHECK : flag if the exit is checked. See CheckExit()!
If set to 0, no exits exist.
The settings of EXIT_DEST and EXIT_OBJ may be these:
- EXIT_OBJ = 0, EXIT_DEST: expanded filename of the dest room
- EXIT_OBJ = 0, EXIT_DEST: the dest room object
- EXIT_OBJ = 0, EXIT_DEST: function closure for this direction
- EXIT_OBJ : expanded filename of function object, or object itself
EXIT_DEST: name of the function to call for this direction
Exits which are not controlled by a function (normal exits)
always lead out of the room. They can't be triggered from outside.
If the exit (special or not) is controlled by a door,
EXIT_DOOR holds the door object in question.
This field is not to be set! The room takes care of it!
EXIT_HIDDEN is normally zero, but if set to non-zero, the exit
is no longer visible as 'obvious', even when it has an open
door before it. Nevertheless it can be used.
EXIT_CHECK is normally zero, but if set to non-zero, using the
exit undergoes extra checks. See CheckExit().
The Exit data is internally kept in two mappings: one holding
EXIT_DEST, the other the other data fields. They may be
accessed directly using:
mapping P_EXITS_DEST "ExitsDest"
A single mapping containing the EXIT_DEST or P_EXITS,
indexed by the exit direction.
It contains an entry for every exit.
mapping P_EXITS_DATA "ExitsData"
A mapping holding [EXIT_OBJ..] or P_EXITS.
Index within an entry by subtracting EXIT_OBJ from the
symbolic index, like [dir, EXIT_DOOR-EXIT_OBJ].
This mapping contains entries for just those exits needing
extra data.
Use this data only if you know what you're doing!
The mapping returned might be empty, so subindexing won't work
in that cases!
mapping QueryPlainExits ()
The functions returns that subset of P_EXITS_DEST which are
just simple exits (all data are filenames of the destination
rooms). The result is always a mapping, even if the properties
themselves are 0.
mixed * QueryExit (string dir)
Return the data for the exit leading <dir> in an array, or 0.
If the exit is a 'special' exit, [EXIT_DEST] is 0,
and [EXIT_OBJ] is either the function closure, or ({ object,
functionname }) of the function to call.
mixed QueryTarget (string dir)
Returns the string or object of the room which will lead
into the direction 'dir'. In case of special exits this
might be the 'most likely' room. This function should be
used for aiming, farsighting, etc but not fort moving NPCs
or players.
If a room has just simple exits, P_EXITS_DEST may be used for
convinient setting. If not, add the non-simple exits using
AddExit() (see below).
string P_NOWAY_MSG "NowayMsg"
The default string to be told to players which attempt to leave
in a direction for which no exit has been added. If 0, the
string "No way\n" is used.
The room expects this to be a builtin property and passes
the command line as argument to QueryNowayMsg().
mapping P_NOWAY_MSGS "NowayMsgs"
A mapping of strings to be told to players which attempt
to leave in a direction for which no exit has been added.
The direction is the mapping index, the data for each
index the message to be told.
void AddNowayMsg (string | string * verb, string msg)
void RemoveNowayMsg (string | string * verb)
Add resp. remove messages for the given verb(s) from
P_NOWAY_MSGS.
string QueryNowayMsg (void | string verb, string arg)
If no argument is given, return the default P_NOWAY_MSG
message, else the no-way-message for the given <verb> and
<arg>. This is again the P_NOWAY_MSG, unless for the
<verb> a message has been defined in P_NOWAY_MSGS.
void AddExit ( string *|string command
, string|object room)
Add an exit into direction <command> to the specified <room>.
<command> may be specified as an array of strings if all
are to describe the same exit.
void AddExit ( string *|string command
, string fun_name
, void|object|string obj
, string|closure target)
Add an exit into direction <command>, with <fun_name> being
the name of the function to execute in <obj> (default is
this_object()) to perform the movement.
<command> may be specified as an array of strings if all
are to describe the same exit. Target is the room or a function
returning the room where the direction will most likely end up.
This will be used for aiming, looking into other rooms, etc.
The function will get the arguments (direction,EXIT_QUERY_ONLY)
void AddExit (string *|string command
, closure fun
, string|closure target)
Add an exit into direction <command> by setting <fun> as
the function to perform the movement.
<command> may be specified as an array of strings if all
are to describe the same exit. The target argument works like
described above. If target is ommited the function 'fun' will
be called with the same arguments (direction,EXIT_QUERY_ONLY)
void RemoveExit ( string *|string command )
Remove the exit(s) denoted by <command>.
int HideExit (string|string * dir, int newstate)
Hide or unhide the exit to <dir> (which can also be a list
of exits).
Result is the old state (in case of a list of exits: just
the state of the last exit).
If the exit in <dir>ection is not controlled by a door, a
setting of HIDE_OPEN or HIDE_ALWAYS hides the exit.
If the exit in <dir>ection is controlled by a door, the
value set is used to set the doors P_HIDEEXIT property and
then acknowledges these values:
HIDE_NOT : the exit is listed.
HIDE_OPEN : the exit is listed only when door is closed.
HIDE_CLOSED : the exit is listed only when door is open.
HIDE_ALWAYS : the exit is not listed (this is in fact
just HIDE_OPEN|HIDE_CLOSED).
If HIDE_BOTH is ored (|) to the value set, the remote
doors property is updated as well.
int CheckExit (string|string * dir, int newstate)
Check or uncheck the exit to <dir> (which can also be a list
of exits).
Result is the old state (in case of a list of exits: just
the state of the last exit).
Possible values are:
DACT_NOT : no check necessary.
DACT_HIDE : check if the exit is hidden.
DACT_CHECK : check always.
DACT_UNHIDE : check if the exit is not hidden.
If a door controls this exit, its effect on hiding the
exit is regarded.
See UseExit() and CheckAction().
string * P_EXIT_STRINGS "ExitStrings"
An array of up to four strings which are used by Exits()
resp. MakeExitString() to construct the exit description.
If this property is not set or incomplete, the following
default is internally used:
({ "There is", "exit", "There are", "exits" })
Exits() and MakeExitString() are described using this
setting.
string Exits(void|int brief, void|object player)
This returns a descriptional string (possibly consisting
of multiple lines) of all defined exits.
The long form (<brief> is zero) is:
'There are <n> exits: <exit1>, <exit2>, ..., and <exitn>',
The short form (<brief> is non-zero) is:
'<exit1>,<exit2>,...<exitn>'
with the names of standard exits abbreviated ("n" instead
of "north", "nw" instead of "northwest").
<player> denotes the living who queries the Exits()
and defaults to this_player().
Not contained are exits for which active doors exist which
return a QueryStatusString() or are not open.
Also not contained are hidden exits if the player is neither a
wizard nor a ghost.
mixed * ExitList()
Return an array of two arrays of strings.
The first array are the directions of obvious exits, the
second array are the direction of hidden exits.
string MakeExitString (int brief, string * dirs, void|string kind)
Return a string describing the list of exits leading
<dirs> in a format suiting for Exits().
If specified, each exit is written as "<kind> exit".
int UseExit(string verb, string arg, int method)
Lead the actual player through the exit <verb> with command
<arg>ument. If it is a normal exit, move method <method>
is used. Result is normal command success code.
Use this function to avoid manual resolving of normal
or special exits.
int CheckAction (string action, string verb, string arg, int method)
The command '<verb> <arg>' is applied to the room, with
its type determined by <action>:
<action> = 'exit': the player tries to leave through one
of the exits, using move-method <method>.
/obj/doors also add the actions 'block', 'door', 'lock'
and 'knock'.
The function has to return non-zero if the action shall
succeed, and zero if the action shall fail.
Default is that every action succeeds, unless it's the
action 'block' and the player is a ghost (i.e. ghosts are
not blocked).
If the exit has no checking enabled, this function won't
be called for it.
This function may be called by doors if the room is set as
P_CHECKOBJ in them.
As mentioned above, the room keeps track of the doors blocking
its exits. Doors MUST call these functions!
mapping P_DOORS "Doors"
A mapping containing all acknowledged doors.
Key is the door object, data are clusters with the
entries:
string DOOR_DIR
The command this door blocks.
int DOOR_STATE
The state (LOCK_xxx) of the door.
void NewDoor (string dir, int state, void|object door)
Add a new door to the door list.
The <door> (default: previous_object()) controls the exit
for the command(s) <dir> and is currently in <state>.
Note that the /std/door calls NewDoor() as part of its
Aloha() initialisation.
void SetDoorData (string dir, int state, void|object door)
Update the information <dir> and <state> for the <door>
(default is previous_object()).
(Mostly only <state> will change).
<dir> may be an array of directions if one door serves
them all.
void RemoveDoorData (void|object door)
Removes the <door> (default: previous_object()) from the
list of active doors.
This doesn't imply that the door left the room - just that
it no longer controls the exit.
void SetDoorState (int state, void|object door)
Set the new locking <state> for <door> (default:
previous_object()). This modifies just the internal data.
int SetDoor (string doorid, int new)
Compatibility: Set the door determined by <doorid> (which
is either the direction or the doors id) to the state <new>.
Return the newstate, or -1 if there is no such door.
mixed * DoorInfo (mixed door)
Return the entry for <door> (specified by the object, by
the exit command or by the doors id) from P_DOORS.
The entry contains an additional field 'object DOOR_OBJECT'
specifying the door object.
If there is no such <door>, 0 is returned.
object AddDoor ( string dir
, string|object|closure dest
, mapping props
, void|string doorobj )
Add a door (and exit) for exit <dir> leading to <dest>
(see AddExit()). The door object is <doorobj>, default is
"/obj/door". The object is added as REFRESH_REMOVE item
with <props> holding the data to initialise the added
door.
<props> has to hold all data necessary for the door
(P_SHORT, P_LOCKSTATE, P_DOORCODE etc). It need not
contains P_DIRECTION or P_OTHERROOM, as these are filled
in by the function. However, a contained P_OTHERROOM would
not be overwritten.
If <props> contains P_IDS, its entry is extended by the ids of
the <doorobj>
Result is the added door object.
object AddDoor ( string dir
, string|object|closure dest
, string doorid
, string doorlong
, mixed *|string keyid
, int state )
Compatibility: Add an /obj/door (and exit) for exit <dir> leading
to <dest> (see AddExit()). The object is added as
REFRESH_REMOVE item and initialised as P_SHORT:"a
<doorid>", P_LONG:<doorlong>, P_DOORCODE:<doorid>,
P_LOCKSTATE:<state>, P_KEYCODE:<keyid>[0],
P_KEYIDS:<keyid>[1..], and door->AddId(<doorid>).
If <keyid> is just a string, only P_KEYIDS is initialised.
If <keyid> is 0, no key data is initialised.
The P_CHECKOBJ is set to the room adding the door.
Result is the added door object.
int HideDoor (string dir, int newstate)
Set the P_HIDEDOOR property of the door in direction <dir>
to <newstate>, and return the old setting.
That property determines whether a door should be listed
in the 'Obvious Doors' description of rooms or not.
Possible settings are:
HIDE_NOT : the door is listed.
HIDE_CLOSED : the door is listed only when open.
HIDE_OPEN : the door is listed only when closed.
HIDE_ALWAYS : the door is not listed.
If HIDE_BOTH is ored (|) to the value set, the remote
doors property is updated as well.
Use this property if the door is not visible in one of its
states, or listed in the rooms long description.
int CheckDoor (string dir, int newstate)
Set the P_CHECKDOOR property of the door in direction <dir>
to <newstate>, and return the old setting.
That property determines whether a door should apply
additional checks on actions or not.
Possible settings are:
DACT_NOT : no check necessary.
DACT_HIDE : check if the door is hidden.
DACT_CHECK : check always.
DACT_UNHIDE : check if the door is not hidden.
If DACT_BOTH is ored (|) to the value set, the remote
doors property is updated as well.
Setting this property has an effect only if some code
actually evaluates it.
Setting P_CHECKOBJ of the door to the roomobject will
result in the room's CheckAction() being called.
string Doors (void|int verbose, void|object player)
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>'.
if <verbose> is non-zero, also "There are no doors.\n"
is possible, else "" is returned if no doors are there.
Doors returning no QueryStatusString() or the empty
string "" are not listed.
<player> denotes the living who queries the Doors()
and defaults to this_player().
Hidden doors are not listed unless the player is a wizard
or a ghost.
mixed * DoorList()
Return an array of two arrays of door objects.
The first array are the obvious doors, the second array
are the hidden doors.
string MakeDoorString (int brief, object * doors, void|string kind)
Return a string describing the list of <doors> leading
<dirs> in a format suiting for Doors().
If specified, each door is written as "<kind> <door>".
Note: Both Exits() and Doors() are to be called by the
player object directly, or by GetIntDesc().
They should not be called by IntLong() or Content().
As a feature, the room can also invoke arbitrary functions
when a specified command is given.
mapping P_COMMANDS "Commands"
The list of all command verbs and their function names.
Key is the verb, data the function name.
void AddRoomCmd (string|string* verb, string|closure function)
Adds a verb with associated function to the room. When
<verb> or one of the elements of the array <verb> is
typed, the function <function> in the room is invoked.
The function should return 1 on success or 0 in case
the room doesn't accept the combination of <verb>
and arguments to <verb> (See "commands" in the concepts
documentation).
void RemoveRoomCmd (string|string* verb)
Removes one or more verbs from the room, deactivating the
commands.
The deactivation is valid only for newly arriving livings.
To activate the exit- and room-commands, the lfun
void init (void)
is implemented here.
Auxiliary functions are:
string map_brief_exit (string dir)
Returns a shorted version of <dir>, if possible, like 'nw'
for 'northwest'.
--- /std/room/cleaning ---
This implements the special remove() and clean_up() for rooms.
Rooms treat the contents in a special way: items, which are
cloned using /std/room/items do not count as 'contained',
since they can be recreated.
On the other hand, some created objects need the room for
refresh (like for REFRESH_HOME), so the existance of such
items prevent the room from clean_up().
int remove (void)
This just destructs the room.
int clean_up (int ref)
Overloads the default handling of /std/base.
The clean_up() handling is different from those of /std/base.
- If P_CLEAN_UP is zero, the object stays and the function
returns 1 to be asked again later.
- A cloned room with environment returns 0, and will thus not
clean up anytime.
- A room with items which needs the room to exist (e.g.
REFRESH_RESET items) force the room to stay and return
with 1 to try again later.
- If there are alien objects in the room, they are called
with clean_up(-1) to let them clean_up() themselves. If
after this some of them still exist, the room will not
clean up and return with 1 to try again later.
- Else the room will destruct all its inventory and itself.
The inventory destruction will first be attempted by
calling clean_up(-1) in each item, and the then still
remaining items will be remove()d the hard way.
The handling of added items is in detail this:
- If items of _RESET or _INIT have been removed from the
room, the room does not clean up this call.
- An REFRESH_HOME item is moved back into the room, and
cleanup continues.
- Other added items do not change cleanup handling.
--- /std/room/secrets ---
Handles the secrets in a room. A secret is a detail which
a player will be shown automatically if his perception skill is
high enough. For example it will be possible to give a hint to
a secret door to players with good skill.
varargs int AddSecret(string secret, int difficulty,mixed desc)
Add a Secret to a room. Its short name is 'name'. Usual "door" or
"exit" or "trap door".
The 'difficulty' detemines how difficult a Secret is to detect (0-1000).
It is related to the perception skill
The next argument is the description of that secret, i.e. what a player
will see when detecting it. It can be a string or string array or a
closure returning a string. If given a string array the text shown to
the player depends on the output of the skill check. A low value will
show the first string of the array and higher values will show latter
strings providing more inforamtion for the player.
The closure function will get 'secret' && 'player' && 'skillvalue'
as arguments, i.e.
varargs string MyFun(string secret,object player,int skillvalue)
where secret is the name given to the secret in AddSecret skillvalue
a number 0..1000 showing how well the player did detect the secret
int RemoveSecret(string secret)
Removes a secret from the list of secrets in this room
BUGS
/std/room/items should be able to recognize items lying around and
reuse them instead of cloning new ones (useful for npcs).
INHERITANCE TREE
room
|-std/base
|-std/room/cleaning
|-std/room/items
|-std/room/details
|-std/room/exits
|-std/room/description
`-std/room/restrictions
SEE ALSO
perception(C), search(C),
base(S), thing(S), container(S), door(S), light(C), inroom(O)