ds2.9a12/bin/
ds2.9a12/extra/
ds2.9a12/extra/crat/
ds2.9a12/extra/creremote/
ds2.9a12/extra/mingw/
ds2.9a12/extra/wolfpaw/
ds2.9a12/fluffos-2.14-ds13/
ds2.9a12/fluffos-2.14-ds13/Win32/
ds2.9a12/fluffos-2.14-ds13/compat/
ds2.9a12/fluffos-2.14-ds13/compat/simuls/
ds2.9a12/fluffos-2.14-ds13/include/
ds2.9a12/fluffos-2.14-ds13/testsuite/
ds2.9a12/fluffos-2.14-ds13/testsuite/clone/
ds2.9a12/fluffos-2.14-ds13/testsuite/command/
ds2.9a12/fluffos-2.14-ds13/testsuite/data/
ds2.9a12/fluffos-2.14-ds13/testsuite/etc/
ds2.9a12/fluffos-2.14-ds13/testsuite/include/
ds2.9a12/fluffos-2.14-ds13/testsuite/inherit/
ds2.9a12/fluffos-2.14-ds13/testsuite/inherit/master/
ds2.9a12/fluffos-2.14-ds13/testsuite/log/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/compiler/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/efuns/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/operators/
ds2.9a12/fluffos-2.14-ds13/testsuite/u/
ds2.9a12/lib/cmds/admins/
ds2.9a12/lib/cmds/common/
ds2.9a12/lib/cmds/creators/include/
ds2.9a12/lib/daemon/services/
ds2.9a12/lib/daemon/tmp/
ds2.9a12/lib/doc/
ds2.9a12/lib/doc/bguide/
ds2.9a12/lib/doc/efun/all/
ds2.9a12/lib/doc/efun/arrays/
ds2.9a12/lib/doc/efun/buffers/
ds2.9a12/lib/doc/efun/compile/
ds2.9a12/lib/doc/efun/floats/
ds2.9a12/lib/doc/efun/functions/
ds2.9a12/lib/doc/efun/general/
ds2.9a12/lib/doc/efun/mixed/
ds2.9a12/lib/doc/efun/numbers/
ds2.9a12/lib/doc/efun/parsing/
ds2.9a12/lib/doc/hbook/
ds2.9a12/lib/doc/help/classes/
ds2.9a12/lib/doc/help/races/
ds2.9a12/lib/doc/lfun/
ds2.9a12/lib/doc/lfun/all/
ds2.9a12/lib/doc/lfun/lib/abilities/
ds2.9a12/lib/doc/lfun/lib/armor/
ds2.9a12/lib/doc/lfun/lib/bank/
ds2.9a12/lib/doc/lfun/lib/bot/
ds2.9a12/lib/doc/lfun/lib/clay/
ds2.9a12/lib/doc/lfun/lib/clean/
ds2.9a12/lib/doc/lfun/lib/clerk/
ds2.9a12/lib/doc/lfun/lib/client/
ds2.9a12/lib/doc/lfun/lib/combat/
ds2.9a12/lib/doc/lfun/lib/connect/
ds2.9a12/lib/doc/lfun/lib/container/
ds2.9a12/lib/doc/lfun/lib/corpse/
ds2.9a12/lib/doc/lfun/lib/creator/
ds2.9a12/lib/doc/lfun/lib/daemon/
ds2.9a12/lib/doc/lfun/lib/damage/
ds2.9a12/lib/doc/lfun/lib/deterioration/
ds2.9a12/lib/doc/lfun/lib/donate/
ds2.9a12/lib/doc/lfun/lib/door/
ds2.9a12/lib/doc/lfun/lib/equip/
ds2.9a12/lib/doc/lfun/lib/file/
ds2.9a12/lib/doc/lfun/lib/fish/
ds2.9a12/lib/doc/lfun/lib/fishing/
ds2.9a12/lib/doc/lfun/lib/flashlight/
ds2.9a12/lib/doc/lfun/lib/follow/
ds2.9a12/lib/doc/lfun/lib/ftp_client/
ds2.9a12/lib/doc/lfun/lib/ftp_data_connection/
ds2.9a12/lib/doc/lfun/lib/fuel/
ds2.9a12/lib/doc/lfun/lib/furnace/
ds2.9a12/lib/doc/lfun/lib/genetics/
ds2.9a12/lib/doc/lfun/lib/holder/
ds2.9a12/lib/doc/lfun/lib/id/
ds2.9a12/lib/doc/lfun/lib/interactive/
ds2.9a12/lib/doc/lfun/lib/lamp/
ds2.9a12/lib/doc/lfun/lib/leader/
ds2.9a12/lib/doc/lfun/lib/light/
ds2.9a12/lib/doc/lfun/lib/limb/
ds2.9a12/lib/doc/lfun/lib/living/
ds2.9a12/lib/doc/lfun/lib/load/
ds2.9a12/lib/doc/lfun/lib/look/
ds2.9a12/lib/doc/lfun/lib/manipulate/
ds2.9a12/lib/doc/lfun/lib/meal/
ds2.9a12/lib/doc/lfun/lib/messages/
ds2.9a12/lib/doc/lfun/lib/player/
ds2.9a12/lib/doc/lfun/lib/poison/
ds2.9a12/lib/doc/lfun/lib/position/
ds2.9a12/lib/doc/lfun/lib/post_office/
ds2.9a12/lib/doc/lfun/lib/potion/
ds2.9a12/lib/doc/lfun/lib/room/
ds2.9a12/lib/doc/lfun/lib/server/
ds2.9a12/lib/doc/lfun/lib/spell/
ds2.9a12/lib/doc/lfun/lib/torch/
ds2.9a12/lib/doc/lfun/lib/vendor/
ds2.9a12/lib/doc/lfun/lib/virt_sky/
ds2.9a12/lib/doc/lfun/lib/weapon/
ds2.9a12/lib/doc/lfun/lib/worn_storage/
ds2.9a12/lib/doc/lpc/basic/
ds2.9a12/lib/doc/lpc/concepts/
ds2.9a12/lib/doc/lpc/constructs/
ds2.9a12/lib/doc/lpc/etc/
ds2.9a12/lib/doc/lpc/intermediate/
ds2.9a12/lib/doc/lpc/types/
ds2.9a12/lib/doc/misc/
ds2.9a12/lib/doc/old/
ds2.9a12/lib/domains/
ds2.9a12/lib/domains/Praxis/adm/
ds2.9a12/lib/domains/Praxis/attic/
ds2.9a12/lib/domains/Praxis/cemetery/mon/
ds2.9a12/lib/domains/Praxis/data/
ds2.9a12/lib/domains/Praxis/death/
ds2.9a12/lib/domains/Praxis/mountains/
ds2.9a12/lib/domains/Praxis/obj/armour/
ds2.9a12/lib/domains/Praxis/obj/magic/
ds2.9a12/lib/domains/Praxis/obj/weapon/
ds2.9a12/lib/domains/Praxis/orc_valley/
ds2.9a12/lib/domains/Ylsrim/
ds2.9a12/lib/domains/Ylsrim/adm/
ds2.9a12/lib/domains/Ylsrim/armor/
ds2.9a12/lib/domains/Ylsrim/broken/
ds2.9a12/lib/domains/Ylsrim/fish/
ds2.9a12/lib/domains/Ylsrim/meal/
ds2.9a12/lib/domains/Ylsrim/npc/
ds2.9a12/lib/domains/Ylsrim/obj/
ds2.9a12/lib/domains/Ylsrim/virtual/
ds2.9a12/lib/domains/Ylsrim/weapon/
ds2.9a12/lib/domains/campus/adm/
ds2.9a12/lib/domains/campus/etc/
ds2.9a12/lib/domains/campus/meals/
ds2.9a12/lib/domains/campus/save/
ds2.9a12/lib/domains/campus/txt/ai/charles/
ds2.9a12/lib/domains/campus/txt/ai/charles/bak2/
ds2.9a12/lib/domains/campus/txt/ai/charles/bak2/bak1/
ds2.9a12/lib/domains/campus/txt/ai/charly/
ds2.9a12/lib/domains/campus/txt/ai/charly/bak/
ds2.9a12/lib/domains/campus/txt/jenny/
ds2.9a12/lib/domains/cave/doors/
ds2.9a12/lib/domains/cave/etc/
ds2.9a12/lib/domains/cave/meals/
ds2.9a12/lib/domains/cave/weap/
ds2.9a12/lib/domains/default/creator/
ds2.9a12/lib/domains/default/doors/
ds2.9a12/lib/domains/default/etc/
ds2.9a12/lib/domains/default/vehicles/
ds2.9a12/lib/domains/default/virtual/
ds2.9a12/lib/domains/default/weap/
ds2.9a12/lib/domains/town/txt/shame/
ds2.9a12/lib/domains/town/virtual/
ds2.9a12/lib/domains/town/virtual/bottom/
ds2.9a12/lib/domains/town/virtual/space/
ds2.9a12/lib/estates/
ds2.9a12/lib/ftp/
ds2.9a12/lib/lib/comp/
ds2.9a12/lib/lib/daemons/
ds2.9a12/lib/lib/daemons/include/
ds2.9a12/lib/lib/lvs/
ds2.9a12/lib/lib/user/
ds2.9a12/lib/lib/virtual/
ds2.9a12/lib/log/
ds2.9a12/lib/log/adm/
ds2.9a12/lib/log/archive/
ds2.9a12/lib/log/chan/
ds2.9a12/lib/log/errors/
ds2.9a12/lib/log/law/adm/
ds2.9a12/lib/log/law/email/
ds2.9a12/lib/log/law/names/
ds2.9a12/lib/log/law/sites-misc/
ds2.9a12/lib/log/law/sites-register/
ds2.9a12/lib/log/law/sites-tempban/
ds2.9a12/lib/log/law/sites-watch/
ds2.9a12/lib/log/open/
ds2.9a12/lib/log/reports/
ds2.9a12/lib/log/router/
ds2.9a12/lib/log/secure/
ds2.9a12/lib/log/watch/
ds2.9a12/lib/obj/book_source/
ds2.9a12/lib/obj/include/
ds2.9a12/lib/powers/prayers/
ds2.9a12/lib/powers/spells/
ds2.9a12/lib/realms/template/adm/
ds2.9a12/lib/realms/template/area/armor/
ds2.9a12/lib/realms/template/area/npc/
ds2.9a12/lib/realms/template/area/obj/
ds2.9a12/lib/realms/template/area/room/
ds2.9a12/lib/realms/template/area/weap/
ds2.9a12/lib/realms/template/bak/
ds2.9a12/lib/realms/template/cmds/
ds2.9a12/lib/save/kills/o/
ds2.9a12/lib/secure/cfg/classes/
ds2.9a12/lib/secure/cmds/builders/
ds2.9a12/lib/secure/cmds/creators/include/
ds2.9a12/lib/secure/cmds/players/
ds2.9a12/lib/secure/cmds/players/include/
ds2.9a12/lib/secure/daemon/imc2server/
ds2.9a12/lib/secure/daemon/include/
ds2.9a12/lib/secure/lib/
ds2.9a12/lib/secure/lib/include/
ds2.9a12/lib/secure/lib/net/include/
ds2.9a12/lib/secure/lib/std/
ds2.9a12/lib/secure/log/adm/
ds2.9a12/lib/secure/log/bak/
ds2.9a12/lib/secure/log/intermud/
ds2.9a12/lib/secure/log/network/
ds2.9a12/lib/secure/modules/
ds2.9a12/lib/secure/npc/
ds2.9a12/lib/secure/obj/include/
ds2.9a12/lib/secure/room/
ds2.9a12/lib/secure/save/
ds2.9a12/lib/secure/save/backup/
ds2.9a12/lib/secure/save/boards/
ds2.9a12/lib/secure/tmp/
ds2.9a12/lib/secure/upgrades/files/
ds2.9a12/lib/secure/verbs/creators/
ds2.9a12/lib/std/board/
ds2.9a12/lib/std/lib/
ds2.9a12/lib/tmp/
ds2.9a12/lib/verbs/admins/include/
ds2.9a12/lib/verbs/builders/
ds2.9a12/lib/verbs/common/
ds2.9a12/lib/verbs/common/include/
ds2.9a12/lib/verbs/creators/
ds2.9a12/lib/verbs/creators/include/
ds2.9a12/lib/verbs/rooms/
ds2.9a12/lib/verbs/rooms/include/
ds2.9a12/lib/www/client/
ds2.9a12/lib/www/errors/
ds2.9a12/lib/www/images/
ds2.9a12/lib/www/lpmuds/downloads_files/
ds2.9a12/lib/www/lpmuds/intermud_files/
ds2.9a12/lib/www/lpmuds/links_files/
ds2.9a12/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 *CommandHist = ({});
private string *localcmds = ({});
private string *next_command = ({});
private static string *QueuedCommands = ({});
private int MaxCommandHistSize = 20;
static string current_command = "";
static string original_command = "";

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


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

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

