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


#include <lib.h>
#include <daemons.h>
#include "include/command.h"

#define OLD_STYLE_PLURALS 1

int Paused = 0;
private static int Forced = 0;
private static int StillTrying = 0;
private static int ParseRecurse = 0;
private static string CommandFail;
private static string *SearchPath;
private static int last_cmd_time = 0;
private static int cmd_count = 1;
private string *localcmds = ({});
private string parsed_command = "";
private static string *QueuedCommands = ({});
static string current_command = "";
static string original_command = "";
static int Charmode = 0;
static string Charbuffer = "";

int direct_force_liv_str(){ return 1; }
int direct_force_liv_to_str(){ return 1; }


/*  ***************  /lib/command.c driver applies  ***************  */

static void create(){
    SetCommandFail(0);
    SearchPath = ({ DIR_PLAYER_CMDS, DIR_SECURE_PLAYER_CMDS, DIR_CLAN_CMDS,
            DIR_COMMON_CMDS, DIR_SECURE_COMMON_CMDS });
}

static string process_input(string args){ 
    string verb, real_verb, tmpalias, orig;
    object env = environment(this_object());
    string *talks = ({ "emote", "tell", "reply", "say", "whisper",
            "yell", "shout", "speak" });
    string *filecmds = ({ "ced", "clone", "goto", "rehash", "reset",
            "showtree", "bk", "cat", "cp", "diff", "ed", "grep", "head", "indent",
            "longcat", "more", "mv", "rm", "sed", "showfuns", "source",
            "tail", "update", "cd", "ls", "mkdir", "rmdir" });
    string *specialcmds = ({ "modify", "mudconfig", "describe" });
    string *exempts = talks + filecmds + specialcmds;
    exempts += this_object()->GetChannels();
    exempts += SOUL_D->GetEmotes();

    orig = args;

    localcmds = ({});
    filter(commands(), (: localcmds += ({ $1[0] }) :));

    if(sizeof(args)){
        string *tmpargs = explode(args, " ");
        if(sizeof(tmpargs)) verb = tmpargs[0];
        else verb = "";
    }
    if(verb && tmpalias = this_object()->GetAlias(verb)){
        real_verb = explode(tmpalias, " ")[0];
    }
    if(verb && tmpalias = this_object()->GetXverb(verb[0..0])){
        real_verb = explode(tmpalias, " ")[0];
    }
    if(!real_verb) real_verb = verb;
    if(Paused && (member_array(real_verb, exempts) == -1)){
        this_object()->eventPrint("You are paused.");
        return "";
    }
    if(!archp(this_object()) && MAX_COMMANDS_PER_SECOND){
        if(last_cmd_time == time()) cmd_count++;
        else {
            last_cmd_time = time();
            cmd_count = 1;
        }
        if(cmd_count > MAX_COMMANDS_PER_SECOND){
            this_object()->eventPrint("You have exceeded the " +
                    MAX_COMMANDS_PER_SECOND + " commands per second limit.");
            return "";
        }
    }
    if(this_object()->GetSleeping() > 0){
        if(verb != "wake"){
            this_object()->eventPrint("You are asleep.");
            return "";
        }
    }
    if(OLD_STYLE_PLURALS && args && (member_array(real_verb, exempts) == -1 ||
                (member_array(verb, exempts) != -1 && !strsrch(trim(args),"to ")))){
        int numba, i, tmp_num;
        string tmp_ret;
        string *line = explode(args," ");
        for(i = 1; i < sizeof(line); i++){
            string element;
            if(!line[i]) error("String handling error in old style plural parser.");
            element = line[i];
            exempts = sort_array(exempts, 1);
            if(sscanf(element,"%d.%d",numba,tmp_num) != 2 &&
                    sscanf(element,"%d.%s",numba,tmp_ret) == 2 &&
                    (member_array(real_verb, exempts) == -1)){
                args = replace_string(args, numba + ".", 
                        numba + ordinal(numba) + " ");
                continue;
            }
            if(numba = atoi(element)){
                int j;
                object o1;
                string e1, e2, tmp_thing = "";
                e1 = numba+ordinal(numba);
                j = member_array(element, line);
                while(j > 0){
                    string old_tmp = tmp_thing;
                    j--;
                    e2 = line[j];
                    if(sizeof(tmp_thing)) tmp_thing = e2 + " " + tmp_thing;
                    else tmp_thing = e2;
                    if(member_array(tmp_thing, exempts) != -1) break;
                    o1 = present(tmp_thing);
                    if(!o1){
                        o1 = present(old_tmp);
                        if(o1){
                            tmp_ret = e1 + " " + old_tmp;
                            args=replace_string(args,old_tmp+" "+numba,tmp_ret);
                        }
                    }
                }
            }//end single number check
        }
    }
    parsed_command = args;
    if(member_array(verb, localcmds) != -1){
        current_command = orig;
    }
    else {
        current_command = parsed_command;
        parsed_command = "";
    }
    return current_command;
}

