Re: races

From: Belgian Underground Mud (bug@asteriks.rug.ac.be)
Date: 05/20/95


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