There is a generic door available. To use it you have to do
following things:

a) Add "#include <door_defs>" to the code of the room in which
   the door is added (usually to the beginning of the file)

b) Clone the door (usually in create_room()), and get its pointer.
   (Something like: 'door_ob = clone_object(DOOR_FILE)'; DOOR_FILE
   is defined in 'door_defs.h' and is the file-name of the standard
   door)

c) Set the data associated with the door; means that you'll usually
   call the function 'add_door()' from the room's code (the function
   itself is in the door's code however...). (Something like:
   'door_ob -> add_door(......)'. The parameters add_door needs
   are listed later on this document(.

d) Do the modifications to the door if needed. Especially you should
   call 'set_pick_level' so that the door might be possible to pick
   by some thief ('door_ob -> set_pick_level(40)').

Steps a) and d) aren't always needed so they may be omitted.

For example there might be a room that looked like this:
===========================================================================
/* A small room in which the door.c is used. */
#include <door_defs>
/* Defines for example DOOR_FILE & KEY_FILE. */
#include <room.h>
/* Standard room that should be used (instead of inheritting /room/room.c). */

void create_room() {

 object door, key;

  set_short("An example room");
  set_long("This is a room created to show how to use the door.c.");
  set_light_level(LT_LIGHTS); /* Lit room. */
  set_outdoors(WD_INDOORS); /* And 'indoors', ie. not outside. */

  door = clone_object(DOOR_FILE);

  door -> add_door("It is a big wooden door","east","/players/my_name/room2",
  "small metal","key_of_my_door",1,1,1,20
  "You see nothing special in it. It is just a normal metal lock.");

  key = clone_object(KEY_FILE);
  key -> set_type ("small metal");
  key -> set_code ("key_of_my_door");
}
===========================================================================
(To get this working, there would have to be a room "/players/my_name/room2"
 also; this is just meant to be a short example.)

The syntax for the 'add_door' is:

'add_door(mixed d_long, mixed d_dir, mixed where, string lock_type,
   mixed lock_code, status is_closed, status is_locked, status can_lock,
   int pick_level, string lock_long)'
