skylib_fluffos_v3/
skylib_fluffos_v3/bin/
skylib_fluffos_v3/bin/db/
skylib_fluffos_v3/fluffos-2.9-ds2.04/
skylib_fluffos_v3/fluffos-2.9-ds2.04/ChangeLog.old/
skylib_fluffos_v3/fluffos-2.9-ds2.04/Win32/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/simuls/
skylib_fluffos_v3/fluffos-2.9-ds2.04/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/clone/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/command/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/data/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/etc/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/master/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/log/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/compiler/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/efuns/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/operators/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/u/
skylib_fluffos_v3/fluffos-2.9-ds2.04/tmp/
skylib_fluffos_v3/fluffos-2.9-ds2.04/windows/
skylib_fluffos_v3/mudlib/
skylib_fluffos_v3/mudlib/cmds/
skylib_fluffos_v3/mudlib/cmds/admin/
skylib_fluffos_v3/mudlib/cmds/guild-race/
skylib_fluffos_v3/mudlib/cmds/living/broken/
skylib_fluffos_v3/mudlib/cmds/player/group_cmds/
skylib_fluffos_v3/mudlib/cmds/playtester/
skylib_fluffos_v3/mudlib/d/admin/
skylib_fluffos_v3/mudlib/d/admin/room/
skylib_fluffos_v3/mudlib/d/admin/room/we_care/
skylib_fluffos_v3/mudlib/d/admin/save/
skylib_fluffos_v3/mudlib/d/admin/text/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/buildings/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/map/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/roads/
skylib_fluffos_v3/mudlib/d/learning/chars/
skylib_fluffos_v3/mudlib/d/learning/functions/
skylib_fluffos_v3/mudlib/d/learning/handlers/
skylib_fluffos_v3/mudlib/d/learning/help_topics/
skylib_fluffos_v3/mudlib/d/learning/help_topics/npcs/
skylib_fluffos_v3/mudlib/d/learning/help_topics/objects/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/RCS/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/crowd/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/situations/
skylib_fluffos_v3/mudlib/d/learning/save/
skylib_fluffos_v3/mudlib/d/learning/school/
skylib_fluffos_v3/mudlib/d/learning/school/add_sc/
skylib_fluffos_v3/mudlib/d/learning/school/characters/
skylib_fluffos_v3/mudlib/d/learning/school/general/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/basic_commands/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/edtutor/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/unix_tutor/
skylib_fluffos_v3/mudlib/d/learning/school/items/
skylib_fluffos_v3/mudlib/d/learning/school/npc_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/room_basic/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/situations/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/terrain_tutor/
skylib_fluffos_v3/mudlib/d/learning/text/
skylib_fluffos_v3/mudlib/d/liaison/
skylib_fluffos_v3/mudlib/d/mudlib/
skylib_fluffos_v3/mudlib/d/mudlib/changes/
skylib_fluffos_v3/mudlib/d/playtesters/
skylib_fluffos_v3/mudlib/d/playtesters/effects/
skylib_fluffos_v3/mudlib/d/playtesters/handlers/
skylib_fluffos_v3/mudlib/d/playtesters/items/
skylib_fluffos_v3/mudlib/d/sage/
skylib_fluffos_v3/mudlib/doc/
skylib_fluffos_v3/mudlib/doc/creator/
skylib_fluffos_v3/mudlib/doc/driver/
skylib_fluffos_v3/mudlib/doc/driver/efuns/arrays/
skylib_fluffos_v3/mudlib/doc/driver/efuns/buffers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/calls/
skylib_fluffos_v3/mudlib/doc/driver/efuns/compile/
skylib_fluffos_v3/mudlib/doc/driver/efuns/filesystem/
skylib_fluffos_v3/mudlib/doc/driver/efuns/floats/
skylib_fluffos_v3/mudlib/doc/driver/efuns/functions/
skylib_fluffos_v3/mudlib/doc/driver/efuns/general/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mappings/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mixed/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mudlib/
skylib_fluffos_v3/mudlib/doc/driver/efuns/numbers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/parsing/
skylib_fluffos_v3/mudlib/doc/login/
skylib_fluffos_v3/mudlib/doc/lpc/basic_manual/
skylib_fluffos_v3/mudlib/doc/lpc/intermediate/
skylib_fluffos_v3/mudlib/doc/new/add_command/
skylib_fluffos_v3/mudlib/doc/new/events/
skylib_fluffos_v3/mudlib/doc/new/handlers/
skylib_fluffos_v3/mudlib/doc/new/living/race/
skylib_fluffos_v3/mudlib/doc/new/living/spells/
skylib_fluffos_v3/mudlib/doc/new/object/
skylib_fluffos_v3/mudlib/doc/new/player/
skylib_fluffos_v3/mudlib/doc/new/room/guild/
skylib_fluffos_v3/mudlib/doc/new/room/outside/
skylib_fluffos_v3/mudlib/doc/new/room/storeroom/
skylib_fluffos_v3/mudlib/doc/object/
skylib_fluffos_v3/mudlib/doc/playtesters/
skylib_fluffos_v3/mudlib/doc/policy/
skylib_fluffos_v3/mudlib/doc/weapons/
skylib_fluffos_v3/mudlib/global/
skylib_fluffos_v3/mudlib/global/creator/
skylib_fluffos_v3/mudlib/handlers/
skylib_fluffos_v3/mudlib/include/casino/
skylib_fluffos_v3/mudlib/include/cmds/
skylib_fluffos_v3/mudlib/include/effects/
skylib_fluffos_v3/mudlib/include/npc/
skylib_fluffos_v3/mudlib/include/room/
skylib_fluffos_v3/mudlib/include/shops/
skylib_fluffos_v3/mudlib/net/daemon/
skylib_fluffos_v3/mudlib/net/daemon/chars/
skylib_fluffos_v3/mudlib/net/inherit/
skylib_fluffos_v3/mudlib/net/obj/
skylib_fluffos_v3/mudlib/net/obj/BACKUPS/
skylib_fluffos_v3/mudlib/obj/amulets/
skylib_fluffos_v3/mudlib/obj/armours/plate/
skylib_fluffos_v3/mudlib/obj/b_day/
skylib_fluffos_v3/mudlib/obj/clothes/transport/horse/
skylib_fluffos_v3/mudlib/obj/faith/symbols/
skylib_fluffos_v3/mudlib/obj/fungi/
skylib_fluffos_v3/mudlib/obj/gatherables/
skylib_fluffos_v3/mudlib/obj/instruments/
skylib_fluffos_v3/mudlib/obj/media/
skylib_fluffos_v3/mudlib/obj/misc/player_shop/
skylib_fluffos_v3/mudlib/obj/monster/godmother/
skylib_fluffos_v3/mudlib/obj/monster/transport/
skylib_fluffos_v3/mudlib/obj/rings/
skylib_fluffos_v3/mudlib/obj/scabbards/
skylib_fluffos_v3/mudlib/obj/spells/
skylib_fluffos_v3/mudlib/obj/stationery/
skylib_fluffos_v3/mudlib/obj/stationery/envelopes/
skylib_fluffos_v3/mudlib/obj/toys/
skylib_fluffos_v3/mudlib/obj/vessels/
skylib_fluffos_v3/mudlib/obj/weapons/axes/
skylib_fluffos_v3/mudlib/obj/weapons/chains/
skylib_fluffos_v3/mudlib/obj/weapons/maces/BACKUPS/
skylib_fluffos_v3/mudlib/save/autodoc/
skylib_fluffos_v3/mudlib/save/book_handler/
skylib_fluffos_v3/mudlib/save/books/history/calarien/
skylib_fluffos_v3/mudlib/save/mail/
skylib_fluffos_v3/mudlib/save/new_soul/data/
skylib_fluffos_v3/mudlib/save/parcels/
skylib_fluffos_v3/mudlib/save/playerinfo/
skylib_fluffos_v3/mudlib/save/players/d/
skylib_fluffos_v3/mudlib/save/players/s/
skylib_fluffos_v3/mudlib/save/random_names/
skylib_fluffos_v3/mudlib/save/random_names/data/
skylib_fluffos_v3/mudlib/save/terrains/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_desert/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_grassy_field/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_mountain/
skylib_fluffos_v3/mudlib/save/todo_lists/
skylib_fluffos_v3/mudlib/secure/
skylib_fluffos_v3/mudlib/secure/cmds/admin/
skylib_fluffos_v3/mudlib/secure/cmds/lord/
skylib_fluffos_v3/mudlib/secure/config/
skylib_fluffos_v3/mudlib/secure/handlers/autodoc/
skylib_fluffos_v3/mudlib/secure/handlers/intermud/
skylib_fluffos_v3/mudlib/secure/include/global/
skylib_fluffos_v3/mudlib/secure/save/
skylib_fluffos_v3/mudlib/secure/save/handlers/
skylib_fluffos_v3/mudlib/secure/std/
skylib_fluffos_v3/mudlib/secure/std/classes/
skylib_fluffos_v3/mudlib/secure/std/modules/
skylib_fluffos_v3/mudlib/std/creator/
skylib_fluffos_v3/mudlib/std/dom/
skylib_fluffos_v3/mudlib/std/effects/
skylib_fluffos_v3/mudlib/std/effects/external/
skylib_fluffos_v3/mudlib/std/effects/fighting/
skylib_fluffos_v3/mudlib/std/effects/magic/
skylib_fluffos_v3/mudlib/std/effects/magic/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/other/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/priest/
skylib_fluffos_v3/mudlib/std/effects/room/
skylib_fluffos_v3/mudlib/std/environ/
skylib_fluffos_v3/mudlib/std/guilds/
skylib_fluffos_v3/mudlib/std/guilds/old/
skylib_fluffos_v3/mudlib/std/languages/
skylib_fluffos_v3/mudlib/std/liquids/
skylib_fluffos_v3/mudlib/std/npc/
skylib_fluffos_v3/mudlib/std/npc/goals/
skylib_fluffos_v3/mudlib/std/npc/goals/basic/
skylib_fluffos_v3/mudlib/std/npc/goals/misc/
skylib_fluffos_v3/mudlib/std/npc/plans/
skylib_fluffos_v3/mudlib/std/npc/plans/basic/
skylib_fluffos_v3/mudlib/std/npc/types/
skylib_fluffos_v3/mudlib/std/npc/types/helper/
skylib_fluffos_v3/mudlib/std/npcs/
skylib_fluffos_v3/mudlib/std/outsides/
skylib_fluffos_v3/mudlib/std/races/shadows/
skylib_fluffos_v3/mudlib/std/room/basic/BACKUPS/
skylib_fluffos_v3/mudlib/std/room/basic/topography/
skylib_fluffos_v3/mudlib/std/room/controller/
skylib_fluffos_v3/mudlib/std/room/inherit/topography/
skylib_fluffos_v3/mudlib/std/room/topography/area/
skylib_fluffos_v3/mudlib/std/room/topography/iroom/
skylib_fluffos_v3/mudlib/std/room/topography/milestone/
skylib_fluffos_v3/mudlib/std/shadows/curses/
skylib_fluffos_v3/mudlib/std/shadows/disease/
skylib_fluffos_v3/mudlib/std/shadows/fighting/
skylib_fluffos_v3/mudlib/std/shadows/healing/
skylib_fluffos_v3/mudlib/std/shadows/magic/
skylib_fluffos_v3/mudlib/std/shadows/poison/
skylib_fluffos_v3/mudlib/std/shadows/room/
skylib_fluffos_v3/mudlib/std/shops/controllers/
skylib_fluffos_v3/mudlib/std/shops/objs/
skylib_fluffos_v3/mudlib/std/shops/player_shop/
skylib_fluffos_v3/mudlib/std/socket/
skylib_fluffos_v3/mudlib/std/soul/d/
skylib_fluffos_v3/mudlib/std/soul/e/
skylib_fluffos_v3/mudlib/std/soul/i/
skylib_fluffos_v3/mudlib/std/soul/j/
skylib_fluffos_v3/mudlib/std/soul/k/
skylib_fluffos_v3/mudlib/std/soul/l/
skylib_fluffos_v3/mudlib/std/soul/n/
skylib_fluffos_v3/mudlib/std/soul/o/
skylib_fluffos_v3/mudlib/std/soul/q/
skylib_fluffos_v3/mudlib/std/soul/r/
skylib_fluffos_v3/mudlib/std/soul/u/
skylib_fluffos_v3/mudlib/std/soul/v/
skylib_fluffos_v3/mudlib/std/soul/y/
skylib_fluffos_v3/mudlib/std/soul/z/
skylib_fluffos_v3/mudlib/std/stationery/
skylib_fluffos_v3/mudlib/w/
skylib_fluffos_v3/mudlib/w/default/
skylib_fluffos_v3/mudlib/w/default/armour/
skylib_fluffos_v3/mudlib/w/default/clothes/
skylib_fluffos_v3/mudlib/w/default/item/
skylib_fluffos_v3/mudlib/w/default/npc/
skylib_fluffos_v3/mudlib/w/default/room/
skylib_fluffos_v3/mudlib/w/default/weapon/
skylib_fluffos_v3/mudlib/www/
skylib_fluffos_v3/mudlib/www/java/
skylib_fluffos_v3/mudlib/www/secure/
skylib_fluffos_v3/mudlib/www/secure/lpc/advanced/
skylib_fluffos_v3/mudlib/www/secure/lpc/intermediate/
skylib_fluffos_v3/win32/
/**
 * This class controls the entire command queue for all player
 * objects.  Whenever a player tries to execute a command,
 * it gets placed in a queue here and eventually (during the
 * player's heart_beat()), the command will (hopefully) be executed.
 *
 * <p>Since this class is a nexus of control for player commands, it
 * is also the natural place for a number of other utilities and
 * functions which also affect the execution of all commands.
 * Among these are things like drunk_check(), do_soul(), etc.
 *
 * @see /global/player/new_parse->add_command()
 * @see /global/player->heart_beat()
 * @see query_passed_out_message()
 *
 * @author Pinkfish
 * @changed 3 November 1997 -- Sin
 *      Documented the bejeesus out of this thing.
 * @changed 4 Novemebr 1997 - Pinkfish
 *      Updated the documentation and changed the interrupt system slightly.
 * @changed 22 Feburary 1998 - Pinkfish
 *      Fixed up the problems with the queueing system.
 * @changed 28 Feburary 2002 - Sandoz
 *      Fixed up a problem in _process_input with printf() erroring
 *      on error messages with % in them.
 */

