Hi, a little remark : it is NOT necessary to convert your playerfile!!!! In structs.h, you can put the byte of the races in one of the spare bytes in player_special_data...Search for them in structs.h!!! You don't need to ruin your playerfile... Hymy, The Wacko P-Imp <Power-Imp> On Sat, 20 May 1995, Steve wrote: > Date: Sat, 20 May 1995 13:30:09 -0700 (PDT) > From: Steve <quickey@cyberverse.com> > To: Ricky David Gibson <rdgibson@mailhost.ecn.uoknor.edu> > Cc: circle@pvv.unit.no > Subject: Re: races > > Races aren't really that hard, here is a sample of the changes needed for > bpl4 i think. I haven't tested it with 7 but i dont think there should be > too many problems, (you will have to convert your playerfile though) > > ------------------------------------------------------------------------------ > Race Modification for CircleMUD 3.0 > -by hash@cyberverse.com- > This mod is VERY bare, just the core for a good race system; it will be > improved VERY soon.... so don't be mad this isn't the spiffiest thing! > Basically this mod is search and add, search and replace, etc... dont > get too scared by the file size! :) > ~~ > > First, let's open up the header (.h) files, as they are very important to > the functioning of the program (.c) files. > > ************************* > OPEN EDIT FILE: structs.h > ************************* > > Search for > --- > /* NPC classes (currently unused - feel free to implement!) */ > #define CLASS_OTHER 0 > #define CLASS_UNDEAD 1 > #define CLASS_HUMANOID 2 > #define CLASS_ANIMAL 3 > #define CLASS_DRAGON 4 > #define CLASS_GIANT 5 > --- > Right below it, put the following > --- > /* PC races */ > #define RACE_UNDEFINED -1 > #define RACE_HUMAN 0 > #define RACE_ELF 1 > #define RACE_GNOME 2 > #define RACE_FAIRY 3 > > #define NUM_RACES 4 > --- > Now search for > --- > #define CON_DELCNF1 15 /* Delete confirmation 1 */ > #define CON_DELCNF2 16 /* Delete confirmation 2 */ > --- > Right below it, put the following > --- > #define CON_QRACE 17 /* Race? */ > --- > Now search for > --- > #define ITEM_ANTI_WARRIOR (1 << 15) /* Not usable by warriors */ > #define ITEM_NOSELL (1 << 16) /* Shopkeepers won't touch it */ > --- > Right below it, put the following > --- > #define ITEM_ANTI_HUMAN (1 << 17) /* Not usable by Humans */ > #define ITEM_ANTI_ELF (1 << 18) /* Not usable by Elves */ > #define ITEM_ANTI_GNOME (1 << 19) /* Not usable by Gnomes */ > #define ITEM_ANTI_FAIRY (1 << 20) /* Not usable by Fairies */ > --- > Now search for > --- > #define APPLY_SAVING_BREATH 23 /* Apply to save throw: breath */ > #define APPLY_SAVING_SPELL 24 /* Apply to save throw: spells */ > --- > Right below it, put the following > --- > #define APPLY_RACE 25 /* Reserved */ > --- > Now search for > --- > /* general player-related info, usually PC's and NPC's */ > struct char_player_data { > char *name; /* PC / NPC s name (kill ... ) */ > char *short_descr; /* for NPC 'actions' */ > char *long_descr; /* for 'look' */ > char *description; /* Extra descriptions */ > char *title; /* PC / NPC's title */ > byte sex; /* PC / NPC's sex */ > byte class; /* PC / NPC's class */ > --- > Right below it, between byte class and the next variable, put the following > --- > byte race; /* PC / NPC's race */ > --- > Lastly search for > --- > struct char_file_u { > /* char_player_data */ > char name[MAX_NAME_LENGTH+1]; > char description[EXDSCR_LENGTH]; > char title[MAX_TITLE_LENGTH+1]; > byte sex; > byte class; > --- > Right below it, between byte class and the next variable, put the following > --- > byte race; > --- > > ************************** > CLOSE EDIT FILE: structs.h > ************************** > > *********************** > OPEN EDIT FILE: utils.h > *********************** > > Search for > --- > #define GET_REAL_LEVEL(ch) \ > (ch->desc && ch->desc->original ? GET_LEVEL(ch->desc->original) : \ > GET_LEVEL(ch)) > > #define GET_CLASS(ch) ((ch)->player.class) > --- > Right below it, put the following > --- > #define GET_RACE(ch) ((ch)->player.race) > --- > Lastly search for > --- > #define IS_THIEF(ch) (!IS_NPC(ch) && \ > (GET_CLASS(ch) == CLASS_THIEF)) > #define IS_WARRIOR(ch) (!IS_NPC(ch) && \ > (GET_CLASS(ch) == CLASS_WARRIOR)) > --- > Right below it, put the following > --- > #define IS_HUMAN(ch) (!IS_NPC(ch) && \ > (GET_RACE(ch) == RACE_HUMAN)) > > #define IS_ELF(ch) (!IS_NPC(ch) && \ > (GET_RACE(ch) == RACE_ELF)) > > #define IS_GNOME(ch) (!IS_NPC(ch) && \ > (GET_RACE(ch) == RACE_GNOME)) > > #define IS_FAIRY(ch) (!IS_NPC(ch) && \ > (GET_RACE(ch) == RACE_FAIRY)) > --- > > ************************ > CLOSE EDIT FILE: utils.h > ************************ > > Now, lets go on to the .C files, the core of it all. > > *********************** > OPEN EDIT FILE: class.c > *********************** > > Search for > --- > const char *pc_class_types[] = { > "Magic User", > "Cleric", > "Thief", > "Warrior", > "\n" > }; > --- > Then put the following below it > --- > const char *race_abbrevs[] = { > "Hum", > "Elf", > "Gno", > "Fai", > "\n" > }; > > const char *pc_race_types[] = { > "Human", > "Elf", > "Gnome", > "Fairy", > "\n" > }; > --- > Now search for > --- > "Select a class:\r\n" > " [C]leric\r\n" > " [T]hief\r\n" > " [W]arrior\r\n" > " [M]agic-user\r\n"; > --- > And put the following right below it > --- > /* The menu for choosing a race in interpreter.c: */ > const char *race_menu = > "\r\n" > "Select a race:\r\n" > " [H]uman\r\n" > " [E]lf\r\n" > " [G]nome\r\n" > " [F]airy\r\n"; > --- > Now search for > --- > case 'w': > return CLASS_WARRIOR; > break; > case 't': > return CLASS_THIEF; > break; > default: > return CLASS_UNDEFINED; > break; > } > } > --- > And block copy the following below it > --- > /* > * The code to interpret a race letter (used in interpreter.c when a > * new character is selecting a race). > */ > int parse_race(char arg) > { > arg = LOWER(arg); > > switch (arg) { > case 'h': > return RACE_HUMAN; > break; > case 'e': > return RACE_ELF; > break; > case 'g': > return RACE_GNOME; > break; > case 'f': > return RACE_FAIRY; > break; > default: > return RACE_UNDEFINED; > break; > } > } > --- > Now search for > --- > case 't': > return 4; > break; > case 'w': > return 8; > break; > default: > return 0; > break; > } > } > --- > Then place the following below it > --- > long find_race_bitvector(char arg) > { > arg = LOWER(arg); > > switch (arg) { > case 'h': > return 1; > break; > case 'e': > return 2; > break; > case 'g': > return 4; > break; > case 'f': > return 8; > break; > default: > return 0; > break; > } > } > --- > Now replace the description of void roll_real_abils(...) with this one > --- > /* > * Roll the 6 stats for a character... each stat is made of the sum of > * the best 3 out of 4 rolls of a 6-sided die. Each class then decides > * which priority will be given for the best to worst stats. Race also > * affects stats. > */ > --- > Now search for > --- > case CLASS_WARRIOR: > ch->real_abils.str = table[0]; > ch->real_abils.dex = table[1]; > ch->real_abils.con = table[2]; > ch->real_abils.wis = table[3]; > ch->real_abils.intel = table[4]; > ch->real_abils.cha = table[5]; > if (ch->real_abils.str == 18) > ch->real_abils.str_add = number(0, 100); > break; > } > --- > And directly<!> below it, put this > --- > switch (GET_RACE(ch)) { > case RACE_HUMAN: > ++ch->real_abils.con; > break; > case RACE_ELF: > ++ch->real_abils.dex; > ++ch->real_abils.intel; > --ch->real_abils.con; > --ch->real_abils.str; > break; > case RACE_GNOME: > ch->real_abils.str+=3; > --ch->real_abils.dex; > --ch->real_abils.intel; > --ch->real_abils.cha; > break; > case RACE_FAIRY: > ch->real_abils.dex+=2; > ++ch->real_abils.wis; > ++ch->real_abils.cha; > ch->real_abils.str-=2; > --ch->real_abils.con; > break; > } > --- > You should have still left the end of the function the same though, like: > --- > ch->aff_abils = ch->real_abils; > } > --- > Okay, now, at the very END of the file, add this function > --- > int invalid_race(struct char_data *ch, struct obj_data *obj) { > if ((IS_OBJ_STAT(obj, ITEM_ANTI_HUMAN) && IS_HUMAN(ch)) || > (IS_OBJ_STAT(obj, ITEM_ANTI_ELF) && IS_ELF(ch)) || > (IS_OBJ_STAT(obj, ITEM_ANTI_GNOME) && IS_GNOME(ch)) || > (IS_OBJ_STAT(obj, ITEM_ANTI_FAIRY) && IS_FAIRY(ch))) > return 1; > else > return 0; > } > --- > > ************************ > CLOSE EDIT FILE: class.c > ************************ > > *************************** > OPEN EDIT FILE: constants.c > *************************** > > Search for > --- > /* CON_x */ > const char *connected_types[] = { > "Playing", > "Disconnecting", > "Get name", > "Confirm name", > "Get password", > "Get new PW", > "Confirm new PW", > "Select sex", > "Select class", > "Reading MOTD", > "Main Menu", > "Get descript.", > "Changing PW 1", > "Changing PW 2", > "Changing PW 3", > "Self-Delete 1", > "Self-Delete 2", > --- > And add the following below it > --- > "Select race", > --- > Lastly search for > --- > /* APPLY_x */ > const char *apply_types[] = { > "NONE", > "STR", > "DEX", > "INT", > "WIS", > "CON", > "CHA", > "CLASS", > "LEVEL", > "AGE", > "CHAR_WEIGHT", > "CHAR_HEIGHT", > "MAXMANA", > "MAXHIT", > "MAXMOVE", > "GOLD", > "EXP", > "ARMOR", > "HITROLL", > "DAMROLL", > "SAVING_PARA", > "SAVING_ROD", > "SAVING_PETRI", > "SAVING_BREATH", > "SAVING_SPELL", > --- > And add the following below it > --- > "RACE", > --- > > *************************** > CLOSE EDIT FILE: constant.c > *************************** > > ******************** > OPEN EDIT FILE: db.c > ******************** > > Search for > --- > mob_proto[i].player.sex = t[2]; > > mob_proto[i].player.class = 0; > --- > Then put this after it > --- > mob_proto[i].player.race = 0; > --- > Now search for > --- > GET_SEX(ch) = st->sex; > GET_CLASS(ch) = st->class; > --- > Then add the following below it > --- > GET_RACE(ch) = st->race; > --- > Lastly search for > --- > st->sex = GET_SEX(ch); > st->class = GET_CLASS(ch); > --- > Then put this below it > --- > st->race = GET_RACE(ch); > --- > > ********************* > CLOSE EDIT FILE: db.c > ********************* > > ************************* > OPEN EDIT FILE: handler.c > ************************* > > Search for > --- > case APPLY_SAVING_SPELL: > GET_SAVE(ch, SAVING_SPELL) += mod; > break; > --- > Put the following below it > --- > case APPLY_RACE: > /* ??? GET_RACE(ch) += mod; */ > break; > --- > Now search for > --- > void equip_char(struct char_data * ch, struct obj_data * obj, int pos) > { > int j; > int invalid_class(struct char_data *ch, struct obj_data *obj); > --- > And add this below it > --- > int invalid_race(struct char_data *ch, struct obj_data *obj); > --- > Lastly search for the following > --- > if ((IS_OBJ_STAT(obj, ITEM_ANTI_EVIL) && IS_EVIL(ch)) || > (IS_OBJ_STAT(obj, ITEM_ANTI_GOOD) && IS_GOOD(ch)) || > (IS_OBJ_STAT(obj, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL(ch)) || > invalid_class(ch, obj)) { > --- > and REPLACE the entire thing with the following: > --- > if ((IS_OBJ_STAT(obj, ITEM_ANTI_EVIL) && IS_EVIL(ch)) || > (IS_OBJ_STAT(obj, ITEM_ANTI_GOOD) && IS_GOOD(ch)) || > (IS_OBJ_STAT(obj, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL(ch)) || > invalid_class(ch, obj) || invalid_race(ch, obj)) { > --- > > ************************** > CLOSE EDIT FILE: handler.c > ************************** > > ***************************** > OPEN EDIT FILE: interpreter.c > ***************************** > > Search for > --- > extern const char *class_menu; > --- > Then add this below it > --- > extern const char *race_menu; > --- > Now, search for (its right below it) > --- > sh_int load_room; > > int load_char(char *name, struct char_file_u * char_element); > int parse_class(char arg); > --- > And add this... > --- > int parse_race(char arg); > --- > Now replace the following two CASE statements for the ones that already exist > <THIS IS VERY IMPORTANT!> completely erase old case CON_QCLASS, and add > this one plus the additional <new> case CON_QRACE at the end of it... > --- > case CON_QCLASS: > if ((GET_CLASS(d->character) = parse_class(*arg)) == CLASS_UNDEFINED) { > SEND_TO_Q("\r\nThat's not a class.\r\nClass: ", d); > return; > } > SEND_TO_Q(race_menu, d); > SEND_TO_Q("\r\nRace: ", d); > STATE(d) = CON_QRACE; > break; > > case CON_QRACE: > if ((GET_RACE(d->character) = parse_race(*arg)) == CLASS_UNDEFINED) { > SEND_TO_Q("\r\nThat's not a race.\r\nRace: ", d); > return; > } > > if (d->pos < 0) > d->pos = create_entry(GET_NAME(d->character)); > init_char(d->character); > save_char(d->character, NOWHERE); > SEND_TO_Q(motd, d); > SEND_TO_Q("\r\n\n*** PRESS RETURN: ", d); > STATE(d) = CON_RMOTD; > > sprintf(buf, "%s [%s] new player.", GET_NAME(d->character), d->host); > mudlog(buf, NRM, LVL_IMMORT, TRUE); > break; > --- > > *************************** > CLOSE EDIT FILE: interpre.c > *************************** > > > *******YOU'RE DONE!******* > .-----------------------------------------------------------------------. | I t ' s n o t a b u g , i t ' s a f e a t u r e ! ! ! | | BUG Mud - Belgian UnderGround @@@@@@@@. @@@. @@@. .@@@@@@@. | | Imps: @@@@ `@@@ @@@@ @@@@ !@@@@' `@@! | | Gekke, Charlotte, Hymy, @@@@..:@@@ @@@@ @@@! !@@@@ ' | | Mentat and Wodan @@!@@@@@@ @@@! !@@! !@!@@ .@@@. | | !@!! `!@@@. @@!! !@!! !@!!@ `@@@ | | Thanx to SunGoku... :!!: .!!@@; !!!:. !@!! `!!!@. :@!@ | | `!!::!!:!' `!!!:::!!' :!!!!!!!!! | | If you can't connect, .!: `:: : `::' `:: :!:' `!' | | email tvergote@eduserv.rug.ac.be :; : . :; : :: : | | with subject "frontdoor" : . : . . . | `-----------------------------------------------------------------------'
This archive was generated by hypermail 2b30 : 12/07/00 PST