/* * _help.c * description: user help command * authors: wayfarer, mr.x * BUGS: change special case below to use mappings * Pallando made a few updates 930109 * Watcher updated the help search pattern 930415 */ // This thingy is from Blue@Tmi-2 although he didn't say so // Major rewrite by him, see doc_d. Good job Blue ;) // Added filtering of LPC help for mortals, probably not // thought of, because Blue did this on Tmi-2 :) // Todo: filter using levels. Eg. Help on a simul_efun // only for ones who have [r] in admsimul_efun. Blue ? :) // Leto: Aug 18th, 1995 // Leto: Sep 16th, 1995: fixed mortal-wizard behaviour // Leto: Oct 7th, 1995: Changes to use with 'string help(){}' calls. // Also changed all write() calls. // Fixed numerous bugs which were not allowing wizards or players // to see helps for commands which duplicated the names of other // help documents. Also improved the help banner to make it // consistent with the format of other player commands. // Emeradii@EarthMud 3Jan95 #include <uid.h> #include <help.h> #include <config.h> #include <daemons.h> #include <mudlib.h> #define STD_HELP "/help/help_screen" inherit DAEMON; void which_doc(string instr, string *list); int filter_mortal(string item) { return ( item[0..4] == "/help" ) ; } string get_banner(string group, string topic) { string temp; string spaces = " "; int num; temp = "Help for "+topic+" ("+group+")"; num = 71-strlen(temp); temp = "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n" + "=-="+spaces[0..num/2]+temp+spaces[0..(num+1)/2]+"=-=\n" + "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; return temp; } void write_banner(string group, string topic) { string temp; string spaces = " "; int num; temp = "Help for "+topic+" ("+group+")"; num = 71-strlen(temp); message ("help","=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n",this_player()); message ("help","=-="+spaces[0..num/2]+temp+spaces[0..(num+1)/2]+"=-=\n",this_player()); message ("help","=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n",this_player()); } string check_cmd( string path ) { string group = ""; switch( path ) { case USER_CMDS : group = "Player Command"; break; case WIZ_CMDS : group = "Wizard Command"; break; case WIZF_CMDS : group = "File Command"; break; case ADM_CMDS : group = "Admin Command"; break; } return group; } int call_help(string path, string topic) { string group, file, temp; object ob; file = path+"/_"+topic; if ((ob = find_object(file)) || (file_size(file+".c") >= 0 ) || (file_size(path + "/" + topic) >=0)) { switch(path) { case HELP_DIR : group = "General Help"; temp = get_banner(group, topic); this_player()->more(explode( (temp+read_file(path+"/"+topic)+"\n"), "\n" ), 0, 1); return 1; case WIZH_DIR : group = "Developer Help"; temp = get_banner(group, topic); this_player()->more(explode( (temp+read_file(path+"/"+topic)+"\n"), "\n" ), 0, 1); return 1; case PROPH_DIR : group = "Properties Help"; temp = get_banner(group, topic); this_player()->more(explode( (temp+read_file(path+"/"+topic)+"\n"), "\n" ), 0, 1); return 1; case CONCEPT_DIR : group = "Concepts Help"; temp = get_banner(group, topic); this_player()->more(explode( (temp+read_file(path+"/"+topic)+"\n"), "\n" ), 0, 1); return 1; case LPCH_DIR : group = "LPC Help"; temp = get_banner(group, topic); this_player()->more(explode( (temp+read_file(path+"/"+topic)+"\n"), "\n" ), 0, 1); return 1; case DAEMONS_DIR : group = "Daemons Help"; temp = get_banner(group, topic); this_player()->more(explode( (temp+read_file(path+"/"+topic)+"\n"), "\n" ), 0, 1); return 1; default : group = check_cmd(path); break; } if ( (group == "") && (wizardp(this_player()))) temp = get_banner( path, topic ); else if (group != "") temp = get_banner( group, topic ); else temp = ""; if (!ob) { call_other( file, "???" ); ob = find_object( file ); } if (!ob) { message("error", temp + "A command with that name exists, but it has an error in it.\n", this_player()); return 1; } if (function_exists("help", ob)) { this_player()->more(explode( (temp + call_other(file, "help")), "\n" ),0,1); return 1; } else { message("error", temp + "A command with that name exists, but it has no help.\n", this_player() ); return 1; } } return 0; } int cmd_help(string topic) { string *search_path; string *list, *newlist; string arg, name; int i, ii, it; object ob, act_ob; string bin, bintopic ; act_ob = this_player(); // We need to print out the help for THIS COMMAND!!! if (topic == "help") { message("help", this_object()->help(), this_player()); return 1; } if (!topic || topic == "") { message("help",read_file(STD_HELP),this_player()); return 1; } topic = lower_case( topic ); arg = replace_string( topic, "-d ", ""); if ( (arg != topic) && wizardp(this_player()) ) { topic = arg; switch(topic) { case "help" : message( "help", "[Help document files]\n\n", this_player() ); this_player()->force_me("ls /help"); return 1; case "properties" : message( "help", "[Property document files]\n\n", this_player() ); this_player()->force_me("ls " + PROPH_DIR); return 1; case "efun" : case "efuns" : message( "help", "[Efun document files]\n\n", this_player() ); this_player()->force_me("ls " + EFUN_DIR); return 1; case "lfun" : case "lfuns" : message( "help", "[Lfun document files]\n\n", this_player() ); this_player()->force_me("ls " + LFUN_DIR); return 1; case "wizhelp" : message( "help", "[Wizhelp document files]\n\n", this_player() ); this_player()->force_me("ls " + WIZH_DIR); return 1; case "simul_efuns" : case "simul_efun" : message( "help", "[Simul_efun document files]\n\n", this_player() ); this_player()->force_me("ls " + SE_DIR); return 1; case "applies" : message( "help", "[Applies document files]\n\n", this_player() ); this_player()->force_me("ls " + APPLY_DIR); return 1; case "lpc" : message( "help", "[LPC document files]\n\n", this_player() ); this_player()->force_me("ls " + LPCH_DIR); return 1; case "concepts" : message( "help", "[Concepts document files]\n\n", this_player() ); this_player()->force_me("ls " + CONCEPT_DIR); return 1; } return notify_fail("Directory search for "+topic+" found nothing.\n"); } if (sscanf(topic,"%s %s",bin,bintopic)==2) { switch (bin) { case "help" : return call_help(HELP_DIR, bintopic) ; case "wizhelp" : return call_help(WIZH_DIR, bintopic) ; case "lfun" : case "lfuns" : return (int)MAN_D -> man( bin, bintopic) ; case "efun" : case "efuns" : return (int)MAN_D -> man( bin, bintopic) ; case "simul_efuns" : return (int)MAN_D -> man( bin, bintopic) ; case "applies" : return (int)MAN_D -> man( bin, bintopic) ; case "commands" : search_path = explode((string)act_ob->query("PATH"), ":"); if (search_path) { for (i = 0; i < sizeof(search_path); i++) if (call_help(search_path[i],bintopic)) return 1; } message("help","There is no help available on that topic.\n", this_player() ); return 1 ; default : message ("error","Couldn't find help section: "+bin+".\n", this_player () ) ; return 1 ; } } list = DOC_D->get_docs_on(topic); if (list) { // leto: filter the list and remove all wiz // only topics from the list // Maybe this should be done by the DOC_D and a wizard // flag should be passed along the DOC_D call if (!wizardp(this_player())) list = filter_array(list,"filter_mortal",this_object() ); // Emeradii: Let's see if there are commands matching the topic which have help() in them. search_path = explode((string)act_ob->query("PATH"), ":"); if (search_path) { int flag; for (i = 0; i < sizeof(search_path); i++) { flag = 0; arg = search_path[i]+"/_"+topic; if ( ob = find_object(arg) ) flag = 1; else if ( file_size(arg + ".c") >= 0 ) { flag = 1; arg += ".c"; } else if ( file_size(search_path[i] + "/" + topic) >=0 ) { flag = 1; arg = search_path[i] + "/" + topic; } if (!ob && flag) { call_other( arg, "???" ); ob = find_object( arg ); } if (ob && flag && function_exists("help", ob)) { list += ({ "<help>\n" }) + ({ arg }); } } } // Leto: check to see if we didn't weed out all items for mortals if (!sizeof(list)) { notify_fail("There is no help available on that topic.\n"); return 0; } // Leto: show one item right away. if (sizeof(list)==2) { which_doc("1",list); return 1; } for (ii = 0; ii < sizeof(list); ii+=2) { printf("[%d] %s: %s", ii/2+1, list[ii+1], list[ii]); } printf("Which doc [1-%d,q]? ", sizeof(list)/2); input_to("which_doc", 0, list); return 1; } if (call_help(HELP_DIR, topic)) return 1; if (wizardp(act_ob)) { if (call_help(WIZH_DIR, topic)) return 1; if (call_help(PROPH_DIR, topic)) return 1; if (call_help(LPCH_DIR, topic)) return 1; if (call_help(CONCEPT_DIR, topic)) return 1; if (call_help(DAEMONS_DIR, topic)) return 1 ; } search_path = explode((string)act_ob->query("PATH"), ":"); if (search_path) { for (i = 0; i<sizeof(search_path); i++) if (call_help(search_path[i],topic)) return 1; } if (wizardp(act_ob)) { if ( sscanf( topic, "%s %s", arg, name ) < 2 ) arg = topic; if ((int)MAN_D -> man( arg, name ) == 1) return 1 ; } if ( (ob = present(topic,act_ob)) || (environment(act_ob) && (ob = present(topic,environment(act_ob)))) ) { if (function_exists("help",ob)) { message ("help","---------------------------------------------------\n",this_player() ); message ("help","Help for "+topic+" (Object Help)\n",this_player() ); message ("help","---------------------------------------------------\n",this_player() ); ob->help(); return 1; } } message("help","There is no help available on that topic.\n", this_player() ); return 1; } void which_doc(string instr, string *list) { string temp; int wd; if (!instr || !stringp(instr)) { message("prompt", "Which doc [1-"+sizeof(list)/2+",q]? ", this_player() ); input_to("which_doc", 0, list); return; } if ((instr[0] | 32) == 'q') { message("help"," Thank you for using Blue-Help(tm)! Please come again.\n", this_player() ); return; } if (((wd = to_int(instr))) < 1 || (wd > sizeof(list)/2)) { message("prompt", "A number in the range 1 to "+sizeof(list)/2 + ", please.\nWhich doc [1-"+sizeof(list)/2 +",q]? " + (this_player()->query("protocol")=="amcp/1.1") ? "\n" : "" ,this_player() ); input_to("which_doc", 0, list); return; } if (list[wd*2-2] == "<help>\n") { temp = check_cmd( "/"+implode((explode(list[wd*2-1],"/"))[0..<2],"/") ); if (temp == "") this_player()->more(explode( call_other(list[wd*2-1],"help"), "\n" ), 0, 1); else this_player()->more( explode( get_banner(temp,((explode(list[wd*2-1],"/"))[<1])[1..<1])+call_other(list[wd*2-1],"help"),"\n") ,0,1); } else this_player()->more(list[wd*2-1],!(wizardp(this_player())),1); } string help() { return @HelpText =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= =-= Help for help (Player Command) =-= =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Usage: help <-d> <area> <topic> The help command can give you help on a number of things in the mudlib Typing "help" will get you a general overview. "help start" will show you some information for new players. "help topics" will give you list of things you might want to read help on. Use of the -d flag will show all topics relating to an area, but can only be used by immortals or higher. You can specify a particular area in which to look for help commands. The HelpText + ((wizardp(this_player())) ? "possible areas are: help, wizhelp, commands, efuns, lfuns, simul_efuns,\n"+ "applies, concepts, and lpc.\n\n" : "possible areas are: help and commands.\n\n") ; }