#include <player.h>

inherit "/global/player/alias";
inherit "/global/player/nickname";

nosave int time_left;
nosave int doing_it;
nosave int last_command;
nosave int bypass_queue;
nosave int flush_call_id;
nosave string *queued_commands;
nosave string in_command;
nosave mixed interrupt;
nosave private function cmd = 0;

/** @ignore  */
void create() {
    time_left = ROUND_TIME;
    last_command = time();
    queued_commands = ({ });
} /* create() */

/**
 * To make the next single command be executed directly rather
 * than being placed in the command queue, call this function.
 */
void bypass_queue() { bypass_queue = 1; }

/**
 * Ensure that the player has no more time for executing commands.
 * This will force the next command to be queued.
 */
void no_time_left() {
    time_left = -ROUND_TIME;
} /* no_time_left() */

/**
 * This is a setup function that is called by the player object.
 * It is used to register the lower_check() and drunk_check()
 * functions.  Plus it initializes the alias object, the
 * nickname object, and the history object.
 */
protected int drunk_check( string str );

/** @ignore yes */
void soul_commands() {
    alias_commands();
    nickname_commands();
    history_commands();
} /* soul_commands() */

/**
 * You can use this function to see if there are any commands
 * queued for this player.
 * @return the number of queued commands
 */
