/
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 under water standard thingy. */
inherit "/std/room";

#define ADD_ARR(ob, arr) if (member_array(ob, arr) == -1) arr += ({ ob });
static object *decrease;

int     check_breath( object ob );

void    create()
{
    decrease = ({ });
    ::create();
}

int     query_underwater()
{
    return 1;
}

/*
 * check for things like whether they can live when they enter the room.
 */
void    event_enter( object ob, string mess, object from )
{
    if( !living( ob ) )
	return;
    set_heart_beat( 1 );
    if( from && !from->query_underwater() )
    {
	if( ob->query_water_breathing() )	/* Spell or something */
	    return;
/* Init the time the player can stay under water, 1-2 minutes */
	ob->add_property( "water breathing", 30 + random( 30 ) );
/* Check for breathing aperatus. */
	if( sizeof( filter_array( all_inventory( ob ), "check_init_breath",
				  this_object() ) ) )
	    return;
	ADD_ARR( ob, decrease )
	    return;
    }
    else
    {
	if( ob->query_water_breathing() )	/* Spell or something */
	    return;
/* Check for breathing aperatus. */
	if( sizeof( filter_array( all_inventory( ob ), "check_breath",
				  this_object() ) ) )
	    return;
/* Init the time the player can stay under water, 1-2 minutes */
	if( check_breath( ob ) )
	    return;
    }
    tell_object( ob, "You are chokeing!  You cannot breath underwater!\n" );
    this_object()->player_drowning( ob );
}

void    event_exit( object ob )
{
    decrease = decrease - all_inventory( ob );
}

/*
 * Default make them leave up.
 */
void    player_drowning( object ob )
{
    this_object()->do_exit_command( "up", "up", ob );
}

/*
 * Ok, two sorts of breathing thingys.  Ones that are infinite and ones
 * that last for definite periods of time.  Will turn on heart_beat and
 * decrease the ones that need decreasing every heart_beat.
 */
int     check_breath( object ob )
{
    if( ob->query_property( "water breathing" ) )
    {
	ADD_ARR( ob, decrease )
	    set_heart_beat( 1 );
	return 1;
    }
    return 0;
}

int     check_init_breath( object ob )
{
    int     i;

    if( !ob->init_water_breathing() )
	if( !(i = (int)ob->query_property( "time for water breathing" )) )
	    return 0;
	else
	    ob->add_property( "water breathing", i );
    ADD_ARR( ob, decrease )
	set_heart_beat( 1 );
    return 1;
}

int     check_living( object ob )
{
    return living( ob );
}

void    heart_beat()
{
    int     i, num;
    object *liv;

    if( !sizeof( liv = filter_array( all_inventory(), "check_living",
				     this_object() ) ) )
	set_heart_beat( 0 );
    decrease = decrease - ({ 0 });
    for( i = 0; i < sizeof( decrease ); i++ )
	decrease[ i ]->add_property( "water breathing",
				     (int)decrease[ i ]->query_property( "water breathing" ) - 1 );
    for( i = 0; i < sizeof( liv ); i++ )
	event_enter( liv[ i ], 0, this_object() );
}

object *query_decrease()
{
    return decrease;
}