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

#include <lib.h>
#include <dirs.h>
#include <daemons.h>

inherit LIB_DAEMON;

static private string Error, SeeAlso = "";
static private mapping Indices;

static private void LoadIndices();
string GetHelp(string str);
string GetHelpByIndex(string index, string topic);
string GetTopic(string index, string topic);
varargs string array GetIndices(string topic);

static void create() {
    daemon::create();
    SetNoClean(1);
    Error = 0;
    LoadIndices();
}

int CanAccess(object who, string index) {
    switch(index) {
        case "admin commands":
            return archp(who);

        case "creator commands": case "creator documents":
            case "library objects": case "daemon objects":
            return creatorp(who);

        case "builder commands":  
            return builderp(who);

        default:
        return 1;
    }
}

static private void LoadIndices() {
    string array tmp;
    function f;
    string dir;

    f = function(string str) { return str[0..<3]; };
    Indices = ([]);

    tmp = get_dir(DIR_ADMIN_VERBS + "/*.c") + get_dir(DIR_ADMIN_CMDS + "/*.c")
        + get_dir(DIR_SECURE_ADMIN_CMDS + "/*.c");
    Indices["admin commands"] = map(tmp, f);

    tmp = get_dir(DIR_COMMON_VERBS+"/*.c") +
        get_dir(DIR_COMMON_CMDS + "/*.c") +
        get_dir(DIR_SECURE_COMMON_CMDS + "/*.c") +
        get_dir(DIR_ITEM_VERBS + "/*.c") +
        get_dir(DIR_PLAYER_VERBS+"/*.c") +
        get_dir(DIR_PLAYER_CMDS+"/*.c") +
        get_dir(DIR_ROOM_VERBS + "/*.c") +	
        get_dir(DIR_SPELL_VERBS + "/*.c") +
        //get_dir(DIR_SECURE_BUILDER_CMDS + "/*.c") +
        //get_dir(DIR_BUILDER_CMDS + "/*.c") +
        get_dir(DIR_SECURE_PLAYER_CMDS + "/*.c");
    Indices["commands"] = map(tmp, f);

    tmp = get_dir(DIR_CREATOR_VERBS+"/*.c") + get_dir(DIR_CREATOR_CMDS+"/*.c")
        + get_dir(DIR_SECURE_CREATOR_CMDS + "/*.c");
    Indices["creator commands"] = map(tmp, f);

    tmp = get_dir(DIR_SECURE_BUILDER_CMDS + "/*.c") +
        get_dir(DIR_BUILDER_VERBS + "/*.c") +
        (get_dir(DIR_BUILDER_CMDS + "/*.c") || ({}));
    Indices["builder commands"] = map(tmp, f);

    tmp = get_dir(DIR_UNDEAD_VERBS "/*.c");
    Indices["undead commands"] = map(tmp, f);

    tmp = SOUL_D->GetEmotes();
    Indices["feelings"] = tmp;

    tmp = filter(map(get_dir(DIR_SPELLS "/*.c"),
                function(string file) {
                file = DIR_SPELLS "/" + file;
                if( file->GetVerb() == "cast" ) {
                return file->GetSpell();
                }
                return 0;
                }), (: $1 :));
    Indices["spells"] = tmp;

    tmp = filter(map(get_dir(DIR_SPELLS "/*.c"),
                function(string file) {
                file = DIR_SPELLS "/" + file;
                if( file->GetVerb() == "pray" ) {
                return file->GetSpell();
                }
                return 0;
                }), (: $1 :));
    Indices["prayers"] = tmp;

    if( tmp = get_dir(DIR_PLAYER_HELP + "/") )
        Indices["player documents"] = tmp + ({ "soul" });
    else Indices["player documents"] = ({ "soul" });

    if( tmp = get_dir(DIR_CREATOR_HELP "/") )
        Indices["creator documents"] = tmp;
    else Indices["creator document"] = ({});

    if( tmp = (string array)CLASSES_D->GetClasses() )
        Indices["classes"] = tmp;
    else Indices["classes"] = ({});

    if( tmp = (string array)RACES_D->GetRaces(1) )
        Indices["races"] = tmp;
    else Indices["races"] = ({});

    if( tmp = get_dir(DIR_LAW_HELP "/") )
        Indices["law"] = tmp;
    else Indices["law"] = ({});    

    if( tmp = get_dir(DIR_RELIGION_HELP "/") )
        Indices["religion"] = tmp;
    else Indices["religion"] = ({});

    if( tmp = get_dir(DIR_CONSTRUCTS_HELP "/") )
        Indices["lpc"] = tmp;
    else Indices["lpc"] = ({});

    if( tmp = get_dir(DIR_CONCEPTS_HELP "/") )
        Indices["lpc"] += tmp;

    Indices["library objects"] = ({});
    foreach(dir in ({ DIR_LIB, DIR_SECURE_LIB })){
        if( !(tmp = get_dir(dir + "/*.c")) ) continue;
        else Indices["library objects"] +=
            map(tmp, (: $(dir)+"/"+$1[0..<3] :));
    }

    Indices["daemon objects"] = ({});
    foreach(dir in ({ DIR_DAEMONS, DIR_SECURE_DAEMONS })) {
        if( !(tmp = get_dir(dir + "/*.c")) ) continue;
        else Indices["daemon objects"] +=
            map(tmp, (: $(dir)+"/"+$1[0..<3] :));
    }
}