int query_queued_commands() {
    return sizeof(queued_commands);
} /* query_queued_commands() */

/**
 * The amount of time units left.  A time unit is 1/40th of a second.
 */
int query_time_left() { return time_left; }

/**
 * Change the amount of time a player has left.  You call this after a command
 * has been executed to make it take more time.
 * @param i the amount of time units to change by
 * @return the amount of time left
 */
int adjust_time_left( int i ) {
    return time_left += i;
} /* adjust_time_left() */

/** @ignore yes */
private void do_flush( int first ) {
    int i;
    string str;

    if( time_left < 1 || !sizeof( queued_commands ) ||
        ( TO->queue_commands(queued_commands[0]) && !TO->query_creator() ) )
        return;

    if( !first ) {
        str = queued_commands[0];
        queued_commands = queued_commands[1..];

        doing_it = 1;
        catch( command(str) );
        doing_it = 0;

        // The end!
        if( !sizeof(queued_commands) ) {
            queued_commands = ({ });
            doing_alias = ([ ]);
        }

        return;
    }

    for( i = 0; i < 2 && i < sizeof(queued_commands); i++ )
        flush_call_id = call_out( (: do_flush(0) :), 1 );

    flush_call_id = call_out( (: do_flush(1) :), 2 );

} /* do_flush() */

