ds2.9a12/bin/
ds2.9a12/extra/
ds2.9a12/extra/crat/
ds2.9a12/extra/creremote/
ds2.9a12/extra/mingw/
ds2.9a12/extra/wolfpaw/
ds2.9a12/fluffos-2.14-ds13/
ds2.9a12/fluffos-2.14-ds13/Win32/
ds2.9a12/fluffos-2.14-ds13/compat/
ds2.9a12/fluffos-2.14-ds13/compat/simuls/
ds2.9a12/fluffos-2.14-ds13/include/
ds2.9a12/fluffos-2.14-ds13/testsuite/
ds2.9a12/fluffos-2.14-ds13/testsuite/clone/
ds2.9a12/fluffos-2.14-ds13/testsuite/command/
ds2.9a12/fluffos-2.14-ds13/testsuite/data/
ds2.9a12/fluffos-2.14-ds13/testsuite/etc/
ds2.9a12/fluffos-2.14-ds13/testsuite/include/
ds2.9a12/fluffos-2.14-ds13/testsuite/inherit/
ds2.9a12/fluffos-2.14-ds13/testsuite/inherit/master/
ds2.9a12/fluffos-2.14-ds13/testsuite/log/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/compiler/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/efuns/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/operators/
ds2.9a12/fluffos-2.14-ds13/testsuite/u/
ds2.9a12/lib/cmds/admins/
ds2.9a12/lib/cmds/common/
ds2.9a12/lib/cmds/creators/include/
ds2.9a12/lib/daemon/services/
ds2.9a12/lib/daemon/tmp/
ds2.9a12/lib/doc/
ds2.9a12/lib/doc/bguide/
ds2.9a12/lib/doc/efun/all/
ds2.9a12/lib/doc/efun/arrays/
ds2.9a12/lib/doc/efun/buffers/
ds2.9a12/lib/doc/efun/compile/
ds2.9a12/lib/doc/efun/floats/
ds2.9a12/lib/doc/efun/functions/
ds2.9a12/lib/doc/efun/general/
ds2.9a12/lib/doc/efun/mixed/
ds2.9a12/lib/doc/efun/numbers/
ds2.9a12/lib/doc/efun/parsing/
ds2.9a12/lib/doc/hbook/
ds2.9a12/lib/doc/help/classes/
ds2.9a12/lib/doc/help/races/
ds2.9a12/lib/doc/lfun/
ds2.9a12/lib/doc/lfun/all/
ds2.9a12/lib/doc/lfun/lib/abilities/
ds2.9a12/lib/doc/lfun/lib/armor/
ds2.9a12/lib/doc/lfun/lib/bank/
ds2.9a12/lib/doc/lfun/lib/bot/
ds2.9a12/lib/doc/lfun/lib/clay/
ds2.9a12/lib/doc/lfun/lib/clean/
ds2.9a12/lib/doc/lfun/lib/clerk/
ds2.9a12/lib/doc/lfun/lib/client/
ds2.9a12/lib/doc/lfun/lib/combat/
ds2.9a12/lib/doc/lfun/lib/connect/
ds2.9a12/lib/doc/lfun/lib/container/
ds2.9a12/lib/doc/lfun/lib/corpse/
ds2.9a12/lib/doc/lfun/lib/creator/
ds2.9a12/lib/doc/lfun/lib/daemon/
ds2.9a12/lib/doc/lfun/lib/damage/
ds2.9a12/lib/doc/lfun/lib/deterioration/
ds2.9a12/lib/doc/lfun/lib/donate/
ds2.9a12/lib/doc/lfun/lib/door/
ds2.9a12/lib/doc/lfun/lib/equip/
ds2.9a12/lib/doc/lfun/lib/file/
ds2.9a12/lib/doc/lfun/lib/fish/
ds2.9a12/lib/doc/lfun/lib/fishing/
ds2.9a12/lib/doc/lfun/lib/flashlight/
ds2.9a12/lib/doc/lfun/lib/follow/
ds2.9a12/lib/doc/lfun/lib/ftp_client/
ds2.9a12/lib/doc/lfun/lib/ftp_data_connection/
ds2.9a12/lib/doc/lfun/lib/fuel/
ds2.9a12/lib/doc/lfun/lib/furnace/
ds2.9a12/lib/doc/lfun/lib/genetics/
ds2.9a12/lib/doc/lfun/lib/holder/
ds2.9a12/lib/doc/lfun/lib/id/
ds2.9a12/lib/doc/lfun/lib/interactive/
ds2.9a12/lib/doc/lfun/lib/lamp/
ds2.9a12/lib/doc/lfun/lib/leader/
ds2.9a12/lib/doc/lfun/lib/light/
ds2.9a12/lib/doc/lfun/lib/limb/
ds2.9a12/lib/doc/lfun/lib/living/
ds2.9a12/lib/doc/lfun/lib/load/
ds2.9a12/lib/doc/lfun/lib/look/
ds2.9a12/lib/doc/lfun/lib/manipulate/
ds2.9a12/lib/doc/lfun/lib/meal/
ds2.9a12/lib/doc/lfun/lib/messages/
ds2.9a12/lib/doc/lfun/lib/player/
ds2.9a12/lib/doc/lfun/lib/poison/
ds2.9a12/lib/doc/lfun/lib/position/
ds2.9a12/lib/doc/lfun/lib/post_office/
ds2.9a12/lib/doc/lfun/lib/potion/
ds2.9a12/lib/doc/lfun/lib/room/
ds2.9a12/lib/doc/lfun/lib/server/
ds2.9a12/lib/doc/lfun/lib/spell/
ds2.9a12/lib/doc/lfun/lib/torch/
ds2.9a12/lib/doc/lfun/lib/vendor/
ds2.9a12/lib/doc/lfun/lib/virt_sky/
ds2.9a12/lib/doc/lfun/lib/weapon/
ds2.9a12/lib/doc/lfun/lib/worn_storage/
ds2.9a12/lib/doc/lpc/basic/
ds2.9a12/lib/doc/lpc/concepts/
ds2.9a12/lib/doc/lpc/constructs/
ds2.9a12/lib/doc/lpc/etc/
ds2.9a12/lib/doc/lpc/intermediate/
ds2.9a12/lib/doc/lpc/types/
ds2.9a12/lib/doc/misc/
ds2.9a12/lib/doc/old/
ds2.9a12/lib/domains/
ds2.9a12/lib/domains/Praxis/adm/
ds2.9a12/lib/domains/Praxis/attic/
ds2.9a12/lib/domains/Praxis/cemetery/mon/
ds2.9a12/lib/domains/Praxis/data/
ds2.9a12/lib/domains/Praxis/death/
ds2.9a12/lib/domains/Praxis/mountains/
ds2.9a12/lib/domains/Praxis/obj/armour/
ds2.9a12/lib/domains/Praxis/obj/magic/
ds2.9a12/lib/domains/Praxis/obj/weapon/
ds2.9a12/lib/domains/Praxis/orc_valley/
ds2.9a12/lib/domains/Ylsrim/
ds2.9a12/lib/domains/Ylsrim/adm/
ds2.9a12/lib/domains/Ylsrim/armor/
ds2.9a12/lib/domains/Ylsrim/broken/
ds2.9a12/lib/domains/Ylsrim/fish/
ds2.9a12/lib/domains/Ylsrim/meal/
ds2.9a12/lib/domains/Ylsrim/npc/
ds2.9a12/lib/domains/Ylsrim/obj/
ds2.9a12/lib/domains/Ylsrim/virtual/
ds2.9a12/lib/domains/Ylsrim/weapon/
ds2.9a12/lib/domains/campus/adm/
ds2.9a12/lib/domains/campus/etc/
ds2.9a12/lib/domains/campus/meals/
ds2.9a12/lib/domains/campus/save/
ds2.9a12/lib/domains/campus/txt/ai/charles/
ds2.9a12/lib/domains/campus/txt/ai/charles/bak2/
ds2.9a12/lib/domains/campus/txt/ai/charles/bak2/bak1/
ds2.9a12/lib/domains/campus/txt/ai/charly/
ds2.9a12/lib/domains/campus/txt/ai/charly/bak/
ds2.9a12/lib/domains/campus/txt/jenny/
ds2.9a12/lib/domains/cave/doors/
ds2.9a12/lib/domains/cave/etc/
ds2.9a12/lib/domains/cave/meals/
ds2.9a12/lib/domains/cave/weap/
ds2.9a12/lib/domains/default/creator/
ds2.9a12/lib/domains/default/doors/
ds2.9a12/lib/domains/default/etc/
ds2.9a12/lib/domains/default/vehicles/
ds2.9a12/lib/domains/default/virtual/
ds2.9a12/lib/domains/default/weap/
ds2.9a12/lib/domains/town/txt/shame/
ds2.9a12/lib/domains/town/virtual/
ds2.9a12/lib/domains/town/virtual/bottom/
ds2.9a12/lib/domains/town/virtual/space/
ds2.9a12/lib/estates/
ds2.9a12/lib/ftp/
ds2.9a12/lib/lib/comp/
ds2.9a12/lib/lib/daemons/
ds2.9a12/lib/lib/daemons/include/
ds2.9a12/lib/lib/lvs/
ds2.9a12/lib/lib/user/
ds2.9a12/lib/lib/virtual/
ds2.9a12/lib/log/
ds2.9a12/lib/log/adm/
ds2.9a12/lib/log/archive/
ds2.9a12/lib/log/chan/
ds2.9a12/lib/log/errors/
ds2.9a12/lib/log/law/adm/
ds2.9a12/lib/log/law/email/
ds2.9a12/lib/log/law/names/
ds2.9a12/lib/log/law/sites-misc/
ds2.9a12/lib/log/law/sites-register/
ds2.9a12/lib/log/law/sites-tempban/
ds2.9a12/lib/log/law/sites-watch/
ds2.9a12/lib/log/open/
ds2.9a12/lib/log/reports/
ds2.9a12/lib/log/router/
ds2.9a12/lib/log/secure/
ds2.9a12/lib/log/watch/
ds2.9a12/lib/obj/book_source/
ds2.9a12/lib/obj/include/
ds2.9a12/lib/powers/prayers/
ds2.9a12/lib/powers/spells/
ds2.9a12/lib/realms/template/adm/
ds2.9a12/lib/realms/template/area/armor/
ds2.9a12/lib/realms/template/area/npc/
ds2.9a12/lib/realms/template/area/obj/
ds2.9a12/lib/realms/template/area/room/
ds2.9a12/lib/realms/template/area/weap/
ds2.9a12/lib/realms/template/bak/
ds2.9a12/lib/realms/template/cmds/
ds2.9a12/lib/save/kills/o/
ds2.9a12/lib/secure/cfg/classes/
ds2.9a12/lib/secure/cmds/builders/
ds2.9a12/lib/secure/cmds/creators/include/
ds2.9a12/lib/secure/cmds/players/
ds2.9a12/lib/secure/cmds/players/include/
ds2.9a12/lib/secure/daemon/imc2server/
ds2.9a12/lib/secure/daemon/include/
ds2.9a12/lib/secure/lib/
ds2.9a12/lib/secure/lib/include/
ds2.9a12/lib/secure/lib/net/include/
ds2.9a12/lib/secure/lib/std/
ds2.9a12/lib/secure/log/adm/
ds2.9a12/lib/secure/log/bak/
ds2.9a12/lib/secure/log/intermud/
ds2.9a12/lib/secure/log/network/
ds2.9a12/lib/secure/modules/
ds2.9a12/lib/secure/npc/
ds2.9a12/lib/secure/obj/include/
ds2.9a12/lib/secure/room/
ds2.9a12/lib/secure/save/
ds2.9a12/lib/secure/save/backup/
ds2.9a12/lib/secure/save/boards/
ds2.9a12/lib/secure/tmp/
ds2.9a12/lib/secure/upgrades/files/
ds2.9a12/lib/secure/verbs/creators/
ds2.9a12/lib/std/board/
ds2.9a12/lib/std/lib/
ds2.9a12/lib/tmp/
ds2.9a12/lib/verbs/admins/include/
ds2.9a12/lib/verbs/builders/
ds2.9a12/lib/verbs/common/
ds2.9a12/lib/verbs/common/include/
ds2.9a12/lib/verbs/creators/
ds2.9a12/lib/verbs/creators/include/
ds2.9a12/lib/verbs/rooms/
ds2.9a12/lib/verbs/rooms/include/
ds2.9a12/lib/www/client/
ds2.9a12/lib/www/errors/
ds2.9a12/lib/www/images/
ds2.9a12/lib/www/lpmuds/downloads_files/
ds2.9a12/lib/www/lpmuds/intermud_files/
ds2.9a12/lib/www/lpmuds/links_files/
ds2.9a12/win32/
/*    /lib/door.c
 *    from the Dead Souls LPC Library
 *    the standard door, window, rock object
 *    created by Descartes of Borg 950410
 *    with many thanks to Balack@Phoenix and Deathblade@ZorkMUD for their ideas
 *    Version: @(#) door.c 1.8@(#)
 *    Last modified: 97/01/01
 */

