foundation2_fluffos_v1/
foundation2_fluffos_v1/bin/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/ChangeLog.old/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/Win32/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/compat/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/compat/simuls/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/include/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/clone/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/command/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/data/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/etc/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/include/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/inherit/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/inherit/master/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/log/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/single/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/single/tests/compiler/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/single/tests/efuns/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/single/tests/operators/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/testsuite/u/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/tmp/
foundation2_fluffos_v1/fluffos-2.9-ds2.13/windows/
foundation2_fluffos_v1/lib/cfg/
foundation2_fluffos_v1/lib/cmds/adm/
foundation2_fluffos_v1/lib/daemon/save/
foundation2_fluffos_v1/lib/daemon/services/
foundation2_fluffos_v1/lib/daemon/soul/
foundation2_fluffos_v1/lib/doc/build/
foundation2_fluffos_v1/lib/doc/classes/
foundation2_fluffos_v1/lib/doc/driver/
foundation2_fluffos_v1/lib/doc/driver/applies/
foundation2_fluffos_v1/lib/doc/driver/applies/interactive/
foundation2_fluffos_v1/lib/doc/driver/concepts/
foundation2_fluffos_v1/lib/doc/driver/driver/
foundation2_fluffos_v1/lib/doc/driver/efuns/arrays/
foundation2_fluffos_v1/lib/doc/driver/efuns/buffers/
foundation2_fluffos_v1/lib/doc/driver/efuns/calls/
foundation2_fluffos_v1/lib/doc/driver/efuns/compile/
foundation2_fluffos_v1/lib/doc/driver/efuns/filesystem/
foundation2_fluffos_v1/lib/doc/driver/efuns/floats/
foundation2_fluffos_v1/lib/doc/driver/efuns/functions/
foundation2_fluffos_v1/lib/doc/driver/efuns/general/
foundation2_fluffos_v1/lib/doc/driver/efuns/mappings/
foundation2_fluffos_v1/lib/doc/driver/efuns/numbers/
foundation2_fluffos_v1/lib/doc/driver/efuns/parsing/
foundation2_fluffos_v1/lib/doc/driver/lpc/constructs/
foundation2_fluffos_v1/lib/doc/driver/lpc/types/
foundation2_fluffos_v1/lib/doc/driver/platforms/
foundation2_fluffos_v1/lib/doc/efun/
foundation2_fluffos_v1/lib/doc/etc/
foundation2_fluffos_v1/lib/doc/faq/
foundation2_fluffos_v1/lib/doc/help/creator/
foundation2_fluffos_v1/lib/doc/help/player/
foundation2_fluffos_v1/lib/doc/lpc/basic/
foundation2_fluffos_v1/lib/doc/lpc/data_types/
foundation2_fluffos_v1/lib/doc/lpc/etc/
foundation2_fluffos_v1/lib/doc/lpc/intermediate/
foundation2_fluffos_v1/lib/doc/lpc/types/
foundation2_fluffos_v1/lib/doc/mudlib/
foundation2_fluffos_v1/lib/doc/mudlib/Features/
foundation2_fluffos_v1/lib/domains/Examples/armour/
foundation2_fluffos_v1/lib/domains/Examples/etc/
foundation2_fluffos_v1/lib/domains/Examples/npc/
foundation2_fluffos_v1/lib/domains/Examples/room/
foundation2_fluffos_v1/lib/domains/Examples/virtual/
foundation2_fluffos_v1/lib/domains/Examples/virtual/exaA/
foundation2_fluffos_v1/lib/domains/Examples/virtual/exaB/
foundation2_fluffos_v1/lib/domains/Examples/weapon/
foundation2_fluffos_v1/lib/domains/School/doc/
foundation2_fluffos_v1/lib/domains/School/room/
foundation2_fluffos_v1/lib/domains/School/room/Classes/
foundation2_fluffos_v1/lib/domains/School/room/Offices/
foundation2_fluffos_v1/lib/domains/Standard/
foundation2_fluffos_v1/lib/domains/Standard/pools/
foundation2_fluffos_v1/lib/domains/Standard/std/
foundation2_fluffos_v1/lib/domains/Standard/xtra/
foundation2_fluffos_v1/lib/include/
foundation2_fluffos_v1/lib/lib/obj/
foundation2_fluffos_v1/lib/news/
foundation2_fluffos_v1/lib/save/
foundation2_fluffos_v1/lib/secure/cfg/
foundation2_fluffos_v1/lib/secure/cmds/player/
foundation2_fluffos_v1/lib/secure/lib/
foundation2_fluffos_v1/old/
foundation2_fluffos_v1/win32/
/*    /daemon/help.c
 *    from the Foundation II LPC Library
 *    daemon handling mud help functions and help interface
 *    created by Descartes of Borg 940420
 */

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

inherit LIB_DAEMON;