/** @ignore yes */
private void call_interrupt( int time_left, object interupter ) {
    mixed stuff;

    stuff = interrupt;
    interrupt = 0;

    // The previous object is the person interupting us.
    if( pointerp(stuff) )
        catch( call_other( stuff[1], stuff[0], time_left, stuff[2], TO,
                           interupter, in_command ) );
    else if( functionp(stuff) )
        catch( evaluate( stuff, time_left, TO, interupter, in_command ) );

} /* call_interrupt() */

/**
 * This method flushes all the queued commands.  It increments the time by the
 * ROUND_TIME define and checks to see if any of the commands now need to be
 * executed.  This should be called each heart beat..
 * @see /global/player->heart_beat()
 */
protected void flush_queue() {
    time_left += ROUND_TIME;

    if( time_left > ROUND_TIME )
        time_left = ROUND_TIME;

    remove_call_out( flush_call_id );
    do_flush(1);

    if( !sizeof(queued_commands) ) {
        // Check to see if an interupt was set up.
        if( interrupt && time_left > 0 )
            call_interrupt( 0, TO );

        in_alias_command = 0;
        doing_alias = ([ ]);

        if( !sizeof(queued_commands) )
            return;

        doing_alias = ([ ]);
        in_alias_command = 0;
    }

} /* flush_queue() */