#include <lib.h>
#include "include/door.h"

inherit LIB_DAEMON;
inherit LIB_SEAL;
inherit LIB_KNOCK;
inherit LIB_SCRATCH;

private mapping Sides;
private static int Hidden = 1;
private static int Opacity = 100;
private static int Perforated = 0;

int GetOpacity(){
    return Opacity;
}

int SetOpacity(int x){
    Opacity = x;
    return Opacity;
}

int GetPerforated(){
    return Perforated;
}

int SetPerforated(int x){
    Perforated = x;
    return Perforated;
}

int CanPeer(){
    if(!GetClosed() || !Opacity) return 1;
    return 0;
}

int SetHiddenDoor(int i){
    if(i) Hidden = 1;
    else Hidden = 0;
    return Hidden;
}

int GetHiddenDoor(){
    return Hidden;
}

string *GetSides(){
    return keys(Sides);
}

/*  ***************  /lib/door.c driver applies  ***************  */

static void create(){
    daemon::create();
    parse_init();
    SetNoClean(0);
    SetLockStrength(50);
    Sides = ([]);
}

/*  ***************  /lib/door.c modals  **************  */
/* method: CanLock()
 * args:
 *    object who - the person doing the locking
 *    object key - the key being used for the locking
 *
 * returns: 1 on success, 0 or failure string on failure
 *
 * Tests to see if a certain player can lock the door with a given
 * key
 */