string GetHelp(string str) {
    string *tmp, choice,ret ="";
    string topic;
    int x;

    Error = 0;
    if( !str || str == "" || str == "help" ) {
        return ("Syntax: <help>\n"
                "        <help index>\n"
                "        <help TOPIC>\n"
                "        <help INDEX TOPIC>\n\n"
                "The special topic, \"help index\", puts you into "
                "a menu driven index of categories for which help exists.\n\n"
                "For players, \"help commands\" will provide an index of "
                "available player commands.\n "
                "For creators, \"help creator commands\" provides an "
                "index of available creator commands.\n\n "
                "Try \"help commands\" "
                "and \"help creator commands\" first. \n\n"
                " ");
    }
    if(member_array(str, CHAT_D->GetChannels()) != -1 &&
            str != "newbie" && member_array(str, CLASSES_D->GetClasses()) == -1){
        return "See: help channels";
    }
    if( sscanf(str, "adverbs %s", topic) || str == "adverbs" ) {
        return (string)SOUL_D->GetHelp(str);
    }
    tmp = GetIndices(str);
    if( sizeof(tmp) > 0){
        if( sizeof(tmp) > 1){
            if(member_array("admin commands",tmp) != -1) choice = "admin commands";
            else if(member_array("creator commands",tmp) != -1) choice = "creator commands";
            else if(member_array("player commands",tmp) != -1) choice = "player commands";
            else if(member_array("builder commands",tmp) != -1) choice = "builder commands";
        }
        if(!choice) choice = tmp[0];
        tmp -= ({ choice });

        if(sizeof(tmp)) SeeAlso = "\nThere also exists help for \"" + str + "\" under the following "
            "indices:\n" + implode(tmp, ", ");
        ret = GetHelpByIndex(choice, str);
        if(ret) ret += SeeAlso;
        SeeAlso = "";
        return ret;
    }
    topic = "";
    str = trim(str);
    while( (x = strsrch(str, " ")) != -1 ) {
        if( topic != "" ) {
            topic = topic + " " + str[0..(x-1)];
        }
        else {
            topic = str[0..(x-1)];
        }
        str = str[(x+1)..];
        if( Indices[topic] && strlen(str) ) {
            return GetHelpByIndex(topic, str);
        }
    }

    if(this_player() && adminp(this_player())){
        Error = "Help for the topic \"" + str + "\" could not be found.";
    }
    else {
        Error = "The search for help on the topic \"" + str + "\" yields you no results.";
    }
    return 0;
}