/**
 * Sets the function to be executed if the command is interrupted.
 * It is also executed if the command finished.  If it is interrupted
 * the first argument to the called function will be the amount of time
 * it had left to complete.  If it complets successfuly, this
 * argument will be 0.  If the first argument is a function pointer,
 * this will be used instead.<p>
 *
 * Eg: set_interupt_command("frog", TO);<p>
 * void frog(int time_left, mixed arg) { <p>
 * ... <p>
 * }
 *
 * @param func the function to call back
 * @param ob the object to call the function on
 * @param arg the argument to pass to the function
 * @example
 * ...
 * void frog(int time_left, mixed arg);
 * ...
 * set_interupt_commant( (: frog :) );
 * ...
 * void frog(int time_left, mixed arg) {
 *    ...
 * } /\* frog() *\/
 */
void set_interupt_command(mixed func, mixed ob, mixed arg) {
    if( !functionp(func) ) {
        interrupt = ({ func, ob, arg });
        if( !stringp( func ) )
            interrupt = 0;
    } else {
        interrupt = func;
    }
} /* set_interupt_command() */

/**
 * This method returns the current value associated with tine interupt
 * command.
 * @return the current interupt command data
 */
mixed query_interupt_command() {
    return interrupt;
} /* query_interupt_command_func() */

