Race before Class Code. v1.0 ---------------------------- Author: Lews Webpage: www.sica.tzo.com/mud/ Email: lews00@yahoo.com Telnet: sica.tzo.com:4000 TERMS OF USE: ------------- Keep any comments of headers in place. If you use my code, send me an e-mail letting me know that you are using it. Always make sure you back up your files before making any changes. I will assume no responsibility if something goes wrong. What it is: ----------- This code changes the character creation process. Instead of choosing a class first then a race, the player will choose a race first, then a race. the setclass, showclass, setrace and showrace commands are also changed to reflect the new code. This code will not affect any current users, they can stll keep there current race and class. Also included are the modified stock class and race files. If there are differences in the stock files to my own, please let me know. This is my first code snippet to be released, be kind. Instructions: ------------- Before you start, make sure you back up your mud. Also make sure you back up your class and race files. The sections that are to be commented out, are to ease an uninstallation process, you can delete these sections of code if you feel the need to. ---------------------------------------------------------------- in mud.h ================================================================ Find this: /* * Per-class stuff. */ struct class_type { char * who_name; /* Name for 'who' */ EXT_BV affected; sh_int attr_prime; /* Prime attribute */ sh_int attr_second; /* Second attribute */ sh_int attr_deficient; /* Deficient attribute */ and ADD this: EXT_BV race_restriction; /* Flags for illegal races -Lews */ find this: /* race dedicated stuff */ struct race_type { char race_name [16]; /* Race name */ EXT_BV affected; /* Default affect bitvectors */ sh_int str_plus; /* Str bonus/penalty */ sh_int dex_plus; /* Dex " */ sh_int wis_plus; /* Wis " */ sh_int int_plus; /* Int " */ sh_int con_plus; /* Con " */ sh_int cha_plus; /* Cha " */ sh_int lck_plus; /* Lck " */ sh_int hit; sh_int mana; int resist; int suscept; int class_restriction; /* Flags for illegal classes */ and CHANGE the last line above to: /* int class_restriction; *//* Flags for illegal classes */ ---------------------------------------------------------------- In act_wiz.c ================================================================ Find this: /* from build.c */ int get_risflag( char *flag ); int get_defenseflag( char *flag ); int get_attackflag( char *flag ); and ADD: int get_pc_race( char *type ); ---------------------------------------------------------------- void do_showclass( CHAR_DATA *ch, char *argument ) ---------------------------------------------------------------- Find this: int cl, low, hi; and CHANGE to: int cl, low, hi, ct, i; find this: pager_printf_color( ch, "&wSecond Attribute: &W%-14s &wDeficient Attribute: &W%-14s\n\r", affect_loc_name(class->attr_second), affect_loc_name(class->attr_deficient) ); and ADD: ct=0; pager_printf_color( ch, "&wAllowed Races: "); for(i=0;i<MAX_RACE;i++){ if( !xIS_SET(class->race_restriction, i ) && str_cmp(race_table[i]->race_name,"unused" ) ) { ct++; pager_printf_color( ch, "&W%s ", race_table[i]->race_name); if( ct%6==0) send_to_char("\n\r", ch); } } if( (ct%6!=0) || (ct==0)) send_to_char("\n\r", ch); ct=0; pager_printf_color( ch, "&wDisallowed Races: "); for(i=0;i<MAX_RACE;i++){ if( xIS_SET(class->race_restriction, i ) && str_cmp(race_table[i]->race_name,"unused" ) ) { ct++; pager_printf_color( ch, "&r%s ", race_table[i]->race_name); if( ct%6==0) send_to_char("\n\r", ch); } } if( (ct%6!=0) || (ct==0)) send_to_char("\n\r", ch); ---------------------------------------------------------------- in bool create_new_class( int index, char *argument ) ---------------------------------------------------------------- find this: class_table[index]->attr_deficient = 0; and add: xCLEAR_BITS(class_table[index]->race_restriction); ---------------------------------------------------------------- in void do_setclass( CHAR_DATA *ch, char *argument ) ---------------------------------------------------------------- find this: send_to_char( " name prime weapon guild thac0 thac32\n\r", ch ); CHANGE to: send_to_char( " name prime race weapon guild thac0 thac32\n\r", ch ); find this: if ( !str_cmp( arg2, "name" ) ) { STRFREE(class->who_name ); class->who_name = STRALLOC( argument ); send_to_char( "Done.\n\r", ch ); return; } and ADD below: /* Race Restriction -Lews */ if ( !str_cmp( arg2, "race" ) ) { if ( !argument || argument[0] == '\0' ) { send_to_char( "Usage: setclass <class> <race> \n\r", ch ); return; } while ( argument[0] != '\0' ) { argument = one_argument( argument, arg2 ); value = get_pc_race( arg2 ); if ( value < 0 || value > MAX_BITS ) ch_printf( ch, "Unknown Race: %s\n\r", arg2 ); else xTOGGLE_BIT( class->race_restriction, value ); } return; } -------------------------------------------------------- in bool create_new_race( int index, char *argument ) -------------------------------------------------------- find this: race_table[index]->class_restriction = 0; and COMMENT it out /* */ -------------------------------------------------------- in void do_setrace( CHAR_DATA *ch, char *argument ) -------------------------------------------------------- Find this: send_to_char( " name classes strplus dexplus wisplus\n\r", ch ); and CHANGE it to send_to_char( " name strplus dexplus wisplus\n\r", ch ); find this: if ( !str_cmp( arg2, "classes" ) ) { for(i=0;i<MAX_CLASS;i++) { if( !str_cmp(argument,class_table[i]->who_name) ) { TOGGLE_BIT( race->class_restriction, 1 << i); /* k, that's boggling */ send_to_char( "Done.\n\r", ch ); return; } } send_to_char( "No such class.\n\r", ch ); return; } and COMMENT it out /* */ -------------------------------------------------------- in void do_showrace( CHAR_DATA *ch, char *argument ) -------------------------------------------------------- find: ct=0; sprintf( buf, "Disallowed Classes: "); send_to_char( buf, ch); for(i=0;i<MAX_CLASS;i++){ if( IS_SET(race->class_restriction, 1 << i) ) { ct++; sprintf(buf,"%s ", class_table[i]->who_name); send_to_char( buf, ch); if( ct%6==0) send_to_char("\n\r", ch); } } if( (ct%6!=0) || (ct==0)) send_to_char("\n\r", ch); ct=0; sprintf( buf, "Allowed Classes: "); send_to_char( buf, ch); for(i=0;i<MAX_CLASS;i++){ if( !IS_SET(race->class_restriction, 1 << i) ) { ct++; sprintf(buf,"%s ", class_table[i]->who_name); send_to_char( buf, ch); if( ct%6==0) send_to_char("\n\r", ch); } } if( (ct%6!=0) || (ct==0)) send_to_char("\n\r", ch); and COMMENT it out /* */ ---------------------------------------------------------------- In comm.c (This is the big one ) ================================================================ Find this: write_to_buffer( d, "\n\rSelect a class, or type help [class] to learn more about that class.\n\r[", 0 ); buf[0] = '\0'; /* * Take this out SHADDAI */ for ( iClass = 0; iClass < MAX_PC_CLASS-2; iClass++ ) { if ( class_table[iClass]->who_name && class_table[iClass]->who_name[0] != '\0' ) { if ( iClass > 0 ) { if ( strlen(buf)+strlen(class_table[iClass]->who_name) > 77 ) { strcat( buf, "\n\r" ); write_to_buffer( d, buf, 0 ); buf[0] = '\0'; } else strcat( buf, " " ); } } strcat( buf, class_table[iClass]->who_name ); } strcat( buf, "]\n\r: " ); write_to_buffer( d, buf, 0 ); d->connected = CON_GET_NEW_CLASS; break; case CON_GET_NEW_CLASS: argument = one_argument(argument, arg); if (!str_cmp(arg, "help")) { for ( iClass = 0; iClass < MAX_PC_CLASS; iClass++ ) { if ( class_table[iClass]->who_name && class_table[iClass]->who_name[0] != '\0' ) { if (toupper(argument[0])==toupper(class_table[iClass]->who_name[0]) && !str_prefix( argument, class_table[iClass]->who_name ) ) { do_help(ch, argument); write_to_buffer( d, "Please choose a class: ", 0 ); return; } } } write_to_buffer( d, "No such help topic. Please choose a class: ", 0 ); return; } for ( iClass = 0; iClass < MAX_PC_CLASS; iClass++ ) { if ( class_table[iClass]->who_name && class_table[iClass]->who_name[0] != '\0' ) { if ( toupper(arg[0]) == toupper(class_table[iClass]->who_name[0]) && !str_prefix( arg, class_table[iClass]->who_name ) ) { ch->class = iClass; break; } } } if ( iClass == MAX_PC_CLASS || !class_table[iClass]->who_name || class_table[iClass]->who_name[0] == '\0' || !str_cmp(class_table[iClass]->who_name,"unused")) { write_to_buffer( d, "That's not a class.\n\rWhat IS your class? ",0); return; } if ( check_bans( ch, BAN_CLASS ) ) { write_to_buffer (d, "That class is not currently avaiable.\n\rWhat IS your class? ",0); return; } write_to_buffer( d, "\n\rYou may choose from the following races, or type help [race] to learn more:\n\r[", 0 ); buf[0] = '\0'; for ( iRace = 0; iRace < MAX_PC_RACE; iRace++ ) { if (iRace != RACE_VAMPIRE && race_table[iRace]->race_name && race_table[iRace]->race_name[0] != '\0' && !IS_SET(race_table[iRace]->class_restriction, 1 << ch->class) && str_cmp(race_table[iRace]->race_name,"unused") ) { if ( iRace > 0 ) { if ( strlen(buf)+strlen(race_table[iRace]->race_name) > 77 ) { strcat( buf, "\n\r" ); write_to_buffer( d, buf, 0 ); buf[0] = '\0'; } else strcat( buf, " " ); } strcat( buf, race_table[iRace]->race_name ); } } strcat( buf, "]\n\r: " ); write_to_buffer( d, buf, 0 ); d->connected = CON_GET_NEW_RACE; break; case CON_GET_NEW_RACE: argument = one_argument(argument, arg); if (!str_cmp( arg, "help") ) { for ( iRace = 0; iRace < MAX_PC_RACE; iRace++ ) { if ( toupper(argument[0]) == toupper(race_table[iRace]->race_name[0]) && !str_prefix( argument, race_table[iRace]->race_name) ) { do_help(ch, argument); write_to_buffer( d, "Please choose a race: ", 0); return; } } write_to_buffer( d, "No help on that topic. Please choose a race: ", 0 ); return; } for ( iRace = 0; iRace < MAX_PC_RACE; iRace++ ) { if ( toupper(arg[0]) == toupper(race_table[iRace]->race_name[0]) && !str_prefix( arg, race_table[iRace]->race_name ) ) { ch->race = iRace; break; } } if ( iRace == MAX_PC_RACE || !race_table[iRace]->race_name || race_table[iRace]->race_name[0] == '\0' || iRace == RACE_VAMPIRE || IS_SET(race_table[iRace]->class_restriction, 1 << ch->class ) || !str_cmp(race_table[iRace]->race_name,"unused") ) { write_to_buffer( d, "That's not a race.\n\rWhat IS your race? ", 0 ); return; } if ( check_bans( ch, BAN_RACE ) ) { write_to_buffer (d, "That race is not currently available.\n\rWhat is your race? ", 0); return; } write_to_buffer( d, "\n\rWould you like RIP, ANSI or no graphic/color support, (R/A/N)? ", 0 ); d->connected = CON_GET_WANT_RIPANSI; break; and CHANGE it to: write_to_buffer( d, "\n\rYou may choose from the following races, or type help [race] to learn more:\n\r[", 0 ); buf[0] = '\0'; for ( iRace = 0; iRace < MAX_PC_RACE; iRace++ ) { if (iRace != RACE_VAMPIRE && race_table[iRace]->race_name && race_table[iRace]->race_name[0] != '\0' && str_cmp(race_table[iRace]->race_name,"unused") ) { if ( iRace > 0 ) { if ( strlen(buf)+strlen(race_table[iRace]->race_name) > 77 ) { strcat( buf, "\n\r" ); write_to_buffer( d, buf, 0 ); buf[0] = '\0'; } else strcat( buf, " " ); } strcat( buf, race_table[iRace]->race_name ); } } strcat( buf, "]\n\r: " ); write_to_buffer( d, buf, 0 ); d->connected = CON_GET_NEW_RACE; break; case CON_GET_NEW_RACE: argument = one_argument(argument, arg); if (!str_cmp( arg, "help") ) { for ( iRace = 0; iRace < MAX_PC_RACE; iRace++ ) { if ( toupper(argument[0]) == toupper(race_table[iRace]->race_name[0]) && !str_prefix( argument, race_table[iRace]->race_name) ) { do_help(ch, argument); write_to_buffer( d, "Please choose a race: ", 0); return; } } write_to_buffer( d, "No help on that topic. Please choose a race: ", 0 ); return; } for ( iRace = 0; iRace < MAX_PC_RACE; iRace++ ) { if ( toupper(arg[0]) == toupper(race_table[iRace]->race_name[0]) && !str_prefix( arg, race_table[iRace]->race_name ) ) { ch->race = iRace; break; } } if ( iRace == MAX_PC_RACE || !race_table[iRace]->race_name || race_table[iRace]->race_name[0] == '\0' || iRace == RACE_VAMPIRE || !str_cmp(race_table[iRace]->race_name,"unused") ) { write_to_buffer( d, "That's not a race.\n\rWhat IS your race? ", 0 ); return; } if ( check_bans( ch, BAN_RACE ) ) { write_to_buffer (d, "That race is not currently available.\n\rWhat is your race? ", 0); return; } write_to_buffer( d, "\n\rYou may choose from the following classes, or type help [class] to learn more:\n\r[", 0 ); buf[0] = '\0'; for ( iClass = 0; iClass < MAX_PC_CLASS; iClass++ ) { if ( class_table[iClass]->who_name && class_table[iClass]->who_name[0] != '\0' && !xIS_SET(class_table[iClass]->race_restriction, 1 << ch->race) && str_cmp(class_table[iClass]->who_name,"unused") ) { if ( iClass > 0 ) { if ( strlen(buf)+strlen(class_table[iClass]->who_name ) > 77 ) { strcat( buf, "\n\r" ); write_to_buffer( d, buf, 0 ); buf[0] = '\0'; } else strcat( buf, " " ); } strcat( buf, class_table[iClass]->who_name ); } } strcat( buf, "]\n\r: " ); write_to_buffer( d, buf, 0 ); d->connected = CON_GET_NEW_CLASS; break; case CON_GET_NEW_CLASS: argument = one_argument(argument, arg); if (!str_cmp(arg, "help")) { for ( iClass = 0; iClass < MAX_PC_CLASS; iClass++ ) { if ( class_table[iClass]->who_name && class_table[iClass]->who_name[0] != '\0' ) { if (toupper(argument[0])==toupper(class_table[iClass]->who_name[0]) && !str_prefix( argument, class_table[iClass]->who_name ) ) { do_help(ch, argument); write_to_buffer( d, "Please choose a class: ", 0 ); return; } } } write_to_buffer( d, "No such help topic. Please choose a class: ", 0 ); return; } for ( iClass = 0; iClass < MAX_PC_CLASS; iClass++ ) { if ( class_table[iClass]->who_name && class_table[iClass]->who_name[0] != '\0' ) { if ( toupper(arg[0]) == toupper(class_table[iClass]->who_name[0]) && !str_prefix( arg, class_table[iClass]->who_name ) ) { ch->class = iClass; break; } } } if ( iClass == MAX_PC_CLASS || !class_table[iClass]->who_name || class_table[iClass]->who_name[0] == '\0' || xIS_SET(class_table[iClass]->race_restriction, 1 << ch->race ) || !str_cmp(class_table[iClass]->who_name,"unused") ) { write_to_buffer( d, "That's not a class.\n\rWhat IS your class? ", 0 ); return; } if ( check_bans( ch, BAN_CLASS ) ) { write_to_buffer (d, "That class is not currently avaiable.\n\rWhat IS your class? ",0); return; } write_to_buffer( d, "\n\rWould you like RIP, ANSI or no graphic/color support, (R/A/N)? ", 0 ); d->connected = CON_GET_WANT_RIPANSI; break; ---------------------------------------------------------------- In tables.c ================================================================ ---------------------------------------------------------------- in bool load_class_file( char *fname ) ---------------------------------------------------------------- Find this: /* Setup defaults for additions to class structure */ class->attr_second = 0; class->attr_deficient = 0; xCLEAR_BITS(class->affected); and ADD: xCLEAR_BITS(class->race_restriction); Find this: KEY( "Resist", class->resist, fread_number( fp ) ); and ADD above KEY( "Races", class->race_restriction, fread_bitvector( fp ) ); ---------------------------------------------------------------- in void write_class_file( int cl ) ---------------------------------------------------------------- Find this: fprintf( fpout, "AttrSecond %d\n", class->attr_second ); fprintf( fpout, "AttrDeficient %d\n", class->attr_deficient ); and ADD: fprintf( fpout, "Races %s\n", print_bitvector(&class->race_restriction )); ---------------------------------------------------------------- In void write_race_file( int ra ) ---------------------------------------------------------------- Find this: fprintf( fpout, "Classes %d\n", race->class_restriction ); and COMMENT it out /* */ ---------------------------------------------------------------- In bool load_race_file( char *fname ) ---------------------------------------------------------------- Find this: KEY( "Classes", race->class_restriction, fread_number( fp ) ); and COMMENT it out /* */ ================================================================ ================================================================ Now you just need to Recompile, and edit all your race and class files. I've included modified race and class files from stock smaug 1.4a