----------------------------------------------------------------------- Help Index System v1.0 by Xerves (September 14 2002) Xerves is the admin/owner of Rafermand (mud.rafermand.net port 3002) Website: http://www.rafermand.net Contact: xerves@rafermand.net ----------------------------------------------------------------------- Well this took a few days of work longer than I thought, but I have finally finished it, and it is a giant dandy of a snippet. This is by far the most complicated snippet I have released so far (but might I add a very easy to implement and use, just difficult to understand, laugh). There are also two phases of installing this. You need to follow step 1 below to prep your helpfiles for the transition, then you need to install the actual code in and then do a reboot/copyover. +++++++VERY IMPORTANT++++++++ Copy the backuped helpfile (help.are.sbak) somewhere safe, like on a few floppy disks till you start to use this system. Once you go to the index, it might not be fun ripping it out of a few hundred helpfiles. So now that is out of the way, what the hell is this snippet anyway? Below is some output from hindex mage ****************************************************************************************** ----------------------------Helpfiles in mage Index----------------------------- imm bodybag remove invis acid breath fire breath frost breath gas breath lightning breath --------------------------------Indexes Above mage------------------------------ general --------------------------------Indexes Below mage------------------------------ attack -------------------------Full index above/below mage --------------------------- ****************************************************************************************** Above is an example of the hindex command. This is used by typing hindex mage to get a listing of all helpfiles in that index, and indexes above/below. If you have MXP support, all the helpfiles have links to them, all the indexes, and the words "Full index" there at the bottom. You can just click on them and it will run the appropriate command. In addition, you can see a full map of the index, and it looks like this ****************************************************************************************** ------------------------Full Map of the Index------------------------ general mage attack gem test imm attack gem test ****************************************************************************************** As you can see, it shows a map of the whole index layer by layer. This one is straight forward, but you can see two of the features of interest here. You can have more than one index at a certain level. You can have Attack->Gem and also Attack->Test. This will allow you to group indexes that are similiar, but you don't want to dump helpfiles into only 1. In addition to this, you can see that attack shows up twice, this is the product of cross-linking. You can have one index point to attack, and then have another. The only problem with this is you have to be careful because if you point it back ahead of the index, it is possible for it to create a infinite loop. So plan out your links before doing that. Below is what you see with help frost breath ****************************************************************************************** 'ACID BREATH' 'FIRE BREATH' 'FROST BREATH' 'GAS BREATH' 'LIGHTNING BREATH' Syntax: cast 'acid breath' Syntax: cast 'fire breath' Syntax: cast 'frost breath' Syntax: cast 'gas breath' Syntax: cast 'lightning breath' These spells are for the use of dragons. Acid, fire, frost, and lightning damage one victim, whereas gas damages every PC in the room. Fire and frost can break objects, and acid can damage armor. High level mages may learn and cast these spells as well. Be aware that area attacks are aggressive to all mobs in the room, including pets, mounts and charmed creatures. Gas breath is an area attack, the other breath spells are not. -------------------------Similiar Helpfiles in mage Index-------------------------- imm bodybag remove invis acid breath fire breath frost breath gas breath lightning breath ****************************************************************************************** Above is what you see with help frost breath. As you notice, the typical helpfile information comes up along with similiar helpfiles in that index (if that helpfile is in more than 1 index all indexes will show up). That brings us to another feature, multiple instances of a helpfile in different indexes. Say you have a skill that belongs in different classes, you are free to put that skill in both classes indexes. Also, there is a config called nosimiliar (config command) to remove the list of helpfiles and instead just show all indexes that are linked to that helpfile. Now that you have seen a good look of what it does, now time to get on with the business. ****************Step 1 - Setting up the Helpfile**************** You need to setup the helpfile to have all the helpfiles use the general group. To do this, follow the following directions ************************** ****File 1: Act_info.c**** ************************** Find the following lines in do_hset if ( str_cmp( arg1, "remove" ) ) argument = one_argument( argument, arg2 ); Directly above them add this if (!str_cmp(arg1, "prepareindex")) { FILE *fpout; log_string_plus("Preparing help index and backuping up help.are...", LOG_NORMAL, LEVEL_STAFF); /* Tracker1 */ send_to_char("&w&RIT IS VERY IMPORTANT that you remove this function from do_hset in act_info.c after use.\n\rAlso save your old helpfile (backuped to help.are.sbak) somewhere safe\n\r", ch); rename("help.are", "help.are.sbak"); fclose(fpReserve); if ((fpout = fopen("help.are", "w")) == NULL) { bug("hset save: fopen", 0); perror("help.are"); fpReserve = fopen(NULL_FILE, "r"); return; } fprintf(fpout, "#HELPS\n\n"); for (pHelp = first_help; pHelp; pHelp = pHelp->next) { fprintf(fpout, "%d %s~\n", pHelp->level, pHelp->keyword); fprintf(fpout, "#%s~\n", HINDEX_GENERAL_NAME); fprintf(fpout, "#END~\n%s~\n\n", help_fix(pHelp->text)); } fprintf(fpout, "0 $~\n\n\n#$\n"); fclose(fpout); fpReserve = fopen(NULL_FILE, "r"); send_to_char("Saved.\n\r", ch); return; } Now, do a make and then do a copyover/reboot. Once you login, you need to type the command hset prepareindex. This will prepare your helpfiles to start to use this system. It will also create a backup of your old helpfiles under the new name of help.are.sbak. I would put that file in a safe place for the time being. Now that this is done, DO NOT REBOOT, wait till you install the following code first. ****************Step 2 - Installing the Code**************** ************************** ****File 1: Act_info.c**** ************************** Find this near the top void show_condition args( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); Directly below it add this int showcollapse; Find do_help function void do_help(CHAR_DATA * ch, char *argument) Right above it add this //maxlength should not be over 25 char *add_wspace(int length, int maxlength) { int x = maxlength - length; static char wbuf[30]; strcpy(wbuf, ""); if (length >= maxlength) { return ""; } else { for(;;) { strcat(wbuf, " "); if (--x == 0) break; } } return wbuf; } Now, replace the whole do_help function you just found with this one void do_help(CHAR_DATA * ch, char *argument) { HELP_DATA *pHelp; HINDEX_DATA *hindex; HINDEX_POINTER *hpointer; HINDEX_IPOINTER *hipointer; HELP_DATA *ihelp; char helpfile[100]; char arg[MAX_INPUT_LENGTH]; int cnt; int nshow = 0; char *helpstring; one_argument(argument, arg); if (!str_cmp(arg, "_clean_")) { nshow = 1; argument = one_argument(argument, arg); } if ((pHelp = get_help(ch, argument)) == NULL) { pager_printf_color( ch, "&C&wNo help on \'%s\' found.\n\r", argument ); return; } /* Make newbies do a help start. --Shaddai */ if (!IS_NPC(ch) && !str_cmp(argument, "start")) SET_BIT(ch->pcdata->flags, PCFLAG_HELPSTART); if (pHelp->level >= 0 && str_cmp(argument, "imotd")) { send_to_pager(pHelp->keyword, ch); send_to_pager("\n\r", ch); } /* * Strip leading '.' to allow initial blanks. */ if (pHelp->text[0] == '.') send_to_pager_color(pHelp->text + 1, ch); else send_to_pager_color(pHelp->text, ch); //HelpIndex Code Below if (!xIS_SET(ch->act, PLR_NOSIMILIAR) && nshow == 0) { for (hpointer = pHelp->first_hindex; hpointer; hpointer = hpointer->next) { cnt = 0; hindex = hpointer->pointer; #ifdef HINDEX_MXP ch_printf(ch, "\n\r&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&CSimiliar Helpfiles in " MXPTAG ("hindex '%s'") "%s" MXPTAG ("/hindex") " Index&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-\n\r\n\r", hindex->keyword, hindex->keyword); #else ch_printf(ch, "\n\r&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&CSimiliar Helpfiles in %s Index&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-\n\r\n\r", hindex->keyword); #endif for (hipointer = hindex->first_help; hipointer; hipointer = hipointer->next) { ihelp = hipointer->pointer; helpstring = ihelp->keyword; for (;;) { if (helpstring[0] == '\0') break; else { helpstring = one_argument(helpstring, helpfile); if (cnt + strlen(helpfile) > 76) { send_to_char("\n\r", ch); cnt = 0; } #ifdef HINDEX_MXP ch_printf(ch, MXPTAG ("help '%s'") "&w&R%s" MXPTAG ("/help") " ", helpfile, helpfile); #else ch_printf(ch, "&w&R%s ", helpfile); #endif cnt+= strlen(helpfile) + 4; } } } send_to_char("\n\r", ch); } } else if (xIS_SET(ch->act, PLR_NOSIMILIAR) && nshow == 0) { cnt = 0; ch_printf(ch, "\n\r&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&CHelpIndex(es) for %s&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-\n\r\n\r", pHelp->keyword); for (hpointer = pHelp->first_hindex; hpointer; hpointer = hpointer->next) { hindex = hpointer->pointer; if (cnt + strlen(hindex->keyword) > 76) { send_to_char("\n\r", ch); cnt = 0; } #ifdef HINDEX_MXP ch_printf(ch, MXPTAG ("hindex '%s'") "&w&W%s" MXPTAG ("/hindex") " ", hindex->keyword, hindex->keyword); #else ch_printf(ch, "&w&W%s ", hindex->keyword); #endif cnt+= strlen(hindex->keyword) + 4; } send_to_char("\n\r", ch); } return; } In do_hedit find the following lines CREATE(pHelp, HELP_DATA, 1); pHelp->keyword = STRALLOC(strupper(argument)); pHelp->text = STRALLOC(""); pHelp->level = lev; Directly below add this //Add it into the general index... parse_helpfile_index(NULL, pHelp, HINDEX_GENERAL_NAME); Find the function do_hset down a little bit, replace the whole function with these functions below /* Used in hindex to do varius functions, it is controlled by the use value 0 - Show full map 1 - Search for a value 2 - Output for collapse */ HINDEX_DATA *hindex_search_function(int level, CHAR_DATA *ch, HINDEX_DATA *hindex, HINDEX_DATA *tindex, char *argument, int use) { char sbuf[200]; int cnt = 0; int ddown = 0; int dnext = 0; HINDEX_DATA *rvalue = NULL; if (use == 0) { strcpy(sbuf, ""); for (;;) { if (cnt < level) { strcat(sbuf, " "); } else break; cnt++; } #ifdef HINDEX_MXP ch_printf(ch, "%s" MXPTAG("hindex '%s'") "&w&W%s\n\r" MXPTAG("/hindex"), sbuf, hindex->keyword, hindex->keyword); #else ch_printf(ch, "&w&W%s%s\n\r", sbuf, hindex->keyword); #endif } if (use == 1) { if (!str_cmp(hindex->keyword, argument)) return hindex; } if (use == 2) { sprintf(sbuf, "%s collapse", hindex->keyword); do_hindex(ch, sbuf); } for (;;) { if (hindex->first_hindex && ddown == 0) { rvalue = hindex_search_function(level+1, ch, hindex->first_hindex, hindex, argument, use); if (rvalue && use == 1) return rvalue; ddown = 1; } else if (hindex->next && dnext == 0) { rvalue = hindex_search_function(level, ch, hindex->next, tindex, argument, use); if (rvalue && use == 1) return rvalue; dnext = 1; } else return rvalue; //Go back up a level or finally exit } } void do_hindex(CHAR_DATA * ch, char *argument) { HINDEX_DATA *hindex; HINDEX_DATA *oindex; HINDEX_IPOINTER *hipointer; HELP_DATA *help; int cnt = -1; char helpfile[100]; char *helpstring; char arg[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; if (argument[0] == '\0') { #ifdef HINDEX_MXP send_to_char("Syntax: " MXPTAG ("hindex toplevel")"hindex toplevel\n\r" MXPTAG ("/hindex"), ch); send_to_char("Syntax: hindex [nohfiles/collapse]\n\r", ch); send_to_char("Syntax: " MXPTAG ("hindex map")"hindex map\n\r" MXPTAG ("/hindex"), ch); send_to_char("Help hindex for more information\n\r", ch); #else send_to_char("Syntax: hindex toplevel\n\r", ch); send_to_char("Syntax: hindex [nohfiles/collapse]\n\r", ch); send_to_char("Syntax: hindex map\n\r", ch); send_to_char("Help hindex for more information\n\r", ch); #endif return; } argument = one_argument(argument, arg); if (!str_cmp(arg, "toplevel"))//Show only the top level indexes, no helpfiles { send_to_char("&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&CTop Level of the Index&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-\n\r", ch); for (hindex = first_hindex; hindex; hindex = hindex->next) { cnt++; if (cnt % 3 == 0) send_to_char("\n\r", ch); #ifdef HINDEX_MXP ch_printf(ch, MXPTAG ("hindex '%s'") "&w&R%s" MXPTAG ("/hindex") "%s", hindex->keyword, hindex->keyword, add_wspace(strlen(helpfile), 25)); #else ch_printf(ch, "&w&R%s%s", hindex->keyword, add_wspace(strlen(helpfile), 25)); #endif } send_to_char("\n\r", ch); return; } if (!str_cmp(arg, "map"))//Show a map of the index top to bottom { send_to_char("&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&CFull Map of the Index&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-\n\r", ch); hindex_search_function(0, ch, first_hindex, NULL, NULL, 0); //Need to do this because I need multiple variables to hold the loop return; } if ((hindex = hindex_search_function(0, ch, first_hindex, NULL, arg, 1)) != NULL) //Need to do this because I need multiple variables to hold the loop) { if (argument[0] == '\0') //do not collapse, show helpfiles { #ifdef HINDEX_MXP ch_printf(ch, "&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&CHelpfiles in " MXPTAG ("hindex '%s'") "%s" MXPTAG ("/hindex") " Index&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-\n\r", hindex->keyword, hindex->keyword); #else ch_printf(ch, "&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&CHelpfiles in %s Index&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-\n\r", hindex->keyword); #endif { for (hipointer = hindex->first_help; hipointer; hipointer = hipointer->next) { help = hipointer->pointer; helpstring = help->keyword; for (;;) { if (helpstring[0] == '\0') break; else { helpstring = one_argument(helpstring, helpfile); cnt++; if (cnt % 3 == 0) send_to_char("\n\r", ch); #ifdef HINDEX_MXP ch_printf(ch, MXPTAG ("help '%s'") "&w&R%s" MXPTAG ("/help") "%s", helpfile, helpfile, add_wspace(strlen(helpfile), 25)); #else ch_printf(ch, "&w&R%-25s ", helpfile); #endif } } } cnt = -1; ch_printf(ch, "\n\r\n\r&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&CIndexes Above %s&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-\n\r", hindex->keyword); for (oindex = hindex->first_top_hindex; oindex; oindex = oindex->tnext) { cnt++; if (cnt % 3 == 0) send_to_char("\n\r", ch); #ifdef HINDEX_MXP ch_printf(ch, MXPTAG ("hindex '%s'") "&c&w%s" MXPTAG ("/hindex") "%s", oindex->keyword, oindex->keyword, add_wspace(strlen(oindex->keyword), 25)); #else ch_printf(ch, "&c&w%s%s", oindex->keyword, add_wspace(strlen(oindex->keyword), 25)); #endif } cnt = -1; ch_printf(ch, "\n\r\n\r&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&CIndexes Below %s&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-\n\r", hindex->keyword); for (oindex = hindex->first_hindex; oindex; oindex = oindex->next) { cnt++; if (cnt % 3 == 0) send_to_char("\n\r", ch); #ifdef HINDEX_MXP ch_printf(ch, MXPTAG ("hindex '%s'") "&w&W%s" MXPTAG ("/hindex") "%s", oindex->keyword, oindex->keyword, add_wspace(strlen(oindex->keyword), 25)); #else ch_printf(ch, "&w&W%s%s", oindex->keyword, add_wspace(strlen(oindex->keyword), 25)); #endif } send_to_char("\n\r", ch); #ifdef HINDEX_MXP ch_printf(ch, "\n\r&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-"MXPTAG ("hindex map")"&w&CFull index" MXPTAG ("/hindex") " &w&Cabove/below %s &w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-\n\r", hindex->keyword, hindex->keyword); #endif return; } } argument = one_argument(argument, arg2); if ((!str_cmp(arg2, "nohfiles") && !str_cmp(argument, "collapse")) || (!str_cmp(arg2, "collapse") && !str_cmp(argument, "nohfiles"))) { send_to_char("You can only choose one, not both.\n\r", ch); return; } if (!str_cmp(arg2, "nohfiles")) //Show only the index { ch_printf(ch, "&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&W-&w&CFull Index Below %s&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-\n\r", hindex->keyword); hindex_search_function(0, ch, hindex, NULL, NULL, 0); } if (!str_cmp(arg2, "collapse")) //Show the complete index below this one + Helpfiles { if (showcollapse == 0) { ch_printf(ch, "&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&W-&w&CFull Index Below %s&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-\n\r", hindex->keyword); hindex_search_function(0, ch, hindex, NULL, NULL, 0); showcollapse = 1; hindex_search_function(0, ch, hindex, NULL, NULL, 2); showcollapse = 0; send_to_char("\n\r", ch); return; } else { cnt = -1; #ifdef HINDEX_MXP ch_printf(ch, "\n\r&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&CHelpfiles in " MXPTAG ("hindex '%s'") "%s" MXPTAG ("/hindex") " Index&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-\n\r", hindex->keyword, hindex->keyword); #else ch_printf(ch, "\n\r&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&CHelpfiles in %s Index&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-&w&W-&w&c-\n\r", hindex->keyword); #endif for (hipointer = hindex->first_help; hipointer; hipointer = hipointer->next) { help = hipointer->pointer; helpstring = help->keyword; for (;;) { if (helpstring[0] == '\0') break; else { helpstring = one_argument(helpstring, helpfile); cnt++; if (cnt % 3 == 0) send_to_char("\n\r", ch); #ifdef HINDEX_MXP ch_printf(ch, MXPTAG ("help '%s'") "&w&R%s" MXPTAG ("/help") "%s", helpfile, helpfile, add_wspace(strlen(helpfile), 25)); #else ch_printf(ch, "&w&R%-25s ", helpfile); #endif } } } send_to_char("\n\r", ch); return; } } } else { send_to_char("That is not an available index, if you cannot find one, view them all with hindex map.\n\r", ch); return; } } HINDEX_DATA *get_hindex_name(char *argument, HELP_DATA *help) { char index[100]; HINDEX_DATA *hindex = NULL; HINDEX_POINTER *hpointer; for (;;) //Get the index's name { argument = one_argument(argument, index); if (argument[0] == '\0') break; } for (hpointer = help->first_hindex; hpointer; hpointer = hpointer->next) { if (!str_cmp(hpointer->pointer->keyword, index)) { hindex = hpointer->pointer; break; } } if (!hindex) { bug("Hindex %s in helpfile %s is invalid", index, help->keyword); return NULL; } return hindex; } HINDEX_POINTER *get_hindex_pointer(HINDEX_DATA *hindex, HINDEX_POINTER *first) { HINDEX_POINTER *hpointer; for (hpointer = first; hpointer; hpointer = hpointer->next) { if (hpointer->pointer == hindex) break; } if (!hpointer) { bug("hpointer error in helpfile %s", hindex->keyword); return NULL; } return hpointer; } void do_hset(CHAR_DATA * ch, char *argument) { HELP_DATA *pHelp; HINDEX_NAME *hname; HINDEX_POINTER *hpointer = NULL; HINDEX_POINTER *chpointer = NULL; HINDEX_IPOINTER *hipointer; char buf[300]; char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char arg3[MAX_INPUT_LENGTH]; char arg4[MAX_INPUT_LENGTH]; smash_tilde(argument); argument = one_argument(argument, arg1); if (arg1[0] == '\0') { send_to_char("Syntax: hset [value] [help page]\n\r", ch); send_to_char("\n\r", ch); send_to_char("Field being one of:\n\r", ch); send_to_char(" level keyword remove save\n\r", ch); send_to_char("------------------------------------------------\n\r", ch); send_to_char("Syntax: hset hindex view\n\r", ch); send_to_char("Syntax: hset hindex place \n\r", ch); send_to_char("Syntax: hset hindex create \n\r", ch); send_to_char("Syntax: hset hindex delete \n\r", ch); send_to_char("Syntax: hset hindex shift \n\r", ch); send_to_char("Syntax: hset hindex crosslink \n\r", ch); send_to_char("------------------------------------------------\n\r", ch); return; } if (!str_cmp(arg1, "hindex")) { HINDEX_DATA *hindex; HINDEX_DATA *chindex; HINDEX_NAME *chname; int value = 0; int cnt = 1; argument = one_argument(argument, arg2); argument = one_argument(argument, arg3); if (!str_cmp(arg2, "crosslink")) { for (hindex = first_fhindex; hindex; hindex = hindex->fnext) { if (!str_cmp(arg3, hindex->keyword)) break; } if (!hindex) { ch_printf(ch, "%s does not exist as an index.\n\r", arg3); } for (chindex = first_fhindex; chindex; chindex = chindex->fnext) { if (!str_cmp(argument, chindex->keyword)) break; } if (!chindex) { ch_printf(ch, "%s does not exist as an index.\n\r", argument); } LINK(chindex, hindex->first_hindex, hindex->last_hindex, next, prev); LINK(hindex, chindex->first_top_hindex, chindex->last_top_hindex, tnext, tprev); ch_printf(ch, "%s has been linked below %s, might check hindex map to make sure it doesn't loop.\n\r", argument, arg3); return; } if ((pHelp = get_help(ch, arg2)) == NULL) { send_to_char("There is no helpfile available by that name.\n\r", ch); return; } if (!str_cmp(arg3, "view")) //Limited information compared to hindex, mainly to get the number for delete { for (hname = pHelp->first_iname; hname; hname = hname->next) { ch_printf(ch, "%-2d> %s\n\r", cnt++, hname->name); } return; } if (!str_cmp(arg3, "create")) //Cannot exist, will create a new one :-) { sprintf(buf, argument); for (;;) { argument = one_argument(argument, arg4); if (argument[0] != '\0') continue; else //time to do a name check to make sure it exists { for (hindex = first_fhindex; hindex; hindex = hindex->fnext) { if (!str_cmp(arg4, hindex->keyword))//Alright can add this helpfile now { ch_printf(ch, "%s already exists and therefore cannot be created\n\r", arg4); return; } } if (!hindex) { argument = &buf[0]; parse_helpfile_index(NULL, pHelp, argument); ch_printf(ch, "%s has been created and %s added to it!\n\r", arg4, arg2); return; } } } } if (!str_cmp(arg3, "place")) //Has to exist, mainly for error checking and level seperation for the two... { sprintf(buf, argument); for (;;) { argument = one_argument(argument, arg4); if (argument[0] != '\0') continue; else //time to do a name check to make sure it exists { for (hindex = first_fhindex; hindex; hindex = hindex->fnext) { if (!str_cmp(arg4, hindex->keyword))//Alright can add this helpfile now { CREATE(hipointer, HINDEX_IPOINTER, 1); hipointer->pointer = pHelp; LINK(hipointer, hindex->first_help, hindex->last_help, next, prev); CREATE(hpointer, HINDEX_POINTER, 1); hpointer->pointer = hindex; LINK(hpointer, pHelp->first_hindex, pHelp->last_hindex, next, prev); CREATE(hname, HINDEX_NAME, 1); hname->name = STRALLOC(buf); LINK(hname, pHelp->first_iname, pHelp->last_iname, next, prev); ch_printf(ch, "%s has been placed in %s\n\r", arg2, arg4); return; } } if (!hindex) { ch_printf(ch, "%s is an index that does not exist\n\r", arg4); return; } } } } argument = one_argument(argument, arg4); if (!str_cmp(arg3, "shift")) //Shift the help index up/down on a helpfile { value = atoi(arg4); if (!value) { send_to_char("You need to specify the number listed in view.\n\r", ch); return; } cnt = 1; if (!str_cmp(argument, "down")) { value = 0; for (hname = pHelp->first_iname; hname; hname = hname->next) { value++; } if (atoi(arg4) == value) { send_to_char("You cannot shift that down, it is at the bottom.\n\r", ch); return; } value = atoi(arg4); for (hname = pHelp->first_iname; hname; hname = hname->next) { if (cnt++ == value) { if ((hindex = get_hindex_name(hname->name, pHelp)) == NULL) { send_to_char("There was a bug, notify an immortal if one doesn't know already.\n\r", ch); return; } if ((hpointer = get_hindex_pointer(hindex, pHelp->first_hindex)) == NULL) { send_to_char("There was a bug, notify an immortal if one doesn't know already.\n\r", ch); return; } break; } } if (!hname) { ch_printf(ch, "That is not in the valid range.\n\r", ch); return; } cnt = 1; for (chname = pHelp->first_iname; chname; chname = chname->next) { if (cnt++ == value+1) { if ((chindex = get_hindex_name(chname->name, pHelp)) == NULL) { send_to_char("There was a bug, notify an immortal if one doesn't know already.\n\r", ch); return; } if ((chpointer = get_hindex_pointer(chindex, pHelp->first_hindex)) == NULL) { send_to_char("There was a bug, notify an immortal if one doesn't know already.\n\r", ch); return; } break; } } if (!hname) { ch_printf(ch, "That is not in the valid range.\n\r", ch); return; } SHIFT_DOWN(hname, chname, pHelp->last_iname); SHIFT_DOWN(hpointer, chpointer, pHelp->last_hindex); ch_printf(ch, "%d is shifted below %d.\n\r", value, value+1); return; } if (!str_cmp(argument, "up")) { if (value == 1) { ch_printf(ch, "You cannot shift that up, it is number 1 in the list.\n\r", ch); return; } for (hname = pHelp->first_iname; hname; hname = hname->next) { if (cnt++ == value) { if ((hindex = get_hindex_name(hname->name, pHelp)) == NULL) { send_to_char("There was a bug, notify an immortal if one doesn't know already.\n\r", ch); return; } if ((hpointer = get_hindex_pointer(hindex, pHelp->first_hindex)) == NULL) { send_to_char("There was a bug, notify an immortal if one doesn't know already.\n\r", ch); return; } break; } } if (!hname) { ch_printf(ch, "That is not in the valid range.\n\r", ch); return; } cnt = 1; for (chname = pHelp->first_iname; chname; chname = chname->next) { if (cnt++ == value-1) { if ((chindex = get_hindex_name(chname->name, pHelp)) == NULL) { send_to_char("There was a bug, notify an immortal if one doesn't know already.\n\r", ch); return; } if ((chpointer = get_hindex_pointer(chindex, pHelp->first_hindex)) == NULL) { send_to_char("There was a bug, notify an immortal if one doesn't know already.\n\r", ch); return; } break; } } if (!chname) { ch_printf(ch, "That is not in the valid range.\n\r", ch); return; } SHIFT_UP(hname, chname, pHelp->first_iname); SHIFT_UP(hpointer, chpointer, pHelp->first_hindex); /* if (pHelp->first_iname == chname) pHelp->first_iname = hname; hname->next = chname->next; if (hname->next) hname->next->prev = hname; chname->prev = hname->prev; if (chname->prev) chname->prev->next = chname; hname->prev = chname; chname->next = hname; */ ch_printf(ch, "%d is shifted above %d.\n\r", value, value-1); return; } } if (!str_cmp(arg3, "delete")) { for (hname = pHelp->first_iname; hname; hname = hname->next) { if (cnt++ == atoi(arg4)) //Delete out this hindex from the helpfile, it DOES NOT delete the hindex. Reboot/copyover to do this { hindex = get_hindex_name(hname->name, pHelp); if (!hindex) { send_to_char("There was a bug, notify an immortal if one doesn't know already.\n\r", ch); return; } for (hpointer = pHelp->first_hindex; hpointer; hpointer = hpointer->next) { if (hpointer->pointer == hindex) { break; } } if (!hpointer) { bug("Helpfile %s is not pointing correctly to a hindex", pHelp->keyword); send_to_char("There was a bug, notify an immortal if one doesn't know already.\n\r", ch); return; } for (hipointer = hindex->first_help; hipointer; hipointer = hipointer->next) { if (hipointer->pointer == pHelp) { break; } } if (!hipointer) { bug("Helpfile %s is not showing up in a hindex", pHelp->keyword); send_to_char("There was a bug, notify an immortal if one doesn't know already.\n\r", ch); return; } ch_printf(ch, "%s was removed from the helpfile and the helpfile from the index.\n\r", hname->name); UNLINK(hipointer, hindex->first_help, hindex->last_help, next, prev); UNLINK(hpointer, pHelp->first_hindex, pHelp->last_hindex, next, prev); STRFREE(hname->name); UNLINK(hname, pHelp->first_iname, pHelp->last_iname, next, prev); return; } } send_to_char("That is not a valid number.\n\r", ch); return; } } if (!str_cmp(arg1, "save")) { FILE *fpout; log_string_plus("Saving help.are...", LOG_NORMAL, LEVEL_STAFF); /* Tracker1 */ rename("help.are", "help.are.bak"); fclose(fpReserve); if ((fpout = fopen("help.are", "w")) == NULL) { bug("hset save: fopen", 0); perror("help.are"); fpReserve = fopen(NULL_FILE, "r"); return; } fprintf(fpout, "#HELPS\n\n"); for (pHelp = first_help; pHelp; pHelp = pHelp->next) { fprintf(fpout, "%d %s~\n", pHelp->level, pHelp->keyword); if (!pHelp->first_iname) fprintf(fpout, "#%s~\n", HINDEX_GENERAL_NAME); else { for (hname = pHelp->first_iname; hname; hname = hname->next) fprintf(fpout, "#%s~\n", hname->name); } fprintf(fpout, "#END~\n%s~\n\n", help_fix(pHelp->text)); } fprintf(fpout, "0 $~\n\n\n#$\n"); fclose(fpout); fpReserve = fopen(NULL_FILE, "r"); send_to_char("Saved.\n\r", ch); return; } if (str_cmp(arg1, "remove")) argument = one_argument(argument, arg2); if ((pHelp = get_help(ch, argument)) == NULL) { send_to_char("Cannot find help on that subject.\n\r", ch); return; } if (!str_cmp(arg1, "remove")) { UNLINK(pHelp, first_help, last_help, next, prev); STRFREE(pHelp->text); STRFREE(pHelp->keyword); DISPOSE(pHelp); send_to_char("Removed.\n\r", ch); return; } if (!str_cmp(arg1, "level")) { pHelp->level = atoi(arg2); send_to_char("Done.\n\r", ch); return; } if (!str_cmp(arg1, "keyword")) { STRFREE(pHelp->keyword); pHelp->keyword = STRALLOC(strupper(arg2)); send_to_char("Done.\n\r", ch); return; } do_hset(ch, ""); } Now find the following lines in do_config set_char_color(AT_DGREEN, ch); send_to_char("\n\r\n\rSettings: ", ch); Right before them add this (Note: I put this on an empty line, format it to your liking later) ch_printf(ch, "\n\r%-12s", xIS_SET(ch->act, PLR_NOSIMILIAR) ? "[+] SHORTHELP" : "[-] shorthelp"); Find this down a bit more bit = PLR_COMBINE; else if (!str_cmp(arg + 1, "prompt")) bit = PLR_PROMPT; Below that add the following else if (!str_cmp(arg + 1, "shorthelp")) bit = PLR_NOSIMILIAR; *********************** ****File 2: Build.c**** *********************** Find this in build.c litterbug This is the list of act flags, at the very end of the list - before the }; - Add the following , "nofamiliar" Make sure to put that after the last item and before the ); ********************** ****File 3: Comm.c**** ********************** If you are going to be using MXP AND you have installed Gammon's snippet support, find the following in comm.c /* List an item tag (for things in a shop) */ write_to_buffer( d, MXPTAG ("!ELEMENT List \"\" " "ATT='name'"), 0); // Click on a help index to view it write_to_buffer( d, MXPTAG ("!ELEMENT Hindex \"\" " "ATT='name'"), 0); Next, this might be tricky, laugh. Any do_help call in comm.c or anywhere else that you don't want to show any of the index information (like motd) you need to do this do_help(ch, "_clean_ motd"); All you need to do is add _clean_ before the keyword. You don't have to add that helpfile (you shouldn't). You will want to search for motd amotd imotd and nmotd and do similiar things to them. ******************** ****File 4: Db.c**** ******************** Find this near the top of db.c HELP_DATA *first_help; HELP_DATA *last_help; Right Below it add this HINDEX_DATA *first_hindex; HINDEX_DATA *last_hindex; HINDEX_DATA *first_fhindex; //First flat hindex HINDEX_DATA *last_fhindex; //Last flat hindex Find the function load_helps, replace it with the following functions int parse_helpfile_index(FILE *fp, HELP_DATA *pHelp, char *argument) { HINDEX_DATA * hindex = NULL; HINDEX_DATA * hindex2; HINDEX_DATA *findex; HINDEX_NAME * hiname; HINDEX_POINTER *hpointer; HINDEX_IPOINTER *hipointer; HELP_DATA *help; char keyword[100]; char fullkeyword[200]; int value = 0; char *keystring; //if there is a file pointer, then it is being read from file, if not, it is being used in hset if (fp) { keystring = fread_string(fp); if (keystring[0] != '#') return 1; keystring++; //advance past the # sprintf(fullkeyword, "%s", keystring); keystring = one_argument(keystring, keyword); if (!str_cmp(keyword, "END")) return 0; } else { sprintf(fullkeyword, argument); keystring = argument; keystring = one_argument(keystring, keyword); } CREATE(hiname, HINDEX_NAME, 1); hiname->name = STRALLOC(fullkeyword); LINK(hiname, pHelp->first_iname, pHelp->last_iname, next, prev); if (!first_hindex) { CREATE(hindex, HINDEX_DATA, 1); hindex->keyword = STRALLOC(keyword); hindex->first_help = NULL; hindex->last_help = NULL; hindex->first_hindex = NULL; hindex->last_hindex = NULL; LINK(hindex, first_hindex, last_hindex, next, prev); LINK(hindex, first_fhindex, last_fhindex, fnext, fprev); } if (keystring[0] == '\0') //Only was one keyword, no need to start looping through the keywords { if (!hindex) { for (hindex = first_hindex; hindex; hindex = hindex->next) { if (!str_cmp(hindex->keyword, keyword)) break; } if (!hindex) { for (findex = first_fhindex; findex; findex = findex->fnext) { if (!str_cmp(findex->keyword, keyword)) break; } if (!findex) { CREATE(hindex, HINDEX_DATA, 1); hindex->keyword = STRALLOC(keyword); hindex->first_help = NULL; hindex->last_help = NULL; hindex->first_hindex = NULL; hindex->last_hindex = NULL; } else hindex = findex; LINK(hindex, first_hindex, last_hindex, next, prev); LINK(hindex, first_fhindex, last_fhindex, fnext, fprev); } } if (!hindex->first_help) { CREATE(hipointer, HINDEX_IPOINTER, 1); hipointer->pointer = pHelp; LINK(hipointer, hindex->first_help, hindex->last_help, next, prev); CREATE(hpointer, HINDEX_POINTER, 1); hpointer->pointer = hindex; LINK(hpointer, pHelp->first_hindex, pHelp->last_hindex, next, prev); } else { for (hipointer = hindex->first_help; hipointer; hipointer = hipointer->next) { help = hipointer->pointer; if (!str_cmp(pHelp->keyword, help->keyword)) // Same helpfile break; } if (!hipointer) { CREATE(hipointer, HINDEX_IPOINTER, 1); hipointer->pointer = pHelp; LINK(hipointer, hindex->first_help, hindex->last_help, next, prev); CREATE(hpointer, HINDEX_POINTER, 1); hpointer->pointer = hindex; LINK(hpointer, pHelp->first_hindex, pHelp->last_hindex, next, prev); } } if (argument) return 1; //another round... value = parse_helpfile_index(fp, pHelp, NULL); return value; //once it reaches a value it will loop back out and return that value } //Will never reach this loop unless there are more than 1 keyword..... for (hindex = first_hindex; hindex; hindex = hindex->next) { if (!hindex->next && str_cmp(keyword, hindex->keyword)) //don't want to break out of this loop just yet... { for (findex = first_fhindex; findex; findex = findex->fnext) { if (!str_cmp(findex->keyword, keyword)) break; } if (!findex) { CREATE(hindex2, HINDEX_DATA, 1); hindex2->keyword = STRALLOC(keyword); hindex2->first_help = NULL; hindex2->last_help = NULL; hindex2->first_hindex = NULL; hindex2->last_hindex = NULL; hindex2->first_top_hindex = NULL; hindex2->last_top_hindex = NULL; } else hindex2 = findex; LINK(hindex2, first_hindex, last_hindex, next, prev); LINK(hindex2, first_fhindex, last_fhindex, fnext, fprev); hindex = hindex2; } if (!str_cmp(keyword, hindex->keyword)) { for (;;) { keystring = one_argument(keystring, keyword); if (keyword[0] == '\0') { if (!hindex->first_help) { CREATE(hipointer, HINDEX_IPOINTER, 1); hipointer->pointer = pHelp; LINK(hipointer, hindex->first_help, hindex->last_help, next, prev); CREATE(hpointer, HINDEX_POINTER, 1); hpointer->pointer = hindex; LINK(hpointer, pHelp->first_hindex, pHelp->last_hindex, next, prev); } else { for (hipointer = hindex->first_help; hipointer; hipointer = hipointer->next) { help = hipointer->pointer; if (!str_cmp(pHelp->keyword, help->keyword)) // Same helpfile { break; } } if (!hipointer) { CREATE(hipointer, HINDEX_IPOINTER, 1); hipointer->pointer = pHelp; LINK(hipointer, hindex->first_help, hindex->last_help, next, prev); CREATE(hpointer, HINDEX_POINTER, 1); hpointer->pointer = hindex; LINK(hpointer, pHelp->first_hindex, pHelp->last_hindex, next, prev); } } break; } if (!hindex->first_hindex) { for (findex = first_fhindex; findex; findex = findex->fnext) { if (!str_cmp(findex->keyword, keyword)) break; } if (!findex) { CREATE(hindex2, HINDEX_DATA, 1); hindex2->keyword = STRALLOC(keyword); hindex2->first_help = NULL; hindex2->last_help = NULL; hindex2->first_hindex = NULL; hindex2->last_hindex = NULL; hindex2->first_top_hindex = NULL; hindex2->last_top_hindex = NULL; } else hindex2 = findex; LINK(hindex2, hindex->first_hindex, hindex->last_hindex, next, prev); LINK(hindex, hindex2->first_top_hindex, hindex2->last_top_hindex, tnext, tprev); LINK(hindex2, first_fhindex, last_fhindex, fnext, fprev); } for (hindex2 = hindex->first_hindex; hindex2; hindex2 = hindex2->next) { if (!str_cmp(keyword, hindex2->keyword)) break; } if (!hindex2) { for (findex = first_fhindex; findex; findex = findex->fnext) { if (!str_cmp(findex->keyword, keyword)) break; } if (!findex) { CREATE(hindex2, HINDEX_DATA, 1); hindex2->keyword = STRALLOC(keyword); hindex2->first_help = NULL; hindex2->last_help = NULL; hindex2->first_hindex = NULL; hindex2->last_hindex = NULL; hindex2->first_top_hindex = NULL; hindex2->last_top_hindex = NULL; } else hindex2 = findex; LINK(hindex2, hindex->first_hindex, hindex->last_hindex, next, prev); LINK(hindex, hindex2->first_top_hindex, hindex2->last_top_hindex, tnext, tprev); LINK(hindex2, first_fhindex, last_fhindex, fnext, fprev); } hindex = hindex2; //So this can go in an infinite loop theoretically } break; } } //another round... if (argument) return 1; value = parse_helpfile_index(fp, pHelp, NULL); return value; //once it reaches a value it will loop back out and return that value } /* * Load a help section. */ void load_helps(AREA_DATA * tarea, FILE * fp) { HELP_DATA *pHelp; for (;;) { CREATE(pHelp, HELP_DATA, 1); pHelp->first_hindex = NULL; pHelp->last_hindex = NULL; pHelp->level = fread_number(fp); pHelp->keyword = fread_string(fp); pHelp->first_iname = NULL; pHelp->last_hindex = NULL; if (pHelp->keyword[0] == '$') { STRFREE(pHelp->keyword); DISPOSE(pHelp); break; } //Parses and creates the helpfile index if (parse_helpfile_index(fp, pHelp, NULL) == 1) { bug("%s has no hindex, exiting!!!!!", pHelp->keyword); STRFREE(pHelp->keyword); DISPOSE(pHelp); exit(0); } pHelp->text = fread_string(fp); if (pHelp->keyword[0] == '\0') { STRFREE(pHelp->text); STRFREE(pHelp->keyword); DISPOSE(pHelp); continue; } if (!str_cmp(pHelp->keyword, "greeting")) help_greeting = pHelp->text; add_help(pHelp); } return; } ********************* ****File 5: Mud.h**** ********************* Find these near the top typedef struct descriptor_data DESCRIPTOR_DATA; typedef struct exit_data EXIT_DATA; typedef struct extra_descr_data EXTRA_DESCR_DATA; Directly below it add this typedef struct help_index_data HINDEX_DATA; typedef struct help_data_pointer HINDEX_POINTER; typedef struct help_index_pointer HINDEX_IPOINTER; typedef struct help_index_name HINDEX_NAME; Find This MAX_LAYERS Above it add #define HINDEX_GENERAL_NAME "General" //Uncomment this below to turn on MXP support for hindex code //#define HINDEX_MXP Note uncomment the HINDEX_MXP (remove the //) if you plan on using MXP and installed it back in comm.c. Find this structure down some struct help_data Replace the structure with these structures /* * Help Index Table */ struct help_index_data { char *keyword; HINDEX_DATA *next; //Next index HINDEX_DATA *prev; //Prev index HINDEX_DATA *fnext; //next flat index HINDEX_DATA *fprev; //prev flat index HINDEX_DATA *tnext; //Next index at the top level HINDEX_DATA *tprev; //Prev index at the top level HINDEX_DATA *first_hindex; //First index below this one HINDEX_DATA *last_hindex; //Last index below this one HINDEX_DATA *first_top_hindex; //First index above this one HINDEX_DATA *last_top_hindex; //Last index below this one HINDEX_IPOINTER *first_help; //First helpfile in this index HINDEX_IPOINTER *last_help; //Last helpfile in this index }; //Points back to help index data since I need to store this data on every helpfile.... struct help_data_pointer { HINDEX_POINTER *next; HINDEX_POINTER *prev; HINDEX_DATA *pointer; }; //Points back to the help data since I need to store this data on every index.... struct help_index_pointer { HINDEX_IPOINTER *next; HINDEX_IPOINTER *prev; HELP_DATA *pointer; }; //Used to store the actual groups on a helpfile since it is really hard to track them back... struct help_index_name { HINDEX_NAME *next; HINDEX_NAME *prev; char *name; }; /* * Help table types. */ struct help_data { HELP_DATA *next; HELP_DATA *prev; HINDEX_POINTER *first_hindex; //First index structure helpfile is in HINDEX_POINTER *last_hindex; //Last index structure helpfile is in sh_int level; char *keyword; HINDEX_NAME *first_iname; HINDEX_NAME *last_iname; char *text; }; Find the following PLR FLAG PLR_LITTERBUG At the end of that list, add this (make sure it is before the } player_flags; and there is a comma added after the item right before it) PLR_NOSIMILIAR Find #define INSERT Above it add the following //Shifts a link down one spot... #define SHIFT_DOWN(slink, olink, last) \ do \ { \ if ( (last) == (olink) ) \ (last) = (slink); \ \ (olink)->prev = (slink)->prev; \ if ((olink)->prev) \ (olink)->prev->next = (olink); \ (slink)->next = (olink)->next; \ if ((slink)->next) \ (slink)->next->prev = (slink); \ \ (olink)->next = (slink); \ (slink)->prev = (olink); \ } while(0) //Shifts a link up one spot... #define SHIFT_UP(slink, olink, first) \ do \ { \ if ((first) == (olink)) \ (first) = (slink); \ \ (slink)->prev = (olink)->prev; \ if ((slink)->prev) \ (slink)->prev->next = (slink); \ (olink)->next = (slink)->next; \ if ((olink)->next) \ (olink)->next->prev = (olink); \ \ (slink)->next = (olink); \ (olink)->prev = (slink); \ } while(0) Find the following down below extern HELP_DATA *first_help; extern HELP_DATA *last_help; Add the following below those two lines extern HINDEX_DATA *first_hindex; extern HINDEX_DATA *last_hindex; extern HINDEX_DATA *first_fhindex; //Flat help index extern HINDEX_DATA *last_fhindex; //Flag help index Find this comment down below /* db.c */ In the db.c function declaration list, add this int parse_helpfile_index args((FILE *fp, HELP_DATA *pHelp, char *argument)); ****************Step 3 - Compile and Setup**************** Once you are done with that, you need to add do_hindex into mud.h and tables.c. After that, do a make clean (note a make clean not a make) and hope to god it compiles fine! Once it does, you are ready to reboot/copyover your mud. Once you do that, create the hedit command cedit hedit create do_hedit cedit hedit level 1 cedit save cmdtable If you type hindex map now, you will notice you have only the General group. Also, you will notice if you do a help on any file in that group, you will get booted. This is because it is trying to show thousands of helpfiles and I don't have this setup to run on pager. So, you need to seperate the helpfiles out. This file is getting long enough, so I am going to break it up into a few more. Just read these files to get more information hindexhelpediting.txt - Instructions on how to alter helpfiles offline and online. hindex.help - Help files to add for hindex :-) hindextweeks.txt - Small changes you can add so you can have the code in while you alter files online/offline