string GetHelpByIndex(string index, string topic) {
    mixed array tmparr, fun;
    mapping tmpmap;
    object ob;
    string help, file, tmpstr;

    if( this_player() && !CanAccess(this_player(), index) ) {
        Error = "You do not have access to that information.";
        return 0;
    }
    switch(index) {
        case "admin commands": case "creator commands": case "undead commands":
            case "commands": case "builder commands" :
            switch(index) {
                case "admin commands":
                    if( file_exists( DIR_ADMIN_VERBS + "/" + topic + ".c") )
                        file = DIR_ADMIN_VERBS + "/" + topic;
                    else if( file_exists( DIR_ADMIN_CMDS + "/" + topic + ".c") )
                        file = DIR_ADMIN_CMDS + "/" + topic;
                    else file = DIR_SECURE_ADMIN_CMDS + "/" + topic;
                break;

                case "creator commands":
                    if( file_exists( DIR_CREATOR_VERBS + "/" + topic + ".c") )
                        file = DIR_CREATOR_VERBS + "/" + topic;
                    else if( file_exists(DIR_CREATOR_CMDS + "/" + topic + ".c") )
                        file = DIR_CREATOR_CMDS + "/" + topic;
                    else file = DIR_SECURE_CREATOR_CMDS + "/" + topic;
                break;      

                case "builder commands":
                    if( file_exists( DIR_BUILDER_VERBS + "/" + topic + ".c") )
                        file = DIR_BUILDER_VERBS + "/" + topic;
                    else if( file_exists(DIR_BUILDER_CMDS + "/" + topic + ".c") )
                        file = DIR_BUILDER_CMDS + "/" + topic;
                    else file = DIR_SECURE_BUILDER_CMDS + "/" + topic;
                break;

                case "commands":
                    foreach(string directory in ({ DIR_COMMON_VERBS,
                                DIR_COMMON_CMDS,
                                DIR_SECURE_COMMON_CMDS,
                                DIR_ITEM_VERBS,
                                DIR_PLAYER_VERBS,
                                DIR_PLAYER_CMDS,
                                DIR_SECURE_PLAYER_CMDS,
                                DIR_ROOM_VERBS,
                                DIR_SPELL_VERBS })) {
                        if( file_exists(directory + "/" + topic + ".c") ) {
                            file = directory + "/" + topic;
                            break;
                        }
                    }
                break;

                case "undead commands":
                    file = DIR_UNDEAD_VERBS + "/" + topic;
                break;      
            }
        if( !file_exists(file + ".c") ) {
            Error = "No such " + index[0..<2] + " exists.";
            return 0;
        }
        if( catch(help = file->GetHelp(topic)) ) {
            Error = "An error occurred in attempting to access help.";
            return 0;
        }
        if( !help ) {
            string *syn, *pd;
            string line;

            pd = regexp(explode(parse_dump(), "\n"), file[1..]);
            syn = ({});
            foreach(line in pd) {
                sscanf(line, "%*s"+file[1..]+") %s", tmpstr);
                syn += ({ tmpstr });
            }
            if( !sizeof(syn) ) {
                if( function_exists("help", load_object(file)) ) {
                    Error = " ";
                    file->help();
                    write(SeeAlso);
                    SeeAlso = "";
                    return 0;
                }
                Error = "Unable to locate any syntax information on " +
                    topic + ".";
                return 0;
            }
            help = "Syntax: " + topic + " " + syn[0] + "\n";
            if( sizeof(syn) == 1 ) help += "\n";
            else {
                foreach(line in syn[1..])
                    help += "        " + topic + " " + line + "\n";
                help += "\n";
            }
            help += "No detailed documentation exists for this command.";
        }
        help = "Index: %^GREEN%^" + index + "%^RESET%^\n" +
            "Topic: %^GREEN%^" + topic + "%^RESET%^\n\n" + help;
        return help;

        case "player documents": case "creator documents":
            case "law": case "lpc":
            switch(index) {
                case "player documents":
                    if( topic == "soul" ) {
                        help = SOUL_D->GetHelp("soul");
                        help = "Index: %^GREEN%^" + index + "%^RESET%^\n" +
                            "Topic: %^GREEN%^" + topic + "%^RESET%^\n\n" + help;
                        return help;
                    }
                file = DIR_PLAYER_HELP "/" + topic;
                break;

                case "creator documents":
                    file = DIR_CREATOR_HELP "/" + topic;
                break;

                case "law":
                    file = DIR_LAW_HELP "/" + topic;
                break;

                case "lpc":
                    file = DIR_CONCEPTS_HELP "/" + topic;
                if( !file_exists(file) )
                    file = DIR_CONSTRUCTS_HELP "/" + topic;
                break;
            }
        if( !file_exists(file) ) {
            Error = "No such " + index[0..<2] + " is available.";
            return 0;
        }
        if( !(help = read_file(file)) ) {
            Error = "The document " + topic + " was empty.";
            return 0;
        }
        help = "Index: %^GREEN%^" + index + "%^RESET%^\n" +
            "Topic: %^GREEN%^" + topic + "%^RESET%^\n\n" + help;
        return help;

        case "feelings":
            help = SOUL_D->GetHelp(topic);
        if( !help ) {
            Error = "No such " + index[0..<2] + " is available.";
            return 0;
        }
        help = "Index: %^GREEN%^" + index + "%^RESET%^\n" +
            "Topic: %^GREEN%^" + topic + "%^RESET%^\n\n" + help;
        return help;;

        case "library objects":
            topic = GetTopic(index, topic);
        if( !file_exists(topic+".c") ){
            Error = "No such topic found.";
            return 0;
        }
        if(  catch(help = topic->GetHelp(topic)) ) {
            Error = "An error occurred in attempting to access help.";
            return 0;
        }
        if( !help ) {
            help = "No synopsis available for this object.\n\n";
        }
        else {
            help = "Synopsis:\n" + help + "\n\n";
        }
        tmparr = stat(topic + ".c");
        tmpstr = "Object: " + topic + "\n"
            "Last Modified: " + ctime(tmparr[1]) + "\n";
        if( tmparr[2] ) {
            tmpstr += "Last Loaded: " + ctime(tmparr[2]) + "\n\n";
        }
        tmparr = inherit_list(ob = find_object(topic));
        if( !sizeof(tmparr) ) {
            tmpstr += "No inherited objects\n\n";
        }
        else {
            tmpstr += "Inherits:\n" + format_page(tmparr, 4) + "\n";
        }
        tmparr = functions(ob, 1);
        tmpmap = ([]);
        foreach(fun in tmparr) {
            if( function_exists(fun[0], ob) != topic ) {
                continue;
            }
            if( fun[0] == "#global_init#" ) {
                continue;
            }
            if( tmpmap[fun[0]] ) {
                continue;
            }
            else {
                tmpmap[fun[0]] = ([ "type" : fun[2],
                        "args" : (fun[1] ? fun[3..] : ({})) ]);
            }
        }
        help = tmpstr + help;
        if( !sizeof(tmparr) ) {
            help += "No functions\n\n";
        }
        else {
            string fnc;

            help += "Functions:\n";
            tmparr = sort_array(keys(tmpmap), 1);
            foreach(fnc in tmparr) {
                help += tmpmap[fnc]["type"] + fnc + "(" +
                    implode(tmpmap[fnc]["args"], ", ") + ")\n";
            }
        }
        help = "Index: %^GREEN%^" + index + "%^RESET%^\n" +
            "Topic: %^GREEN%^" + topic + "%^RESET%^\n\n" + help;
        return help;

        case "daemon objects":
            topic = GetTopic(index, topic);
        if( !topic || catch(help = topic->GetHelp(topic)) ) {
            Error = "An error occurred in attempting to access help for that.";
            return 0;
        }
        if( !help ) {
            help = "No synopsis available for this object.\n\n";
        }
        else {
            help = "Synopsis:\n" + help + "\n\n";
        }
        tmparr = stat(topic + ".c");
        tmpstr = "Object: " + topic + "\n"
            "Last Modified: " + ctime(tmparr[1]) + "\n";
        if( tmparr[2] ) tmpstr += "Last Loaded: " + ctime(tmparr[2]) + "\n\n";
        tmparr = inherit_list(ob = find_object(topic));
        if( !sizeof(tmparr) ) tmpstr += "No inherited objects\n\n";
        else tmpstr += "Inherits:\n" + format_page(tmparr, 4) + "\n";
        tmparr = functions(ob, 1);
        tmpmap = ([]);
        foreach(fun in tmparr) {
            if( function_exists(fun[0], ob) != topic ) continue;
            if( fun[0] == "#global_init#" ) continue;
            if( tmpmap[fun[0]] ) continue;
            else tmpmap[fun[0]] = ([ "type" : fun[2],
                    "args" : (fun[1] ?  fun[3..] : ({})) ]);
        }
        help = tmpstr + help;
        if( !sizeof(tmparr) ) help += "No functions\n\n";
        else {
            string fnc;

            help += "Functions:\n";
            tmparr = sort_array(keys(tmpmap), 1);
            foreach(fnc in tmparr)
                help += tmpmap[fnc]["type"] + fnc + "(" +
                implode(tmpmap[fnc]["args"], ", ") + ")\n";
        }
        help = "Index: %^GREEN%^" + index + "%^RESET%^\n" +
            "Topic: %^GREEN%^" + topic + "%^RESET%^\n\n" + help;
        return help;    

        case "religons": case "religion":
            if( file_exists(DIR_RELIGION_HELP "/" + topic) ) {
                help = read_file(DIR_RELIGION_HELP "/" + topic);
                help = "Index: %^GREEN%^" + index + "%^RESET%^\n" +
                    "Topic: %^GREEN%^" + topic + "%^RESET%^\n\n" + help;
                return help;
            }
        Error = "No such religion exists.";
        return 0;

        case "races":
            if( help = (string)RACES_D->GetHelp(topic) ) {
                help = "Index: %^GREEN%^" + index + "%^RESET%^\n" +
                    "Topic: %^GREEN%^" + topic + "%^RESET%^\n\n" + help;
                return help;
            }
            else if( file_exists(DIR_RACE_HELP + "/" + topic) ){
                help = read_file(DIR_RACE_HELP + "/" + topic);
                return help;
            }
        Error = "There is no such race.";
        return 0;

        case "spells": case "prayers":
            ob = SPELLS_D->GetSpell(topic);
        if( !ob ) {
            Error = "No such spell exists.";
            return 0;
        }
        if( !(help = ob->GetHelp(topic)) ) {
            Error = "No help is available for that spell.";
            return 0;
        }
        help = "Index: %^GREEN%^" + index + "%^RESET%^\n" +
            "Topic: %^GREEN%^" + topic + "%^RESET%^\n\n" + help;
        return help;

        case "classes":
            if( help = (string)CLASSES_D->GetHelp(topic) ) {
                help = "Index: %^GREEN%^" + index + "%^RESET%^\n" +
                    "Topic: %^GREEN%^" + topic + "%^RESET%^\n\n" + help;
                if( file_exists(DIR_CLASS_HELP + "/" + topic) )
                    help += read_file(DIR_CLASS_HELP + "/" + topic);
                return help;
            }
        Error = "No such class exists.";
        return 0;

        default:
        Error = "No help exists for the index " + index + ".";
        return 0;
    }
}