varargs void help(string topic, string category, int menu) {
    if(!topic || topic == "" ) topic = "*player general";
    if(topic[0] == '*') help_menu(topic, 0, 0);
    else cmd_help(topic, category, menu);
}

static void help_menu(string category, string *topics, int ind) {
    int *screen;
    int i, maxi, x, cols, width, colwidth, y = 0;
    string tmp;

    if( !topics && !(topics = query_topics(category)) ) {
        message("help", "\nInvalid help category.", this_player());
        message("prompt", "\nSelection: ", this_player());
        input_to("select_topic", category, topics, ind);
        return;
    }
    screen = (int *)this_player()->GetScreen();
    for(i=0, maxi = sizeof(topics); i<maxi; i++) 
      if( width < (y = strlen(topics[i])) ) width = y;
    cols = screen[0]/(width+2);
    colwidth = screen[0]/cols;
    if( (maxi = ind + ((screen[1] - 15)*cols)) > sizeof(topics) ) 
      maxi = sizeof(topics);
    message("Nhelp", "%^INITTERM%^" + 
	    center(mud_name() + " System Help", screen[0]), this_player());
    message("Nhelp", "Category: %^GREEN%^" + category + 
	    sprintf("%:-" + (screen[0]/2 - strlen("Category: "+ category)) + 
		    "s", "") + sprintf("%" + (screen[0]/2) + "s",
				       "Page: " + (ind/40+1) + " of " +
				       (sizeof(topics)/40 + 1)) + "%^RESET%^",
	    this_player());
    i = sizeof(topics);
    i = ind;
    while(i < maxi) {
        if( (x = i + cols) >=maxi ) x = maxi;
        tmp = "";
        while(i < x) {
            tmp += arrange_string(topics[i], colwidth);
            i++;
        }
        message("help", tmp, this_player());
    }
    message("Nhelp", "\n%^CYAN%^Available categories:\n" +
      format_page(query_categories(), 3), this_player());
    message("help", "\nTo choose another category, enter the name of "
      "the category.", this_player());
    message("help", "To view help on any of the above topics, "
      "enter the name of the topic.", this_player());
    message("help", "To see the next page of topics, enter the "
      "<return> key.", this_player());
    message("help", "To quit from help, enter \"q\" alone.",
      this_player());
    message("prompt", "\nSelection: ", this_player());
    input_to("select_topic", category, topics, ind, maxi);
}

static void select_topic(string str, string category, string *topics, int ind,int maxi) {
    if(str == "") {
        if(maxi < sizeof(topics)) help_menu(category, topics, maxi);
        else help_menu(category, topics, ind);
        return;
      }
    else if(str == "q") {
        message("help", "\nExit from help.", this_player());
        return;
      }
    else help(str, category, 1);
}

static string *query_categories() {
    string *tmp;

    tmp = ({ "*player general", "*player commands" });
    if( (string)this_player()->GetGuild() ) tmp += ({ "*guild commands" });
    if( avatarp(this_player()) || high_mortalp(this_player()) || 
       creatorp(this_player()) )
      tmp += ({ "*high mortal general", "*high mortal commands" });
    if( avatarp(this_player()) || creatorp(this_player()) )
      tmp += ({ "*avatar general", "*avatar commands" });
    if( creatorp(this_player()) ) 
      tmp += ({ "*creator general", "*creator commands" });
    if (archp(this_player()) ) tmp += ({ "*admin commands" }); 
    return tmp;
}

static string *query_topics(string category) {
    string tmp;

    switch(category) {
    case "*player general": return get_dir(DIR_PLAYER_HELP+"/");
    case "*creator general":
        if(!creatorp(this_player())) return 0;
        else return get_dir(DIR_CREATOR_HELP+"/");
    case "*avatar general":
        if( !creatorp(this_player()) && !avatarp(this_player()) ) return 0;
        else return get_dir(DIR_AVATAR_HELP+"/");
    case "*high mortal general":
        if(!creatorp(this_player()) && !high_mortalp(this_player())) return 0;
        else return get_dir(DIR_HM_HELP+"/");
    case "*player commands":
        return (string *)CMD_D->GetCommands(DIR_PLAYER_CMDS) +
          (string *)CMD_D->GetCommands(DIR_SECURE_PLAYER_CMDS);
    case "*creator commands":
        if(!creatorp(this_player())) return 0;
        return (string *)CMD_D->GetCommands(DIR_CREATOR_CMDS) +
          (string *)CMD_D->GetCommands(DIR_SECURE_CREATOR_CMDS);
    case "*high mortal commands":
        if(!creatorp(this_player()) && !high_mortalp(this_player()) &&
	   !avatarp(this_player()) ) return 0;
        return (string *)CMD_D->GetCommands(DIR_HM_CMDS);
    case "*avatar commands":
        if(!creatorp(this_player()) && !avatarp(this_player())) return 0;
        return (string *)CMD_D->GetCommands(DIR_AVATAR_CMDS);
    case "*admin commands":
        if(!archp(this_player())) return 0;
        else return (string *)CMD_D->GetCommands(DIR_ADMIN_CMDS) +
          (string *)CMD_D->GetCommands(DIR_SECURE_ADMIN_CMDS);
    default: return 0;
  }
}