/**
 * This one only takes a function pointer as an input.
 * @param func the function pointer to call back with
 */
void set_interrupt_command( function func ) {
    set_interupt_command( func, 0, 0 );
} /* set_interrupt_command() */

/**
 * This is called by the stop command.  It sets the entire queue back to
 * empty.  It calls the interrupt functions and stuff if they need to be
 * called.
 */
void remove_queue() {
    queued_commands = ({ });

    if( interrupt && time_left < 0 )
        call_interrupt( -time_left, TO );

    tell_object( TO, "Removed queue.\n");

    if( lordp(TO) ) {
        // Just in case something really bad happens...  Let lords fix it.
        time_left = 0;
    } else {
        // Make sure they cannot do anything for a heartbeat.
        time_left = -DEFAULT_TIME;
    }
} /* remove_queue() */

/**
 * This method interupts the current command.
 * @param interupter the person interupting the command
 */
void interupt_command( object interupter ) {
    if( interupter )
        call_interrupt( -time_left, interupter );
} /* interupt_command() */

/**
 * Use this function to set a function that is called with the players input
 * before the command handlers get to it, return 1 from the function if the
 * input needs no further parsing (ie the command is handled)
 * @param func function in the players environment to call.
 */

void command_override( function func ) {
    if( !functionp(func) )
        error("command_override needs a function!");
    cmd = func;
} /* command_override() */

/**
 * This poorly named function was originally used to affect the
 * player's behavior when they are drunk, and to prevent any
 * player from doing anything in the event that they are passed
 * out.  Now the function also is responsible for adding commands
 * to the player's command queue, for implementing the 'stop'
 * and 'restart' commands, and for ensuring that the player can quit
 * the game, even when queueing.
 *
 * <p>To see if a player is passed out, it checks the
 * "passed out" property.  If that property is nonzero, then
 * the player will be prevented from doing the command unless
 * that player is also a creator.  By default, it will print
 * a message that says: "You are unconscious.  You can't do
 * anything.\n".  If the function query_passed_out_message() is
 * defined on the player object (usually by a shadow), and
 * returns a string, then that string is printed instead.
 *
 * @return 0 if nothing was done, 1 if drunk_check() blocked
 * the command.
 * @param str the command being executed
 *
 * @see /global/new_parse->add_command()
 */
