Expanding classes / races in Circle Mud. (USING OASIS OLC) OasisOLC written by Harvey Gilpin. AUTHOR: TOOIE: Email: Zyrenthian@home.com WARNING: THIS REQUIRES MODIFYING THE OBJECT FILES IN "lib/world/obj" BUT ASK YOURSELF... DO I WANT UP TO 32 RACES, CLASSES, AND OBJECT FLAGS? AS YOU CAN GUESS... MY ANSWER WAS YES :) DISCLAIMER: THIS WORKED FOR ME WITH MY CURRENT SETUP OF THE MUD. I DON'T KNOW ANY MODIFICATIONS YOU MAY HAVE MADE AND IN NO WAY WILL I BE HELD RESPONSIBLE FOR ANY PROBLEMS THIS CAUSES. SO... ************************************************************************** BACK UP YOUR FILES BEFORE DOING THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ************************************************************************** APOLOGY: IF I FORGOT ANYTHING, PLEASE LET ME KNOW BUT I'M PRETTY SURE I GOT IT ALL NOTE: IF anti_class/race_bits are not defined, extern em!!!! (just incase I forget to mention it somewhere) If you're anything like me, you want a lot of races and classes to offer diversity. Well, I know there are other ways of modifying the code but this is how I did it. You will need to edit the following files. act.wizard.c class.c constants.c constants.h db.c objsasve.c oedit.c olc.h shop.c spells.c structs.h utils.h ALL of the object files (this is the tedious part) *** please see below for a possible way around going into obj files*** ACT.WIZARD.C ------------ in the function: do_stat_object add the following below send_to_char("Extra flags : ", ch); sprintbit(GET_OBJ_EXTRA(j), extra_bits, buf); strcat(buf, "\r\n"); send_to_char(buf, ch); /****** NEW CODE ******/ send_to_char("!Class flags : ", ch); sprintbit(GET_OBJ_ANTIC(j), anti_class_bits, buf); strcat(buf, "\r\n"); send_to_char(buf, ch); send_to_char("!Race flags : ", ch); sprintbit(GET_OBJ_ANTIR(j), anti_race_bits, buf); strcat(buf, "\r\n"); send_to_char(buf, ch); Also please check if "constants.h" is included at the top. /****** END NEW CODE ******/ CLASS.C ------- /**** NEW ****/ int invalid_class change the IS_OBJ_STAT to IS_OBJ_STATC int invalid_race change the IS_OBJ_STAT to IS_OBJ_STATR /**** END ****/ CONSTANTS.C ----------- Below const char *extra_bits[] = { ... "\n" }; /****** NEW CODE ******/ const char *anti_class_bits[] = { "!MAGE", "!CLERIC", "!THIEF", "!WARRIOR", "\n" }; const char *anti_race_bits[] = { "!HUMAN", "!ELF", ... "\n" }; /******* END NEW CODE ********/ CONSTANTS.H ----------- add the following 2 lines (anywhere) /****** NEW CODE ******/ extern const char *anti_race_bits[]; extern const char *anti_class_bits[]; /******* END NEW CODE ********/ DB.C ---- int the function char *parse_object below obj_proto[i].obj_flags.weight = t[0]; obj_proto[i].obj_flags.cost = t[1]; obj_proto[i].obj_flags.cost_per_day = t[2]; and above /* check to make sure that weight of containers exceeds curr. quantity */ add the following /******* NEW CODE ******/ if (!get_line(obj_f, line)) { log("SYSERR: Expecting fourth numeric line of %s, but file ended!", buf2); exit(1); } if ((retval = sscanf(line, "%d %d", t, t + 1)) != 2) { log("SYSERR: Format error in second numeric line (expecting 2 args, got %d), %s", retval, buf2); exit(1); } obj_proto[i].obj_flags.anti_class_flags = t[0]; obj_proto[i].obj_flags.anti_race_flags = t[1]; /****** END NEW CODE ********/ OBJSAVE.C --------- in: struct obj_data *Obj_from_store add the following: GET_OBJ_EXTRA(obj) = object.extra_flags; <--- below this line (doesn't really matter where but this is where I did it) /******* NEW CODE ******/ GET_OBJ_ANTIC(obj) = object.anti_class_flags; GET_OBJ_ANTIR(obj) = object.anti_race_flags; /****** END NEW CODE ********/ in: int Obj_to_store add the following /******* NEW CODE ******/ object.extra_flags = GET_OBJ_EXTRA(obj); <---- ditto object.anti_class_flags = GET_OBJ_ANTIC(obj); object.anti_race_flags = GET_OBJ_ANTIR(obj); /****** END NEW CODE ********/ OEDIT.C ------- add with all the other externs: (we could include constants.h but I wasn't sure if I would get multiple declarations so I did this instead) /******* NEW CODE ******/ extern char *anti_class_bits[]; extern char *anti_race_bits[]; /****** END NEW CODE ********/ add the following functions (dont forget prototypes) *I added em below oedit_disp_extra menu* /**** NEW CODE ****/ void oedit_disp_antic_menu(struct descriptor_data *d) { int counter, columns = 0; get_char_cols(d->character); #if defined(CLEAR_SCREEN) send_to_char("", d->character); #endif for (counter = 0; counter < NUM_ANTIC_FLAGS; counter++) { sprintf(buf, "%s%2d%s) %-20.20s %s", grn, counter + 1, nrm, anti_class_bits[counter], !(++columns % 2) ? "\r\n" : ""); send_to_char(buf, d->character); } sprintbit(GET_OBJ_ANTIC(OLC_OBJ(d)), anti_class_bits, buf1); sprintf(buf, "\r\nObject flags: %s%s%s\r\n" "Enter anti race flag (0 to quit) : ", cyn, buf1, nrm); send_to_char(buf, d->character); } void oedit_disp_antir_menu(struct descriptor_data *d) { int counter, columns = 0; get_char_cols(d->character); #if defined(CLEAR_SCREEN) send_to_char("", d->character); #endif for (counter = 0; counter < NUM_ANTIR_FLAGS; counter++) { sprintf(buf, "%s%2d%s) %-20.20s %s", grn, counter + 1, nrm, anti_race_bits[counter], !(++columns % 2) ? "\r\n" : ""); send_to_char(buf, d->character); } sprintbit(GET_OBJ_ANTIR(OLC_OBJ(d)), anti_race_bits, buf1); sprintf(buf, "\r\nObject flags: %s%s%s\r\n" "Enter anti race flag (0 to quit) : ", cyn, buf1, nrm); send_to_char(buf, d->character); } /****** END NEW CODE ********/ in void oedit_disp_menu: (here we modify the menu) sprintbit(GET_OBJ_EXTRA(obj), extra_bits, buf2); <--- add below this line (near top) /**** NEW CODE ****/ (you may need to declare char* buf3, buf4;) sprintbit(GET_OBJ_ANTIC(obj), anti_class_bits,buf3); sprintbit(GET_OBJ_ANTIR(obj), anti_race_bits,buf4); /***BELOW THIS*****/ (below this portion of the menu) "-- Item number : [%s%d%s]\r\n" "%s1%s) Namelist : %s%s\r\n" "%s2%s) S-Desc : %s%s\r\n" "%s3%s) L-Desc :-\r\n%s%s\r\n" "%s4%s) A-Desc :-\r\n%s%s" "%s5%s) Type : %s%s\r\n" "%s6%s) Extra flags : %s%s\r\n", cyn, OLC_NUM(d), nrm, grn, nrm, yel, (obj->name && *obj->name) ? obj->name : "undefined", grn, nrm, yel, (obj->short_description && *obj->short_description) ? obj->short_description : "undefined", grn, nrm, yel, (obj->description && *obj->description) ? obj->description : "undefined", grn, nrm, yel, (obj->action_description && *obj->action_description) ? obj->action_description : "\r\n", grn, nrm, cyn, buf1, grn, nrm, cyn, buf2 ); /* * Send first half. */ send_to_char(buf, d->character); /*** ADD ****/ /*Expanded class race menu portion */ sprintf(buf, "%s7%s) Anti-Class flags : %s%s\r\n" "%s8%s) Anti-Race flags : %s%s\r\n", grn, nrm, cyn, buf3, grn, nrm, cyn, buf4 ); /* SEND NEW STUFF FOR EXPANDED CLASSES / RACES */ send_to_char(buf, d->character); /****************** NOTE ************************ * ADJUST THE REST OF THE MENU BELOW ACCORDINLY * ************************************************/ /*********/ add the following in the switch statement case '7': oedit_disp_antic_menu(d); OLC_MODE(d) = OEDIT_ANTIC; break; case '8': oedit_disp_antir_menu(d); OLC_MODE(d) = OEDIT_ANTIR; break; case OEDIT_ANTIR: number = atoi(arg); if ((number < 0) || (number > NUM_ANTIR_FLAGS)) { oedit_disp_antir_menu(d); return; } else if (number == 0) break; else { TOGGLE_BIT(GET_OBJ_ANTIR(OLC_OBJ(d)), 1 << (number - 1)); oedit_disp_antir_menu(d); return; } case OEDIT_ANTIC: number = atoi(arg); if ((number < 0) || (number > NUM_ANTIC_FLAGS)) { oedit_disp_antic_menu(d); return; } else if (number == 0) break; else { TOGGLE_BIT(GET_OBJ_ANTIC(OLC_OBJ(d)), 1 << (number - 1)); oedit_disp_antic_menu(d); return; } It doesnt matter where you insert these but i put them where they fit so i could find em easier when coding. /*******/ now... in void oedit_save_to_disk make these sleight modifications: fprintf(fp, "#%d\n" "%s~\n" "%s~\n" "%s~\n" "%s~\n" "%d %d %d\n" "%d %d %d %d\n" "%d %d %d\n" "%d %d\n", <--------- this GET_OBJ_VNUM(obj), (obj->name && *obj->name) ? obj->name : "undefined", (obj->short_description && *obj->short_description) ? obj->short_description : "undefined", (obj->description && *obj->description) ? obj->description : "undefined", buf1, GET_OBJ_TYPE(obj), GET_OBJ_EXTRA(obj), GET_OBJ_WEAR(obj), GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 2), GET_OBJ_VAL(obj, 3), GET_OBJ_WEIGHT(obj), GET_OBJ_COST(obj), GET_OBJ_RENT(obj),GET_OBJ_ANTIC(obj), GET_OBJ_ANTIR(obj) <---- these two macros ); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <---- please not the carots if cutting and pasting /***********/ PHEW!!!!!!!!!! /****** END NEW CODE ********/ OLC.H ----- /**** NEW *****/ define the following #define NUM_ANTIC_FLAGS <#classes> #define NUM_ANTIR_FLAGS <#races> /**** END ****/ SHOP.C ------ /****** NEW CODE ********/ add with other externs: extern const char *anti_race_bits[]; extern const char *anti_class_bits[]; (once again didnt include constants.h) /*********/ next in int evaluate_expression, *AT TOP OF FUNCTION* int temp, index1,index2,index3; <---- change index to index 1,2,3 int ex,cl,ra; <---- declare these 3 new variables cl=ra=ex=index1=index2=index3=0; <---- initalize all to zero to avoid warnings below this modify the for loop for extra_bits to the following for (index1 = 0; *extra_bits[index1] != '\n'; index1++) if (!str_cmp(name, extra_bits[index1])) { push(&vals, IS_SET(GET_OBJ_EXTRA(obj), 1 << index1)); ex = 1; break; } if(!ex) { for (index2 = 0; *anti_class_bits[index2] != '\n'; index2++) if (!str_cmp(name, anti_class_bits[index2])) { push(&vals, IS_SET(GET_OBJ_ANTIC(obj), 1 << index2)); cl = 1; break; } } if(!cl) { for (index3 = 0; *anti_race_bits[index3] != '\n'; index3++) if (!str_cmp(name, anti_race_bits[index3])) { push(&vals, IS_SET(GET_OBJ_ANTIR(obj), 1 << index3)); ra = 1; break; } } if (*extra_bits[index1] == '\n' && *anti_class_bits[index2] == '\n' && *anti_race_bits[index3] == '\n') push(&vals, isname(name, obj->name)); /********/ in function int same_obj add the following check before the for loop: if (GET_OBJ_ANTIC(obj1) != GET_OBJ_ANTIC(obj2)) return (FALSE); if (GET_OBJ_ANTIR(obj1) != GET_OBJ_ANTIR(obj2)) return (FALSE); /********/ /****** END NEW CODE ********/ SPELLS.C -------- in spell_identify: below this add: send_to_char("Item is: ", ch); sprintbit(GET_OBJ_EXTRA(obj), extra_bits, buf); strcat(buf, "\r\n"); send_to_char(buf, ch); /* NEW */ send_to_char("Restrictions: ", ch); sprintbit(GET_OBJ_ANTIC(obj), anti_class_bits, buf1); sprintbit(GET_OBJ_ANTIR(obj), anti_race_bits, buf2); strcat(buf1,buf2); strcat(buf1,"\r\n"); send_to_char(buf1,ch); /* END */ Note: check for constants.h at top. STRUCTS.H --------- /***** NEW *****/ seperate any class related flags from the ITEM_XXXX flags for extra_flags into /* Extra object flags: used by obj_data.obj_flags.anti_class_flags */ #define ITEM_ANTI_MAGIC_USER (1 << 0) /* Not usable by mages */ #define ITEM_ANTI_CLERIC (1 << 1) /* Not usable by clerics */ #define ITEM_ANTI_THIEF (1 << 2) /* Not usable by thieves */ #define ITEM_ANTI_WARRIOR (1 << 3) /* Not usable by warrior */ ... /* Extra object flags: used by obj_data.obj_flags.anti_race_flags */ #define ITEM_ANTI_HUMAN (1 << 0) /* Not usable by Humans */ #define ITEM_ANTI_ELF (1 << 1) /* Not usable by Elves */ ... /*******/ in struct obj_flag_data ***AND*** struct obj_file_elem, add below extra_flags int /*bitvector_t*/ anti_class_flags; int /*bitvector_t*/ anti_race_flags; /******/ /***** END ******/ UTILS.H ------- /**** NEW *****/ define the following macros #define GET_OBJ_ANTIC(obj) ((obj)->obj_flags.anti_class_flags) #define GET_OBJ_ANTIR(obj) ((obj)->obj_flags.anti_race_flags) /**** END ****/ ************************************ FIXING THE OBJECT FILES ************************************ as I said, this is tedious but if you have some help it can go quick. SAMPLE OBJECT ~~~~~~~~~~~~~ #1 wings~ a pair of wings~ A pair of wings is sitting here.~ ~ 9 0 17 6 0 0 0 0 0 200 change to #1 wings~ a pair of wings~ A pair of wings is sitting here.~ ~ 9 0 17 6 0 0 0 0 0 200 0 0 <--------- anti class / anti race stuff THIS MUST BE DONE FOR EVERY OBJECT. NOW, I DIDN'T REALIZE THIS UNTIL I HAD EDITED ALL THE OBJECTS BY HAND BUT IF YOU DON'T MODIFY THE READ CODE IN DB.C AND BOOT THE MUD, YOU CAN THEN USE "oedit save zone#" FOR EVERY ZONE YOU HAVE AND THIS SHOULD WRITE THE OBJECT FILES CORRECTLY. THEN GO IN AND PUT IN THE CODE FOR DB.C TO READ IN THE EXTRA TWO VALUES. Well, thats it. Hope it works for you like it works for me. Tooie zyrenthian@home.com