(Not all the parameters are essential; for example you don't have to set
the 'lock_long' (if you don't have a lock in the door for example).
If you omit 'is_closed', 'is_locked' or 'can_lock' but want to set the
lock_long, you'll still have to use commas between the missing arguments.)
Note: add_door sets both doors so you don't have to call 'set_both_status'
after add_door (unlike when using 'set_x'-functions in door.c).

Arguments used are:

- mixed d_long:
    (Either string or an array of the strings containing two strings).
    The long description(s) of the door; if an array, then the first one
    is for this door and the second one for the 'other side' of the door.
    In the example above, the description "It is a big wooden door" will
    be used for both doors.
- mixed d_dir:
    (Either string or an array of the strings containing two strings).
    The direction to which this door is; if an array, then the first one
    is used for this door and the second for the other side. Usually
    only one string is used and in that case the matching pair for that
    direction will be used for the other side of the door (means that
    if this was "north" then the other side would be "south" etc.).
    In the example above, the d_dir is "east" and so the door in the
    first room would be "A door to the east" and the other side would
    be "A door to the west".
- mixed where:
    Either a string (usually), an objectpointer (seldom) or an array of
    size 2 (in which either of the elements may be either a string or
    an objectpointer).
    If it's a string or an objectpointer, this is the place where the
    other side will be located (this side will be located to the room
    in which code the 'add_door' was called). If an array, then the
    first one is the place for this side and the second for the other
    side.
    In the example above, the first side of the door will be in the room
    where the 'add_door' was called and the other side in the room
    "/players/my_name/room2".
- string lock_type:
    The 'type' of the lock (for example "golden" -> "the golden lock").
    In the example above, the type is "small metal" so the lock will be
    "a small metal lock". Usually the key that fits into this lock is
    of the same type as the lock so the "small metal key" might fit into
    this lock; however, it doesn't have to be so; whether the key really
    fits into the lock depends on the lock_code (see below).
- mixed lock_code:
    Either a string or an array of strings. If the key's code is
    the same as the lock's code (or one of the codes if this is an
    array), then the door may be locked/unlocked with that key.
    You may, for example set multiple codes so that there will be
    keys that can open multiple doors and other keys that only open one
    door (master keys of a sort).
    In the example above, only the key of which code is "key_of_my_door"
    will lock/unlock this door.
- status is_closed:
    Whether this door is closed; 0 = open, 1 = closed.
    In the example above, the door is closed.
- status is_locked:
    Whether this door is locked; 0 = not locked, 1 = locked.
    In the example above, the door is locked.
- status can_lock:
    Whether this door can be locked/unlocked with the appropriate key.
    If this is 0, then 'lock_code', 'lock_type' and 'lock_long' don't
    have any meaning (in which case they may be omitted too).
    In the example above, the door may be locked/unlocked.
- int pick_level:
    Set how hard this door is to be lockpicked. Values between 0 and 100
    are used; however if this door can't be lockpicked, use the value -1.
- string lock_long:
    The long description of the lock; may freely be omitted (especially
    if there isn't a lock in the door...). If there is a lock in the
    door, but 'lock_long' isn't defined, the standard message is used
    ("You can see nothing special in it...").

-------------------------------------------------------------------------

When you have set up a door, there are several functions with which
you can customize your doors. The following functions may be used
for this purpose (although they are usually set with the 'add_door').
Note that all these functions only affect one side of the door;
if you want changes on both sides either call every function for
both doors or set one door and then call 'set_both_status' for
the side that you modified.

set_door_long(desc)
    string desc. Sets the long description for the door to desc.
    Used for changing the description on one side of the door.

set_lock_long(desc)
    string desc. Sets the long description for the lock that is in
    the door (if there is one).

set_closed(value, quiet, both)
    int value. Variable is_closed is set to value.
    int quiet. Unless this is 0, players get the message 'x door opens.'.
    int both. If this is 0, only 'this side' is closed, otherwise both.

set_locked(value, quiet, both) 
    int value. Variable is_locked is set to value.
    int quiet. Unless this is 0, there will be a sound 'click' on the door.
	int both. If this is 0, only "this side" is locked, otherwise both.

set_can_lock(value)
    int value. Variable can_lock is set to value (0 = means that there isn't
    a lock in the door and any other value that there is).

set_type(lock_type)
    string lock_type. Sets the type of the lock.

set_code(lock_code)
    Sets the codes that this door will accept from the keys.
    If the argument is an array, then all of the codes the array
    contains will do.

set_pick_level(pick_level)
    int pick_level. Set how hard is this door to be lockpicked.
    -1.

----------------------------------------------------------------------------

When you want to get information about some door, there are following
functions that return some info about the door:

string query_dir()
    returns the direction of this door ("east door" would return "east").

string query_type()
    returns the type of the lock (as set with set_type).

string query_code()
    returns the code of the lock (as set with set_code)

int query_pick_level()
    returns how hard it is to pick this door (as set with set_pick_level).

string full_name()
    returns the 'full name' of the door; for example "the east door",
    "the north door" etc.

If you want the door to make any kind of noise, such as knocking etc,
you should call function:

tell_this_door(message)
    string message. This call causes the door to 'say' 'message'. If you
    want to use something like "You hear <x> from the <y> door.",
    you can use function 'full_name' defined in door.c. (see the
    explananation of that function above). If you want the message to
    be heard on both sides of the door, call the partner door's
    tell_this_door too.

---------------------------------------------------------------------------

And then last but certainly not the least: hooks.
(Hooks are functions that are called in some crucial place
in the code).

The hooks are used when we want to do something unusual when the
player tries to open, close, lock, unlock or knock the door (or
go through it). When we set up a hook for some action, that hook
will be called either before or after executing the normal
open/close/lock/unlock/knock/go action. If the hooks was called
before the action and the hook returned something other than 0,
the normal action won't happen; this way we can prevent the door
from being opened etc.

The way you can add a hook is:
a) 'if(door_ob) door_ob -> set_door_hook(BEFORE,OPEN,"some_func",some_ob)' or
b) 'if(door_ob) door_ob -> set_door_hook(BEFORE,OPEN,"some_func")'.
Now when player enters a command that would normally open the door,
the function "some_func" would be called in the object some_ob (case a) or
in the object that set up the hook (case b). When you set up a hook,
you have to have include file "door_defs" in the code of the object that
sets up the hook.

The best way to understand how and why the hooks may be used, is to
look for the example-room that is in the /examples-directory
("/examples/door/door_room.c" (as soon as I'll code it ready,
in the meantime, you can ask me (Doomdark) about details).

---------------------------------------------------------------------

Appendix A:

The commands available to players defined by doors:

 +  'go [direction] door'
	 or
    'direction'	if the door is opened the player is move to the other
		side of the door.
 +  'open/close [direction] door'
		works if door is unlocked.
 +  'unlock/lock [direction] door with [type] key'
		works if door is set up to have a working lock. 
 +  'knock [direction] door' or 'knock at [direction] door'
		knocks on the appropriate door and also prints
		a message on the other side.

--------------------------------------------------------------------------
Document made by Doomdark, last revision 01-02-94.
--------------------------------------------------------------------------
