Generic exit

    This object defines the behavior of exits.

    Public methods:

	go_through()			Attempt to go through exit.

    Protected methods:

	verb_changed_in_leaf()		Notification of verb changes

    Exit protocol methods:

	attach(place)			Attach exit to a new source
	link(place)			Link exit to a new place

    Verbs:

	lock_verb()			Set lock.

parent vr
object exit

var exit source 0
var exit dest 0
var exit lock 0

method init
    arg ancestors;

    (> pass(ancestors) <);
    if (definer() in ancestors) {
	source = $sys.exit_starting_room();
	dest = source;
	source.add_exit();
	lock = $true_lock_class.new();
    }
.

eval
    .initialize();
    .set_name("Generic exit");
    .add_verb("@lock %this with *", 'lock_verb, 'remote);
    .set_fertile(1);
.

method show
    var output, i;

    output = pass();
    output = output + ["Exit variables:"];
    for i in (definer().parameters())
	output = output + ["  " + tostr(i) + ": " + toliteral(get_var(i))];
    return output;
.

method verb_changed_in_leaf
    (> pass() <);
    source.verb_changed_inside();
.

method go_through
    if (lock.try(sender()))
	sender().move(dest);
    else
	sender().tell("You can't go that way.");
.

method lock_verb
    arg dummy1, dummy2, dummy3, str;

    if (!.is_owned_by(sender()))
	sender().tell("Permission denied.");
    catch ~objnf, ~parse {
	lock = $lock.parse(str, sender());
	sender().tell("Locked.");
    } with handler {
	switch (error()) {
	    case ~objnf:
		sender().tell("Object not found in lock string.");
	    case ~parse:
		sender().tell("Invalid lock string.");
	}
    }
.

method attach
    disallow_overrides;
    arg place;

    if (!.is_owned_by(sender()))
	throw(~perm, "Sender does not own exit.");
    if (!place.follows('room))
	throw(~type, "Place doesn't follow room protocol.");
    if (place == source)
	return;
    (> place.will_attach(sender()) <);
    source.remove_exit();
    source = place;
    place.add_exit();
    (| place.did_attach(sender()) |);
.

method link
    disallow_overrides;
    arg place;

    if (!.is_owned_by(sender()))
	throw(~perm, "Sender does not own exit.");
    if (!place.follows('room))
	throw(~type, "Place doesn't follow room protocol.");
    (> place.will_link(sender()) <);
    dest = place;
    (| place.did_link(sender()) |);
.