static string process_input(string cmd){ 
    current_command = cmd;
    return cmd;
}

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

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

    if(Paused){
        return 0;
    }

    if(!archp(this_player()) && 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){
            write("You have exceeded the "+MAX_COMMANDS_PER_SECOND+" commands per second limit.");
            return 1;
        }
    }    

    if(sizeof(CommandHist) >= MaxCommandHistSize) CommandHist -= ({ CommandHist[0] }); 
    if(!args) CommandHist += ({ query_verb() });
    else CommandHist += ({ query_verb()+" "+args });

    old_agent = this_agent(this_object());
    verb = query_verb();

    if(this_player()->GetSleeping() > 0){
        if(verb != "wake"){
            this_player()->eventPrint("You are asleep.");
            return 1;
        }
    }

    if(BARE_EXITS && environment()){
        localcmds = ({});
        filter(this_player()->GetCommands(), (: 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,environment(this_player())->GetExits()) != -1) verb = "go "+verb;
            if(member_array(dir,environment(this_player())->GetEnters()) != -1) verb = "enter "+verb;
        }
    }

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

    if(OLD_STYLE_PLURALS && args){
        int numba, i;
        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];
            if(sscanf(element,"%d.%s",numba,tmp_ret) == 2){
                if(present(numba+ordinal(numba)+" "+tmp_ret,environment(this_player()))){
                    args = replace_string(args,element,numba+ordinal(numba)+" "+tmp_ret);
                    continue;
                }
            }
            if(numba = atoi(element)){
                object o1;
                string e1, e2;
                e1 = numba+ordinal(numba);
                e2 = line[i-1];
                o1 = present(e2+" "+numba,this_player());
                if(!o1) o1 = present(e2+" "+numba,environment(this_player()));
                if(o1){
                    tmp_ret = e1+" "+e2;
                    args = replace_string(args,e2+" "+numba,tmp_ret);
                }
            }//end single number check
        }
    }

    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 = (string)CMD_D->GetCommand(verb, GetSearchPath())) ){
            string cmd;
            int dbg;

            if( args ) cmd = verb + " " + args;
            else cmd = verb;
            if( (int)this_object()->GetProperty("parse debug") ) dbg = 1;
            else if( (int)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 = (string)VERBS_D->GetErrorMessage(verb)) &&
                      !(err = (string)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 = (mixed)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 = (string)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 = (mixed)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);
    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++;
        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;

    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(!(int)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; }

static string *GetCommandHist(){
    return CommandHist;
}

string GetLastCommand(){
    if(!GetForced() && (this_player() == this_object() || previous_object() == master())){
        return CommandHist[sizeof(CommandHist)-1];
    }
    else return "";
}

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

int GetMaxCommandHistSize(){
    return MaxCommandHistSize;
}

int SetMaxCommandHistSize(int i){
    if(!i || i < 2) i = 2;
    return MaxCommandHistSize = i;
}

int SetPlayerPaused(int i){
    if( !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_player())) CommandFail = "Try \"help commands\" for a list of some commands.";
        if(creatorp(this_player())) CommandFail = "Try \"help creator commands\" for a list of some creator commands.";
        return CommandFail;
    }
    else return (CommandFail = str);
}

string GetCommandFail(){ return CommandFail; }