/************************************************************ * SPECSET.C * Code to assign special procedures on the fly * Syntax: Specset * * Written by L. Raymond * Comments to raymond@brokerys.com * * The code in this file and the accompanying header makes it * as easy to assign a special procedure to a room, object or * mob as it is to GOTO someplace. With minor alterations to * existing code these specs can be saved to disk and restored * at bootup or, if you prefer not to change anything, they'll * be temporary and exist only until the next reboot. * * Changes required to save to disk (details follow): * * Add a new int to the structures index_data and room_data: * int specproc * In DB.C: * - add a new case to parse_room, parse_object and parse_mobile * - have boot_db() call assign_spec_procs () anytime after * boot_world() [syntax: assign_spec_procs (0,0,0,1);] * In your OLC code, make whatever changes are needed to save * the spec. (I'll outline my way below) * * The functions: * * ACMD (do_specset) * The main function. This asigns the proper integer to * mob_index.specnum, obj_index.specnum or world.specnum then * calls assign_spec_procs () to attach the actual function. * If you choose not to save to disk, this function will need * to be altered to handle the function assignment directly. * * void assign_spec_procs * (char type, sh_int vnum, int which, char startup); * This function uses the information you provide in the various * specproc_info structs (defined in this file) to assign * the functions. In case of error, it just sets the function * pointer to NULL. If startup = 1 then it will loop through * the entire mob, object and world tables and assign the * functions specified by the specnum int. This function will * not be required if you choose not to save to disk and * edit specset to handle the assignments. * * void get_spec_name (int i, char *specname, char type); * This returns a name for each spec. proc. I use it in the * various do_stat functions and the speclist report. Esentially * cosmetic, but very handy. * * void do_initial_specs(void); * Called by assign_spec_proc when startup=1. This is what * does the actual looping through the tables. * * void display_spec_options(struct char_data* ch); * Displays a numbered list of specs for reference. Typing * SPECSET with no paramters displays this list. * * ACMD(do_speclist) * This is just a report function that will list every mob, object or * room with a special procedure attached to it, telling you what the * spec proc is. * * Saving to disk * * No matter what code you use for OLC, when it comes to saving the * info the output file is pretty much the same, so all you need to * do is add another line to the save function for mobs, objects and * rooms. I decided to designate spec procs with a "P", so mobs * are saved like this: * * [last 4 lines of my mob_save_to_disk] * if (GET_CON(mob) != 11) fprintf(mob_file, "Con: %d\n", GET_CON(mob)); * if (GET_CHA(mob) != 11) fprintf(mob_file, "Cha: %d\n", GET_CHA(mob)); * if (GET_NUM_ATTACKS(mob) > 1) * fprintf(mob_file, "Att: %d\n", GET_NUM_ATTACKS(mob)); * if (mob_index[GET_MOB_RNUM(mob)].specproc>0) * fprintf(mob_file,"P: %d\r\n",mob_index[GET_MOB_RNUM(mob)].specproc); * * In db.c's parse_mobile() I added this line to the switch statement: * * case 'S': // Simple monsters * parse_simple_mob(mob_f, i, nr); * break; * case 'E': // Circle3 Enhanced monsters * parse_enhanced_mob(mob_f, i, nr); * break; * case 'P': //spec_proc. * get_line(mob_f, line); * if ((j=atoi(line)) <0) * { * sprintf(buf,"SYSERR(DB71): Format error in mob #%d's Spec Proc\n", nr); * log (buf); * exit(1); * } * else mob_index[i].specproc=j; * break; * * Do the same for rooms and objects, editing your various save_to_disk * and boot up routines. After the boot up is complete, call * assign_spec_procs(), specifying startup=1,and it will use this info * to make the actual function assignments. * * Using get_spec_name () * * Add this to your various do_stat functions to get output * that tells you what spec. proc is assigned. Example: * Name: 'a cashcard', Aliases: cashcard card atm * VNum: [ 3036], RNum: [ 83], Type: OTHER SpecProc: (Bank) * * For this output, edit do_stat_object and replace the code which * prints "Exists" with this: * * if (obj_index[GET_OBJ_RNUM(j)].func!=NULL) * get_spec_name(GET_OBJ_RNUM(j), buf2, 'o'); * else sprintf(buf2,"none"); * sprintf(buf, "SpecProc: (%s%s%s)\r\n",CCGRNB(ch, C_NRM),buf2,CCNRM(ch, C_NRM)); * send_to_char(buf, ch); * * Be sure to remove the color codes if needed. This is also * how to change do_stat_character and do_stat_room; just change * the 'o' to 'm' or 'r' as needed in get_spec_name. * * ************************************************************/