void cmd_help(string topic, string category, int menu) {
    object ob;
    string *tmp;
    int i;

    if( category && category != "" ) {
        if(member_array(category, query_categories()) == -1) {
            message("help", "Category " + category + " not available.",
		    this_player());
            if(menu) {
                message("prompt", "\nHit <return> to continue: ", 
                  this_player());
                input_to("menu_return", category);
	      }
	  }
        else if(!find_help(topic, category, menu)) {
            message("help", sprintf("The help topic %s does not exist in "
              "the category %s.", topic, category), this_player());
            if(menu) {
                message("prompt", "\nHit <return> to continue: ",
                  this_player());
                input_to("menu_return", category);
	      }
	  }
        return;
      }
    else {
        i = sizeof(tmp = query_categories());
        while(i--) if(find_help(topic, tmp[i], menu)) return;
        if((ob = present(topic, this_player())) &&
          function_exists("help", ob)) {
            ob->help();
            return;
	  }
        else if((ob = present(topic, environment(this_player()))) &&
          function_exists("help", ob)) {
            ob->help();
            return;
	  }
        message("help", sprintf("No help available for the topic %s.",
          topic), this_player());
        if(menu) {
            message("prompt", "\nHit <return> to continue: ", this_player());
            input_to("menu_return", category);
	  }
        return;
      }
  }

static int find_help(string topic, string category, int menu) {
    object ob;
    string str;
    mixed tmp;

    switch(category) {
	case "*player general":
        if(!file_exists(tmp = DIR_PLAYER_HELP+"/"+topic)) return 0;
        break;
    case "*player commands":
        if(!file_exists(tmp = DIR_PLAYER_CMDS "/" + topic+".c") &&
          !file_exists(tmp = DIR_SECURE_PLAYER_CMDS "/"+topic+".c")) return 0;
        if(!(ob = load_object(tmp)) || !function_exists("help", ob))
          return 0;
        tmp = ob;
        break;
    case "*creator general":
        if(!file_exists(tmp = DIR_CREATOR_HELP "/"+topic)) return 0;
        break;
    case "*creator commands":
        if(file_exists(tmp = DIR_CREATOR_CMDS "/"+topic+".c") &&
          (ob = load_object(tmp)) && function_exists("help", ob)) tmp = ob;
        else if(file_exists(tmp = DIR_SYSTEM_CMDS "/"+topic+".c") &&
          (ob = load_object(tmp)) && function_exists("help", ob)) tmp = ob;
        else if(file_exists(tmp = DIR_SECURE_CREATOR_CMDS "/"+topic+".c") &&
         (ob = load_object(tmp)) && function_exists("help", ob)) tmp = ob;     
        else return 0;
        break;
    case "*avatar general":
        if( !file_exists(tmp = DIR_AVATAR_HELP "/"+topic ) ) return 0;
        break; 
    case "*avatar commands":
        if(file_exists(tmp = DIR_AVATAR_CMDS "/" + topic+".c") &&
          (ob = load_object(tmp)) && function_exists("help", ob)) tmp = ob;
        else return 0;
        break;
    case "*high mortal general":
        if(!file_exists(tmp = DIR_HM_HELP+"/"+topic)) return 0;
        break;
    case "*high mortal commands":  
        if(!file_exists(tmp = DIR_HM_CMDS "/" + topic+".c")) return 0;
        if(!(ob = load_object(tmp)) || !function_exists("help", ob))
          return 0;
        tmp = ob;
        break;
    case "*admin commands":
        if(!archp(this_player())) return 0;
        if(!file_exists(tmp = DIR_ADMIN_CMDS "/"+topic+".c") &&
          !file_exists(tmp = DIR_SECURE_ADMIN_CMDS "/"+topic+".c")) return 0;
        if(!(ob = load_object(tmp)) || !function_exists("help", ob))
          return 0;
        tmp = ob;
        break; 
      }
    message("help", "\n%^INITTERM%^Topic: " + topic + "\n", this_player());
    if(objectp(tmp)) {
        tmp->help();
        if(menu) {
            message("prompt", "\nHit <return> to continue: ", this_player());
            input_to("menu_return", category);
        }
    }
    else this_player()->more(tmp, "help", (menu ? (: endmore :) : 0),
      (menu ? category : 0));
    return 1;
  }

static void menu_return(string duh, string category) {
    if(duh != "q") help(category);
}

void endmore(string category) {
    message("prompt", "\nHit <return> to continue: ", this_player());
    input_to("menu_return", category);
}