mixed CanLock(object who, string foo){
    object room;
    if( !(room = environment(who)) ) return 0;
    foreach(string side, mapping val in Sides){
        if( member_array(room, val["Rooms"]) != -1 ){
            if( !GetLockable(side) ) return 0;
            else return seal::CanLock(who);
        }
    }
    return 0;
}

/* method: CanUnlock()
 * args:
 *    object who - the person doing the unlocking
 *    object key - the key being used for the unlocking
 *
 * returns: 1 on success, 0 or failure string on failure
 *
 * Tests to see if a certain player can unlock the door with a given
 * key
 */
mixed CanUnlock(object who){
    object room;

    if( !(room = environment(who)) ) return 0;
    foreach(string side, mapping val in Sides){
        if( member_array(room, val["Rooms"]) != -1 ){
            if( !GetLockable(side) ) return 0;
            else return seal::CanUnlock(who);
        }
    }
    return 0;
}

/*  ***************  /lib/door.c events  **************  */

/* eventClose()
 * object who - who is closing it
 *
 * returns 1,0, or an error string based on parser conditions
 *
 * Check to be certain the door is not already closed before calling so
 * you may issue the appropriate message
 */

varargs mixed eventClose(object who){
    object room,whom;
    string tmp;

    if(!GetClosed()){
        SetClosed(1);
        if(who) room = environment(who);
        else room = environment(this_player());
        if(!who) whom = this_player();
        else whom = who;
        foreach(string side, mapping val in Sides){
            if( member_array(environment(whom), val["Rooms"]) != -1 ) tmp = side;
            if(who)
                filter(val["Rooms"], (: $1 && ($1 != $(room)):))->eventPrint(capitalize(GetShort(side)) + " closes.");
            else (val["Rooms"])->eventPrint(capitalize(GetShort(side)) + " closes.");
        }
        if(who){
            who->eventPrint("You close " + GetShort(tmp) + ".");
            room->eventPrint((string)who->GetName() + " closes " + GetShort(tmp) + ".",
              who);
        }
    }
    return 1;
}

