/
LIB3/
LIB3/D/ADMIN/
LIB3/D/ADMIN/OBJ/
LIB3/D/ADMIN/ROOM/W/
LIB3/D/HOME/
LIB3/D/HOME/CITY/ARENA/
LIB3/D/HOME/CITY/ITEMS/
LIB3/D/HOME/CITY/POSTOFFI/
LIB3/DOC/
LIB3/GLOBAL/SPECIAL/
LIB3/GLOBAL/VIRTUAL/
LIB3/NET/
LIB3/NET/CONFIG/
LIB3/NET/DAEMON/CHARS/
LIB3/NET/GOPHER/
LIB3/NET/INHERIT/
LIB3/NET/OBJ/
LIB3/NET/SAVE/
LIB3/NET/VIRTUAL/
LIB3/OBJ/B_DAY/
LIB3/OBJ/HANDLERS/TERM_TYP/
LIB3/PLAYERS/B/
LIB3/PLAYERS/N/
LIB3/ROOM/
LIB3/SAVE/
LIB3/SAVE/BOARDS/
LIB3/SAVE/ENVIRON/
LIB3/SAVE/POST/
LIB3/STD/COMMANDS/SHADOWS/
LIB3/STD/CREATOR/
LIB3/STD/DOM/
LIB3/STD/EFFECTS/
LIB3/STD/EFFECTS/HEALING/
LIB3/STD/EFFECTS/OTHER/
LIB3/STD/EFFECTS/POISONS/
LIB3/STD/ENVIRON/
LIB3/STD/GUILDS/
LIB3/STD/LIQUIDS/
LIB3/STD/ROOM/
LIB3/STD/TRIGGER/SHADOW/
LIB3/W/
LIB3/W/BANNOR/
LIB3/W/NEWSTYLE/
/*
   ** The room_handler.
   ** Handles door types, and checks exits between rooms.
   ** Optimised by Newstyle, 93/10/01
 */

mapping exit_types;
mapping door_types;
mapping opposite;

/* ({ messsage, obvious, size, function }) */
void    create()
{
    exit_types = ([ 
  "standard":	       ({ 0, 1, 10, 0 }),	/* Same as corridor */
  "door":	       ({ 0, 1, 5, 0 }),	/* Opens and Closes */
  "secret":	       ({ 0, 0, 5, 0 }),	/* Invisible door */
  "corridor":	       ({ 0, 1, 10, 0 }),	/* Small non-door exit */
  "hidden":	       ({ 0, 0, 5, 0 }),	/* Invisible non-door */
  "stair":	       ({ 0, 1, 5, 0 }),	/* Specialised corridor */
  "gate":	       ({ 0, 1, 15, 0 }),	/* Fairly large exit */
  "path":	       ({ 0, 1, 20, 0 }),	/* Small road */
  "road":	       ({ 0, 1, 30, 0 }),
  "plain":	       ({ 0, 1, 100, 0 }),	/* Huge exit */
		        ]);
    door_types = ([ 
  "door":	       ({ 0, 0, "generic_key", 100 }),
  "secret":	       ({ 0, 0, "generic_key", 100 }),
  "gate":	       ({ 1, 0, "generic_key", 100 }),
		        ]);
  opposite = ([ "north": ({ 0, "the south" }), "south":({ 0, "the north" }),
  "east": ({ 0, "the west" }), "west":({ 0, "the east" }),
  "northeast":	  ({ 0, "the southwest" }),
  "northwest":	  ({ 0, "the southeast" }),
  "southeast":	  ({ 0, "the northwest" }),
  "southwest":	  ({ 0, "the northeast" }),
  "up": ({ 0, "below" }), "down":({ 0, "above" }),
  "out": ({ 0, "inside" }), "in":({ 0, "outside" }),
  "exit": ({ 0, "inside" }), "enter":({ 0, "outside" }) ]);
}

int     add_exit_type( string type, mixed message, mixed obvious, int size,
		       mixed func )
{
    if( exit_types[ type ] )
	return 0;
    exit_types[ type ] = ({ message, obvious, size, func });
    return 1;
}

int     remove_exit_type( string type )
{
    exit_types = m_delete( exit_types, type );
    return 1;
}

mixed * query_door_type( string type, string direc, string dest )
{
    if( !door_types[ type ] )
	return 0;

/* If there isnt a door on the other side, don't join. */
    call_out( "check_door", 0, ({ previous_object(), direc, dest }) );
    return door_types[ type ] + ({ 0 });
}

void    check_door( mixed bing )
{
    mixed   frog;

    if( !find_object( bing[ 2 ] ) )
	if( catch( call_other( bing[ 2 ], "??" ) ) )
	{			/* room failed to load. */
	    bing[ 0 ]->modify_exit( bing[ 1 ], ({ "undoor", 0 }) );
	    if( objectp( bing[ 0 ] ) )
		bing[ 0 ] = file_name( bing[ 0 ] );
	    if( objectp( bing[ 2 ] ) )
		bing[ 2 ] = file_name( bing[ 2 ] );
	    if( stringp( bing[ 0 ] ) && stringp( bing[ 2 ] ) )
		log_file( "BAD_DOORS", bing[ 2 ] + " not loading from " + bing[ 0 ] + "\n" );
	    else
		log_file( "BAD_DOORS", "Unknown error type for reporting.\n" );
	    return;
	}
    frog = (mixed)bing[ 2 ]->query_door( bing[ 0 ] );
    if( !frog )
	bing[ 0 ]->modify_exit( bing[ 1 ], ({ "undoor", 0 }) );
    else
	bing[ 0 ]->modify_exit( bing[ 1 ], ({ "other", frog }) );
}

mixed * query_exit_type( string type, string dir )
{
    mixed   s;

    if( !(s = opposite[ dir ]) )
	s = ({ 0, "elsewhere" });
    if( !exit_types[ type ] )
	return exit_types[ "standard" ] + ({ s });
    return exit_types[ type ] + ({ s });
}