/*  ***************  /lib/command.c command lfuns  ***************  */

static int cmdAll(string args){
    object old_agent, env;
    mixed err;
    string verb, file;

    if(grepp(parsed_command," ")){
        sscanf(parsed_command,"%s %s", verb, args);
        parsed_command = "";
    }

    if(!verb) verb = query_verb();

    if(!this_object()->GetCharmode()){
        if(!args) this_object()->Push(verb);
        else this_object()->Push(verb+" "+args);
    }
    else {
        this_object()->Push(this_object()->GetTempbuffer());
    }

    old_agent = this_agent(this_object());

    env = environment();
    if(BARE_EXITS && env){
        localcmds = ({});
        filter(commands(), (: localcmds += ({ $1[0] }) :));
        if(member_array(verb,CMD_D->GetCommands()) == -1 &&
                member_array(verb,keys(VERBS_D->GetVerbs())) == -1 &&
                member_array(verb,localcmds) == -1 ){
            string dir;
            if(args) dir = verb + " " + args;
            else dir = verb;
            if(member_array(dir, (env->GetExits() || ({}))) != -1) 
                verb = "go "+verb;
            if(member_array(dir, (env->GetEnters() || ({}))) != -1) 
                verb = "enter "+verb;
        }
    }

    if(COMMAND_MATCHING && sizeof(match_command(verb))){
        verb = match_command(verb);
    }

    if(query_custom_command(verb) && query_custom_command(verb) != "" && !creatorp(this_player()) ){
        this_player()->eventPrint("How clever of you. Or lucky. In any case, this command is unavailable to you.");
        return 1;
    }
    if( !(file = (query_custom_command(verb) )) || query_custom_command(verb) == ""){
        if( !(file = CMD_D->GetCommand(verb, GetSearchPath())) ){
            string cmd;
            int dbg;

            if( verb && args ) cmd = verb + " " + args;
            else if(verb) cmd = verb;
            else if(args) cmd = args;
            if( this_object()->GetProperty("parse debug") ) dbg = 1;
            else if( this_object()->GetProperty("debug") ) dbg = 1;
            else dbg = 0;
            if( (err = parse_sentence(cmd, dbg)) == 1 ){
                this_agent(old_agent || 1);
                return 1;
            }
            if( err ){
                if( err == -1 ){
                    if( !(err = VERBS_D->GetErrorMessage(verb)) &&
                            !(err = SOUL_D->GetErrorMessage(verb)) ){
                        err = "Such a command exists, but no default "
                            "syntax is known.";
                    }
                }
                if( intp(err) )  /* MudOS bug */ err = "What?";
                SetCommandFail(err);
            }
            message("error", GetCommandFail(), this_object());
            this_agent(old_agent || 1);
            return 1;
        }
    }

    if( (err = call_other(file, "cmd", args)) != 1 ){
        string cmd;

        if( err ) SetCommandFail(err);
        if( !args || args == "" ) cmd = verb;
        else cmd = verb + " " + args;
        if( (err = parse_sentence(cmd)) == 1 ){
            this_agent(old_agent || 1);
            return 1;
        }
        if( !err ) err = GetCommandFail();
        message("error", err, this_object());
        this_agent(old_agent || 1);
        return 1;
    }
    this_agent(old_agent || 1);
    return 1;
}