/* eventLock()
 * object who - the agent responsible for locking it
 * object key - the key being used to lock it
 * returns 1, 0 or a string according to parser conditions
 *
 * Check to make sure the door is closed and unlocked before calling this
 * Also check to see that the door is lockable from this side
 * object by is required here
 */

varargs mixed eventLock(object who, mixed key, mixed foo){
    object room;

    room = environment(who);

    foreach(string side, mapping val in Sides){
        if( member_array(room, val["Rooms"]) != -1 ){
            string tmp;

            tmp = GetShort(side);
            if( !(sizeof(key->GetId() & GetKeys(side))) ){
                who->eventPrint("You fail to lock " + tmp +
                  " with " + (string)key->GetShort()+".");
                room->eventPrint((string)who->GetName() + " attempts to " 
                  "lock " + tmp + " with " +
                  (string)key->GetShort() + ", but fails.",who);
                return 1;
            }
            SetLocked(1);
            who->eventPrint("You lock " + tmp +
              " with " + (string)key->GetShort()+".");
            room->eventPrint((string)who->GetName() + " locks " + tmp +
              " with " + (string)key->GetShort() + ".", who);
            return 1;
        }
    }
    return 0;
}

/* eventOpen()
 * object by - The room from which the door is being open
 * object agent - The living thing responsible for it opening
 *
 * returns 1, 0, or an error string depending on parser circumstances
 *
 * Used for actually opening the door
 * Before calling this, you should check if the door is locked and
 * check if it is already open so you can issue the appropriate messages
 */