protected int drunk_check( string str ) {
    string *rabbit, *green, mess, comm, arg;

    if( cmd ) {
        object owner;

        owner = function_owner(cmd);

        if( owner && owner == ENV(TP) ) {
            int ret;

            if( ret = evaluate( cmd, str ) )
                return ret;
        } else {
            cmd = 0;
        }
    }

    if( sizeof( rabbit = explode( str, " ") ) == 1 )
        if( rabbit[0] == ",")
            return 0;

    if( in_command == str ) {
        in_command = 0;
        sscanf( str, "%s %*s", str );
        if( is_doing_alias(str) )
            notify_fail("Recursive aliases. Bad "+({"thing", "boy",
                "girl"})[TO->query_gender()]+".\n");
        return 0;
    }

    if( bypass_queue ) {
        bypass_queue = 0;
        return 0;
    }

    last_command = time();

    if( TO->query_property(PASSED_OUT) || !interactive(TO) ) {
        if( str == "quit")
            return 0;

        if( !stringp( mess = TO->query_passed_out_message() ) )
            mess = "You are unconscious.  You can't do anything.\n";

        write( mess );

        if( !TO->query_creator() )
            return 1;

        write("On the other hand, you're a creator...\n");
    }

    if( str == "stop" || str == "restart") {
        remove_queue();
        return 0;
    }

    if( stringp(str) && str[0..4] == "stop ")
        return 0;

    /*
     * If: there's no time left
     * or: commands are to be queued (e.g. spell casting) and this is a player
     * or: if we have queueing commands and we are not currently executing
     *     a command off the stack
     * or: we are trying to do a flush
     * then queue the command.
     */
    if( time_left < 0 || ( TO->queue_commands(str) && !TO->query_creator() ) ||
        ( !doing_it && ( sizeof( queued_commands ) ||
        find_call_out( flush_call_id ) != -1 ) ) ) {
        // Only print commands which are not in upper case.
        rabbit = explode( str, " ");
        if( rabbit[0] != upper_case( rabbit[0] ) )
            write("Queued command: "+str+"\n");

        if( str == "quit")
            write("If you are trying to quit and it is queueing things, use "
                "\"stop\" to stop your commands, or \"restart\" to restart "
                "your heartbeat.\n");
        // The command should always go on the end because the aliases
        // in the queue are expanded elsewhere...
        queued_commands += ({ str });
        return 1;
    }

    if( interrupt )
        call_interrupt( 0, TO );

    interrupt = 0;
    in_command = str;

    // Get the args and stuff to run the alias.
    if( sscanf( str, "%s %s", comm, arg ) != 2 ) {
        comm = str;
        arg = "";
    }

    if( rabbit = run_alias( comm, arg ) ) {
        // Set us as running the alias.
        set_doing_alias(comm);

        green = queued_commands;
        queued_commands = ({ });

        foreach( comm in rabbit )
            catch( command(comm) );

        queued_commands += green;

    } else if( sizeof(str) > 1024 ) {
        write("Command too long.\n");
    } else {
        if( str[0..8] != "END_ALIAS")
            time_left -= DEFAULT_TIME;
        command(str);
    }

    if( interrupt && time_left >= 0 )
        call_interrupt( 0, TO );

    return 1;

} /* drunk_check() */

/** @ignore yes */
protected string _process_input( string str ) {
    object ob;

    if( str == "" )
        return 0;

    ob = TP;
    set_this_player(TO);
    _notify_fail(0);

    if( !sizeof( explode( str, " " ) - ({"", 0 }) ) || str[0] == ',' ) {
        efun::tell_object( TO, "What?\n");
        set_this_player(ob);
        return 0;
    }

    if( !drunk_check(str) && !TO->exit_command(str) && !TO->cmdAll(str) &&
        !TO->new_parser(str) && !TO->lower_check(str) ) {
        efun::tell_object( TO, query_notify_fail() || "What?\n");
        set_this_player(ob);
        return 0;
    }

    set_this_player(ob);
    return "bing";

} /* _process_input() */

/**
 * This is the command called by the driver on a player object every
 * time a command is executed.  It expands the history comands.
 * @param str the string to expand
 * @return the expanded history string
 */
protected string process_input( string str ) {
    reset_eval_cost();

    if( str[0] == '.' )
        str = expand_history(str[1..]);
    else if( str[0] == '^' )
        str = substitute_history(str[1..]);

    TO->add_history(str);
    _process_input(str);

    return 0;

} /* process_input() */

/**
 * This function will get called when all other commands and actions
 * have refused to do anything for this input from the user.  This
 * function adds some extra time for the user, and then returns.
 * @param str the user's input
 * @return 1 if the user's input is "stop", otherwise 0.
 */
int lower_check( string str ) {
    query_time_left();
    return str == "stop";
} /* lower_check() */