varargs string array GetIndices(string topic) {
    string array topics, val;
    string ind, tmp;

    if( !topic ) {
        return sort_array(keys(Indices), 1);
    }
    topics = ({});
    foreach(ind, val in Indices) {
        if( !CanAccess(this_player(), ind) ) {
            continue;
        }
        tmp = GetTopic(ind, topic);
        if( member_array(tmp, val) != -1 ) {
            topics += ({ ind });
        }
    }
    return sort_array(topics, 1);
}

string GetTopic(string index, string topic) {
    string array dirlist;
    string dir;

    if( index != "library objects" && index != "daemon objects" ) {
        return topic;
    }
    if( index == "library objects" ) {
        dirlist = ({ DIR_LIB, DIR_SECURE_LIB });
    }
    else {
        dirlist = ({ DIR_DAEMONS, DIR_SECURE_DAEMONS });
    }
    if( strlen(topic) > 2 && topic[<2..] == ".c" ) {
        topic = topic[0..<3];
    }
    if( file_exists(topic + ".c") ) {
        return topic;
    }
    foreach(dir in dirlist) {
        if( file_exists(dir + "/" + topic + ".c") ) {
            return dir + "/" + topic;
        }
    }
    return 0;
}

string array GetTopics(string index) {
    string array topics = Indices[index];

    if( !topics ) {
        return 0;
    }
    else {
        return sort_array(topics, 1);
    }
}

string GetLastError() {
    return Error;
}

void Reload() {
    LoadIndices();
}