varargs int eventOpen(object who, object tool){
    object room, whom;
    string tmp;

    if(GetClosed()){
        SetClosed(0);
        if(who) room = environment(who);
        else room = environment(this_player());
        if(!who) whom = this_player();
        else whom = who;
        foreach(string side, mapping val in Sides){
            if( member_array(environment(whom), val["Rooms"]) != -1 ) tmp = side;
            if(who)
                filter(val["Rooms"], (: $1 && ($1 != $(room)) :))->eventPrint(capitalize(GetShort(side)) + " opens.");
            else (val["Rooms"])->eventPrint(capitalize(GetShort(side)) + " opens.");
        }
        if(who){
            who->eventPrint("You open " + GetShort(tmp) + ".");
            room->eventPrint((string)who->GetName() + " opens " + GetShort(tmp) + ".",
              who);
        }
    }
    return 1;
}

/* eventRegisterSide()
 * string side - directional exit identifying which side of the door this room
 *               exits in
 *
 * returns 1 on success, 0 on failure
 *
 * never should be called manually
 * this is called by SetDoor() in exits.c to tell the door there is a room
 * which is observing it
 */

int eventRegisterSide(string side){
    string array id = GetId(side);
    Sides[side]["Rooms"] = 
    distinct_array(Sides[side]["Rooms"] +
      ({ previous_object() }));
    previous_object()->AddItem(id, (: GetLong($(side)) :));
    foreach(object ob in all_inventory(previous_object())){
        if( !ob->isDummy() ){
            continue;
        }
        if( sizeof(id & ob->GetId()) ){
            if(!ob->GetDoor()) ob->SetDoor(file_name(this_object()), side);
        }
    }
    return 1;
}

/* method: eventUnlock()
 * args:
 *    object who - the person unlocking the door
 *    object key - the key being used to unlock it
 *
 * returns: 1 on success, 0 or failure string on failure
 *
 * Check to make sure the door is closed and locked before calling this
 * Also check to see that the door is lockable from this side
 * object by is required here
 */
mixed eventUnlock(object who, object key){
    object room;
    string *key_id = key->GetId();
    room = environment(who);
    foreach(string side, mapping val in Sides){
        if( member_array(room, val["Rooms"]) != -1 ){
            string tmp;

            tmp = GetShort(side);
            if(!sizeof((key_id & (GetKeys(side) || ({}))))){
                who->eventPrint("You fail to unlock " + tmp +
                  " with " + (string)key->GetShort()+".");
                room->eventPrint((string)who->GetName() + " attempts to "
                  "unlock " + tmp + " with " +
                  (string)key->GetShort() + ", but fails.",who);
                return 1;
            }
            SetLocked(0);
            who->eventPrint("You unlock " + tmp + ".");
            room->eventPrint((string)who->GetName() + " unlocks " + tmp +
              " with " + (string)key->GetShort() + ".", who);
            return 1;
        }
    }
    return 0;
}

/*  **************  /lib/door.c data functions  **************  */

void SetSide(string side, mapping mp){
    mapping new_side = ([ "Rooms" : ({}) ]);

    if( stringp(mp["id"]) ) new_side["Ids"] = ({ mp["id"] });
    else new_side["Ids"] = mp["id"];
    new_side["Short"] = mp["short"];
    new_side["Long"] = mp["long"];
    if( stringp(mp["keys"]) ) new_side["Keys"] = ({ mp["keys"] });
    else new_side["Keys"] = mp["keys"];
    new_side["Lockable"] = mp["lockable"];
    Sides[side] = new_side;
}

mapping GetSide(string side){
    mapping RetMap = ([]);
    if(!sizeof(Sides[side])) return ([]);
    RetMap["id"] = Sides[side]["Ids"];
    RetMap["short"] = Sides[side]["Short"];
    RetMap["long"] = Sides[side]["Long"];
    RetMap["keys"] = Sides[side]["Keys"];
    RetMap["lockable"] = Sides[side]["Lockable"];
    return copy(RetMap);
}

int SetLockable(string side, int x){
    if( !Sides[side] )
        Sides[side] = ([ "Rooms" : ({}) ]);
    return Sides[side]["Lockable"] = x; 
}

