/
CDC-1.2b/
CDC-1.2b/src/
parent $physical
object $located

var $located inited 0
var $located location $nowhere
var $root child_index 0
var $root owners [$located]
var $root fertile 0
var $has_verbs verbs #[]
var $root owned [$located]
var $gendered gender $gender_neuter
var $located obvious 1
var $described prose #[]
var $root manager $located
var $root writable [$located]
var $root readable ['parameters, 'methods, 'code]
var $root dbref 'located
var $named name ['uniq, "Generic Located Object"]
var $named name_aliases []

method init_located
    .perms($root, caller());
    location = $nowhere;
    location.add_sender_to_contents();
    obvious = 1;
.

method uninit
    if (caller() != $root)
        throw(~perm, "Caller is not root.");
    location.del_sender_from_contents();
    location = 0;
.

method environment
    return [this()] + setremove(location.environment(), this());
.

method match_environment
    arg str;
    var thing, matches;
    
    if (str == "here") {
        return location;
    } else if (str in ["everyone", "everybody", "everything"]) {
        matches = [];
        if (str in ["everyone", "everybody"]) {
            for thing in (setremove((.location()).contents(), this())) {
                if (thing.has_ancestor($user))
                    matches = [@matches, thing];
            }
        } else {
            matches = (.location()).contents();
        }
        if (listlen(matches) > 1)
            throw(~ambig, "Several matches.", matches);
        else if (matches)
            return matches[1];
        else
            throw(~objnf, "No matches.");
    } else {
        return (> pass(str) <);
    }
.

method location
    disallow_overrides;
    
    return location || $void;
.

method _move_to
    disallow_overrides;
    arg place;
    var old;
    
    if (sender() != this())
        throw(~perm, "Use .move_to()");
    
    // Don't do anything if we're already here.
    if (place == location)
        return;
    if (!(place.has_ancestor($location)))
        throw(~type, "Argument is not a location.");
    
    // Notify involved parties of impending move, allowing them to throw
    // errors.
    if (!valid(location))
        location = $nowhere;
    (> .will_move(sender(), place) <);
    (> location.will_leave(place) <);
    (> place.will_arrive(location) <);
    
    // Set location.
    old = location;
    location = place;
    old.del_sender_from_contents();
    place.add_sender_to_contents();
    
    // Notify involved parties of completed move, in reverse order.
    place.did_arrive(old);
    old.did_leave(place);
    .did_move(sender(), old);
.

method will_move
    arg mover, place;
    
    if ((caller() != definer()) || (sender() != this()))
        throw(~perm, "Invalid call to protected method.");
.

method did_move
    arg mover, old_place;
    
    if ((caller() != definer()) || (sender() != this()))
        throw(~perm, "Invalid call to protected method.");
.

method realm
    return realm;
.

method uninit_located
    if (caller() != $root)
        throw(~perm, "Caller is not root.");
    (.location()).del_sender_from_contents();
.

method move_to
    arg place;
    
    if (.is_writable_by(sender())) {
        ._move_to(place);
    } else {
        // we will have to get some checking and validation in here.
        ._move_to(place);
    }
.

method match_environment_all
    arg s;
    
    if (s == "here")
        return [location, @(> pass(@args) <)];
    else
        return (> pass(s) <);
.

method obvious
    return obvious;
.

method set_obvious
    arg obv;
    
    .perms(sender());
    obvious = obv;
.

method realm_name
    return (.location()).realm_name();
.

method local_verb_templates
    var obj, out;
    
    return (.location()).local_verb_templates();
.