private mixed heart_beat;	/* heart_beat key */

/*
 * NAME:	call_out()
 * DESCRIPTION:	handle a call_out
 */
static varargs void call_out(string func, int delay, mixed args...)
{
    ARGCHECK(func, call_out, 1);

    if (func == "_F_heart_beat" || func == "_F_reset") {
	return;
    }
    add_call_out(delay);
    ::call_out(func, delay, args...);
}

/*
 * NAME:	remove_call_out()
 * DESCRIPTION:	remove a call_out
 */
static int remove_call_out(string func)
{
    if (func == "_F_heart_beat" || func == "_F_reset") {
	return -1;
    }
    return ::remove_call_out(func);
}

/*
 * NAME:	set_heart_beat()
 * DESCRIPTION:	start or stop the heart_beat
 */
static int set_heart_beat(int flag)
{
    if (flag) {
	if (!arrayp(heart_beat)) {
	    heart_beat = ({ });
	    ::call_out("_F_heart_beat", 1 + (time() & 1), heart_beat);
	    add_heart_beat();
	    return 1;
	}
    } else {
	if (arrayp(heart_beat)) {
	    ::remove_call_out("_F_heart_beat");
	    del_heart_beat();
	    heart_beat = 0;
	    return 1;
	}
	heart_beat = 0;
    }
    return 0;
}

/*
 * NAME:	_F_heart_beat()
 * DESCRIPTION:	handle heart_beat calls
 */
nomask void _F_heart_beat(mixed key)
{
    if (key == heart_beat && arrayp(key)) {
	heart_beat = 1;
	del_heart_beat();
	if (living(this_object())) {
	    set_this_player(this_object());
	} else {
	    set_this_player(0);
	}
	this_object()->heart_beat();
	if (heart_beat == 1) {
	    heart_beat = key;
	    ::call_out("_F_heart_beat", 1 + (time() & 1), key);
	    add_heart_beat();
	}
    }
}