int cmdDebugAll(string args){
    object old_agent;
    mixed err;
    string verb, file;

    old_agent = this_agent(this_object());
    verb = query_verb();
    if( !(file = CMD_D->GetCommand(verb, GetSearchPath())) ){
        string cmd;

        if( args ) cmd = verb + " " + args;
        else cmd = verb;
        if( (err = parse_sentence(cmd, 3)) == 1 ){
            this_agent(old_agent || 1);
            return 1;
        }
        if( err ) SetCommandFail(err);
        message("error", GetCommandFail(), this_object());
        this_agent(old_agent || 1);
        return 1;
    }
    if( (err = call_other(file, "cmd", args)) != 1 ){
        string cmd;

        if( err ) SetCommandFail(err);
        if( !args || args == "" ) cmd = verb;
        else cmd = verb + " " + args;
        if( (err = parse_sentence(cmd, 3)) == 1 ){
            this_agent(old_agent || 1);
            return 1;
        }
        if( !err ) err = GetCommandFail();
        message("error", err, this_object());
        this_agent(old_agent || 1);
        return 1;
    }
    this_agent(old_agent || 1);
    return 1;
}

/*  ***************  /lib/command.c lfuns  ***************  */

int Setup(){
    enable_commands();
    add_action( (: cmdAll :), "", 1);
}

int eventForce(string cmd){
    string err;
    int res;
#if 0
    if(this_player() && interactive(this_object()) 
            && this_player() != this_object()){
        string forcer = this_player()->GetKeyName();
        string forcee = this_object()->GetKeyName();
        log_file("adm/force", 
                timestamp()+" "+forcer+" forced "+forcee+" to "+cmd+"\n");
    }
#endif
    if(!cmd) return 0;

    cmd = process_input(cmd);
    if(!cmd) return 0;
    Forced = 1;
    err = catch(res = command(cmd));
    Forced = 0;
    if(err){
        error(err);
    }
    return res;
}

int eventForceQueuedCommand(string cmd){
    tell_object(this_object(),"%^RED%^Executing queued command: %^RESET%^"+cmd);
    eventForce(cmd);
}

int eventExecuteQueuedCommands(){
    int i = 0;
    foreach(string tmp in QueuedCommands){
        i++;
        //tmp = process_input(tmp);
        call_out("eventForceQueuedCommand", i, tmp);
        QueuedCommands -= ({ tmp });
    }
}

int eventQueueCommand(string line){
    if(!line || !sizeof(line) || !stringp(line)) return 0;
    if(!this_player()) return 0;
    if(interactive(this_object())){
        if(this_player() && this_player() != this_object()) return 0;
    }
    if(line != "") QueuedCommands += ({ line });
    return 1;
}

int DoneTrying(){
    return StillTrying = 0;
}

//Here we determine if the string corresponds unambiguously
//to a limb possessed by the command issuer.
int LimbCertain(string str){
    object env = environment(this_player());
    if(!env) env = this_player();
    if(!str){
        return 0;
    }
    foreach(mixed envs in ({ env, this_player() })){
        if(present(str, env)){
            return 0;
        }
    }
    if(member_array(str, this_player()->GetLimbs()) != -1){
        return 1;
    }
    return 0;
}