int GetLockable(string side){
    return Sides[side]["Lockable"];
}

varargs string *SetId(string side, mixed *args...){ 
    if( !Sides[side] ) Sides[side] = ([ "Rooms" : ({}) ]);
    Sides[side]["Ids"] = ({});
    foreach(mixed val in args){
        if( stringp(val) ) Sides[side]["Ids"] += ({ val });
        else Sides[side]["Ids"] += val;
    }
    return Sides[side]["Ids"];
}

string *GetId(string side){ 
    if(!Sides[side]) return ({});
    return Sides[side]["Ids"];
}

mixed SetShort(string side, mixed short){
    if( !Sides[side] )
        Sides[side] = ([ "Rooms" : ({}) ]);
    return Sides[side]["Short"] = short;
}

varargs string GetShort(string side){
    if( !side){ /* let's hack a side */
        object room;
        side = previous_object()->GetDoorSide();
        if( !this_player() ) room = previous_object();
        else room = environment(this_player());
        foreach(string s, mapping val in Sides){
            if(!side) side = s;
            if( member_array(room, val["Rooms"]) != -1 ) break;
        }
    }
    if( stringp(Sides[side]["Short"]) )
        return Sides[side]["Short"];
    else return (string)evaluate(Sides[side]["Short"], side);
}

string GetDefiniteShort(){
    string tmp = GetShort();

    return add_article(tmp, 1);
}

mixed SetLong(string side, mixed long){
    if( !Sides[side] )
        Sides[side] = ([ "Rooms" : ({}) ]);
    return Sides[side]["Long"] = long;
}

string GetLong(string side){
    string tmp;

    if( GetClosed() ) tmp = "It is closed.";
    else tmp = "It is open.";
    if( stringp(Sides[side]["Long"] ) )
        return Sides[side]["Long"] + "\n" + tmp;
    else return (string)evaluate(Sides[side]["Long"], side);
}

varargs string *SetKeys(string side, mixed *args...){
    if( !Sides[side] ) Sides[side] = ([ "Rooms" : ({}) ]);
    Sides[side]["Keys"] = ({});
    foreach(mixed val in args){
        if( stringp(val) ) Sides[side]["Keys"] += ({ val });
        else Sides[side]["Keys"] += val;
    }
    return Sides[side]["Keys"];
}

string *GetKeys(string side){ return Sides[side]["Keys"]; }

object *GetRooms(string side){ return Sides[side]["Rooms"]; }

int get_closed(){ return GetClosed(); }

varargs mixed eventKnock(object who, mixed what){
    object room,whom;
    string tmp;
    if(GetClosed()){
        if(who) room = environment(who);
        else room = environment(this_player());
        if(!who) whom = this_player();
        else whom = who;
        foreach(string side, mixed val in Sides){
            if( member_array(environment(whom), val["Rooms"]) != -1 ) tmp = side;
            if(who)
                filter(val["Rooms"], (: $1 && ($1 != $(room)):))->eventPrint(
                  "There is a knock at the "+remove_article(GetShort(side)) + ".");
            else (val["Rooms"])->eventPrint(
                  "There is a knock at the "+remove_article(GetShort(side)) + ".");
        }
        if(who){
            who->eventPrint("You knock on the " + remove_article(GetShort(tmp)) + ".");
            room->eventPrint((string)who->GetName() + " knocks on the " + remove_article(GetShort(tmp)) + ".",
              who);
        }
    }
    else write("It isn't closed!");
    return 1;
}

varargs mixed eventScratch(object who, mixed what){
    object room,whom;
    string tmp;
    if(GetClosed()){
        if(who) room = environment(who);
        else room = environment(this_player());
        if(!who) whom = this_player();
        else whom = who;
        foreach(string side, mixed val in Sides){
            if( member_array(environment(whom), val["Rooms"]) != -1 ) tmp = side;
            if(who)
                filter(val["Rooms"], (: $1 && ($1 != $(room)):))->eventPrint(
                  "There is a scratch at the "+remove_article(GetShort(side)) + ".");
            else (val["Rooms"])->eventPrint(
                  "There is a scratch at the "+remove_article(GetShort(side)) + ".");
        }
        if(who){
            who->eventPrint("You scratch on the " + remove_article(GetShort(tmp)) + ".");
            room->eventPrint((string)who->GetName() + " scratches on the " + remove_article(GetShort(tmp)) + ".",
              who);
        }
    }
    else write("It isn't closed!");
    return 1;
}

void init(){
}