varargs int eventRetryCommand(string lastcmd, int errtype, mixed args){
    string virb, wrd, prep, rest,ret;
    string *tmp_arr = ({});
    string *prep_arr = MASTER_D->parse_command_prepos_list();
    object tmpob;
    mixed err;
    int i;
    string tmpret, act, direct, indirect, odirect, oindirect;
    mixed direct2, indirect2;

    if(previous_object() != master()) return 0;

    if(StillTrying){
        StillTrying = 0;
        original_command = 0;
        return 1;
    }

    StillTrying = 1;

    if(!original_command || !sizeof(original_command)) original_command = lastcmd;

    tmpret = (lastcmd || "");
    foreach(string foo in prep_arr){
        if(grepp(tmpret," "+foo+" ")){
            tmpret = replace_string(tmpret," "+foo+" "," PREPO ");
        }
    }
    tmpret = implode(explode(tmpret," ")," ");
    i = sscanf(tmpret,"%s %s PREPO %s",act, direct, indirect);
    if(i != 3) i = sscanf(tmpret,"%s %s PREPO PREPO %s",act, direct, indirect);
    if(i != 3) i = sscanf(tmpret,"%s %s %s",act, direct, indirect);
    if(i != 3) i = sscanf(tmpret,"%s %s",act, direct);
    odirect = direct;
    oindirect = indirect;

    //read is a special case. takes a str as first arh sometimes.
    if(act == "read" && !grepp(tmpret, " in a ")){
        tmpret = replace_string(lastcmd, " in ", " in a ");
    }
    else if(i > 1 ){
        object ob1, ob2;
        string tmpstr, s1, s2, article1, article2;
        if(StillTrying){
            tmpstr = remove_article(direct);
            if(args && sizeof(args) && answers_to(tmpstr, args[0]) &&
                    present(args[0]))
                ob1 = args[0];
            else ob1 = to_object(tmpstr, this_object());
        }
        if(StillTrying && indirect){
            tmpstr = remove_article(indirect);
            if(args && sizeof(args) && answers_to(tmpstr, args[0]) &&
                    present(args[0]))
                ob2 = args[0];
            else ob2 = to_object(tmpstr, this_object());
        }
        if(ob1) direct = ob1->GetUniqueId();
        else direct = remove_article(direct);
        if(ob2) indirect = ob2->GetUniqueId();
        else indirect = remove_article(indirect);
        if(!ob1 && direct && grepp(direct," ")){
            if(sscanf(direct,"%s %s",s1, s2) == 2 && 
                    !ordinalp(s1,1)){
                direct2 = "a "+direct;
            }
        }
        else if(!ob1 && direct){
            if(first(direct,2) == "a " || first(direct,3) == "an "){
                direct2 = direct;
            }
            else direct2 = "a "+direct;
        }
        if(!ob2 && indirect && grepp(indirect," ")){
            if(sscanf(indirect,"%s %s",s1, s2) == 2 && 
                    !ordinalp(s1,1)){
                if(!LimbCertain(indirect)) indirect2 = "a "+indirect;
            }
        }
        else if(!ob2 && indirect){
            if(first(indirect,2) == "a " || first(indirect,3) == "an "){
                if(!LimbCertain(indirect)) indirect2 = indirect;
            }
            else if(!LimbCertain(indirect)) indirect2 = "a "+indirect;
        }
        if(direct && !direct2) direct2 = direct;
        if(indirect && !indirect2) indirect2 = indirect;
        tmpret = replace_string(lastcmd, odirect, direct2);
        if(indirect2 && oindirect) tmpret = replace_string(tmpret, oindirect, indirect2); 
    }

    ret = tmpret;
    err = parse_sentence(ret);
    StillTrying = 0;
    original_command = 0;
    if( !stringp(err) && err > -1 ){
        return 1;
    }
    write("It seems you'll have to be more specific.");
    return 1;
}


/*  **********  /lib/command.c data manipulation functions  ********** */

string *AddSearchPath(mixed val){
    if(stringp(val)){
        if(!strsrch(val,"/secure/cmds/admins") || !strsrch(val,"/cmds/admins")){
            if(!master()->valid_apply(({ "SECURE", "ASSIST", "LIB_CONNECT" })) ){
                tell_creators("Security violation in progress: "+identify(previous_object(-1)) + ", "+get_stack());
                error("Illegal attempt to modify path data: "+identify(previous_object(-1)) + ", "+get_stack());

            }
        }
        val = ({ val });
    }

    else if(!pointerp(val)) error("Bad argument 1 to AddSearchPath()\n");
    return (SearchPath = distinct_array(SearchPath + val));
}

string *RemoveSearchPath(mixed val){
    if(stringp(val)) val = ({ val });
    else if(!pointerp(val)) error("Bad argument 1 to RemoveSearchPath()\n");
    return (SearchPath -= val);
}

string *GetSearchPath(){ return SearchPath; }

int GetForced(){ return Forced; }

int GetClient(){ return 0; }

string GetCurrentCommand(){
    if(!this_player()) return "";
    if(this_player() != this_object()) return "";
    return current_command;
}

int SetPlayerPaused(int i){
    if( base_name(previous_object()) != LIB_CONNECT &&
            (!this_player() || !archp(this_player())) ){
        error("Illegal attempt to pause a player: "+get_stack()+" "+identify(previous_object(-1)));
        log_file("adm/pause",timestamp()+" Illegal attempt to access SetPlayerPaused on "+identify(this_object())+" by "+identify(previous_object(-1))+"\n");
    }
    Paused = i;
    return Paused;
}

int GetPlayerPaused(){
    return Paused;
}

string SetCommandFail(string str){ 
    if( !str || str == "" ){
        if(!creatorp(this_object())) CommandFail = "Try \"help commands\" for a list of some commands.";
        if(creatorp(this_object())) CommandFail = "Try \"help creator commands\" for a list of some creator commands.";
        return CommandFail;
    }
    else return (CommandFail = str);
}

string GetCommandFail(){ return CommandFail; }