######################################################################################### Instructions ######################################################################################### 1. follow steps from original code copied in below 2. add the fix listed at the end of this file 3. do a clean build and have fun ######################################################################################### Original code ######################################################################################### From: Jair <jddotter@ou.edu> Subject: Diety worship system Greetings. What follows is my attempt at a working worship/god system that allows players to pick a god to worship at creation (I have this restricted by alignment and even class, you may not want to do this). Once this god is picked, there is a pray channel that allows them to 'pray' to their god, and anyone else who has the same god can also get the messages. Whenever you sacrifice something, it goes to your god instead of 'Mota', or whatever you've set that to. I also (slightly) modified the mset command (just set mob etc...) so that you can set a characters god from inside the game. However, this is not restricted by alighment or class (to allow for special RP situations). Also, the god you worship shows up in your score. A word of warning: I couldn't make a conventional patch for this because our code is modified enough from stock that the line numbers would be way off, so where it's ambiguous as to where to insert the code, I'll try and put lines before and after the insert. NOTE: all the {B and {y and basically {x in anything that's printed is Lope's colo(u)r code. If you have it, great. If you don't, just delete all that stuff. The colour codes are { and the _one_ character following. My comments on the code should be enclosed in < >. Without further ado: /* Jair's diety worship system, by implementing this code you are under no obligation to credit myself for anything or notify me at all; however, if you wish to give me credit, I'll be thrilled */ *** in comm.c *** <This is the tail end of case CON_GET_ALIGNMENT, have to get rid of this...> group_add(ch,"rom basics",FALSE); group_add(ch,class_table[ch->class].base_group,FALSE); ch->pcdata->learned[gsn_recall] = 50; write_to_buffer(d,"Do you wish to customize this character?\n\r",0); write_to_buffer(d,"Customization takes time, but allows a wider range of skills and abilities.\n\r",0); write_to_buffer(d,"Customize (Y/N)? ",0); d->connected = CON_DEFAULT_CHOICE; break; <...and replace it with this:> write_to_buffer(d,"The following gods are available:\n\r ",0); for ( god = 0; god < MAX_GOD; god++ ) { if ((god_table[god].pc_evil && ch->alignment == -750) || (god_table[god].pc_neutral && ch->alignment == 0) || (god_table[god].pc_good && ch->alignment == 750) ) { if((god_table[god].pc_mage && ch->class == 0) || (god_table[god].pc_cleric && ch->class == 1) || (god_table[god].pc_thief && ch->class == 2) || (god_table[god].pc_warrior && ch->class == 3) ) { write_to_buffer(d,god_table[god].name,0); write_to_buffer(d," ",1); } } } write_to_buffer(d,"\n\r",0); write_to_buffer(d,"Who do you want to worship (help for more information)? ",0); d->connected = CON_GET_GOD; break; case CON_GET_GOD: one_argument(argument,arg); if (!strcmp(arg,"help")) { argument = one_argument(argument,arg); if (argument[0] == '\0') do_help(ch,"gods"); else do_help(ch,argument); write_to_buffer(d,"Who do you want to worship (help for more information)? ",0); break; } god = god_lookup(argument); if ( god == 0 || (!god_table[god].pc_evil && ch->alignment == -750) || (!god_table[god].pc_neutral && ch->alignment == 0) || (!god_table[god].pc_good && ch->alignment == 750) || (!god_table[god].pc_mage && ch->class == 0) || (!god_table[god].pc_cleric && ch->class == 1) || (!god_table[god].pc_thief && ch->class == 2) || (!god_table[god].pc_warrior && ch->class == 3) ) { write_to_buffer(d,"That is not a valid god.\n\r",0); write_to_buffer(d,"The following gods are available:\n\r",0); for ( god = 0; god < MAX_GOD; god++ ) { if ((god_table[god].pc_evil && ch->alignment == -750) || (god_table[god].pc_neutral && ch->alignment == 0) || (god_table[god].pc_good && ch->alignment == 750) ) { if((god_table[god].pc_mage && ch->class == 0) || (god_table[god].pc_cleric && ch->class == 1) || (god_table[god].pc_thief && ch->class == 2) || (god_table[god].pc_warrior && ch->class == 3) ) { write_to_buffer(d,god_table[god].name,0); write_to_buffer(d," ",1); } } } write_to_buffer(d,"\n\r",0); write_to_buffer(d, "Who do you want to worship (help for more information)? ",0); break; } ch->god = god; write_to_buffer(d,"\n\r",0); group_add(ch,"rom basics",FALSE); group_add(ch,class_table[ch->class].base_group,FALSE); ch->pcdata->learned[gsn_recall] = 50; write_to_buffer(d,"Do you wish to customize this character?\n\r",0); write_to_buffer(d,"Customization takes time, but allows a wider range of skills and abilities.\n\r",0); write_to_buffer(d,"Customize (Y/N)? ",0); d->connected = CON_DEFAULT_CHOICE; break; <obviously, if you don't want the gods that the player is able to worship dependent on race or alignment, get rid of the appropriate if statements in the previous code> <Now, to aid us in replacing 'Mota' with the players appropriate god, I just put another case into the $x statements. I left in the surrounding lines so you can see where it goes, the new line is indicated with a '+'> case 'E': i = he_she [URANGE(0, vch ->sex, 2)]; break; case 'm': i = him_her [URANGE(0, ch ->sex, 2)]; break; case 'M': i = him_her [URANGE(0, vch ->sex, 2)]; break; case 's': i = his_her [URANGE(0, ch ->sex, 2)]; break; case 'S': i = his_her [URANGE(0, vch ->sex, 2)]; break; + case 'g': i = god_table[ch->god].name; break; case 'p': i = can_see_obj( to, obj1 ) ? obj1->short_descr : "something"; break; *** in merc.h *** #define MAX_GOD 23 (or however many gods you have +2) <here, you'll have to increment all the numbers after CON_GET_GOD by one (duh)) #define CON_GET_GOD 10 #define CON_DEFAULT_CHOICE 11 #define CON_GEN_GROUPS 12 #define CON_PICK_WEAPON 13 #define CON_READ_IMOTD 14 #define CON_READ_MOTD 15 #define CON_BREAK_CONNECT 16 <This slot (K) should be empty, if not, just pick another empty one> #define COMM_NOPRAY (K) <All the bool fields in the god_type are for setting and determing if that god can be worshiped by pc's of that alignment and/or class. If you don't want to have these restrictions, you can simplify this and the table of gods immensly by just taking out these fields> /* * Immortal table god fields. */ struct god_type { char * name; /* call name of the god */ bool pc_good; /* can be chosen by good pcs */ bool pc_neutral; /* can be chosen by neutral pcs */ bool pc_evil; /* can be chosen by evil pcs */ bool pc_mage; /* can be chosen by Mage pcs */ bool pc_thief; /* can be chosen by Thief pcs */ bool pc_warrior; /* can be chosen by Warrior pcs */ bool pc_cleric; /* can be chosen by Cleric pcs */ }; <This line goes into the: struct char_data (for PC's and NPC's) I didn't think this would be a problem, I just arbitrarily decided do put it here instead of pc_data.> sh_int god; <Should be easy to find where the next two lines go.> extern const struct god_type god_table [MAX_GOD]; int god_lookup args( ( const char *name) ); *** in act_comm.c *** <just add this function> void do_pray( CHAR_DATA *ch, char *argument ) { char buf[MAX_STRING_LENGTH]; DESCRIPTOR_DATA *d; if ( argument[0] == '\0' ) { if (IS_SET(ch->comm,COMM_NOPRAY)) { send_to_char("Pray channel is now ON\n\r",ch); REMOVE_BIT(ch->comm,COMM_NOPRAY); } else { send_to_char("Pray channel is now OFF\n\r",ch); SET_BIT(ch->comm,COMM_NOPRAY); } return; } REMOVE_BIT(ch->comm,COMM_NOPRAY); sprintf( buf, "{y$n:{c %s{x", argument ); act_new("$n prays {B$t{x",ch,argument,NULL,TO_CHAR,POS_DEAD); for ( d = descriptor_list; d != NULL; d = d->next ) { if ( d->connected == CON_PLAYING && ( ch->god == d->character->god ) && !IS_SET(d->character->comm,COMM_NOPRAY) && !IS_SET(d->character->comm,COMM_QUIET) ) { act_new("$n prays {B$t{x",ch,argument,d->character,TO_VICT,POS_DEAD); } } return; } <and in the pose tables (if you still have those in) change the following lines:> "The great god Mota gives you a staff.", "The great god Mota gives $n a staff.", <to these lines:> "The great god $g gives you a staff.", "The great god $g gives $n a staff.", *** in act_obj.c *** <for the following, < means put in, > means take out (they're just replaces, no biggie)> < act( "$n offers $mself to $g, who graciously declines.", > act( "$n offers $mself to Mota, who graciously declines.", < act( "$g appreciates your offer and may accept it later.", ch, NULL, NULL, TO_CHAR ); > send_to_char( "Mota appreciates your offer and may accept it later.\n\r", ch ); < act( "$g gives you one silver coin for your sacrifice.", ch, NULL, NULL, TO_CHAR ); > send_to_char( "Mota gives you one silver coin for your sacrifice.\n\r", ch ); < sprintf(buf,"%s gives you %d silver coins for your sacrifice.\n\r", < god_table[ch->god].name,silver); > sprintf(buf,"Mota gives you %d silver coins for your sacrifice.\n\r", > silver); < act( "$n sacrifices $p to $g.", ch, obj, NULL, TO_ROOM ); > act( "$n sacrifices $p to Mota.", ch, obj, NULL, TO_ROOM ); <now, I might not have to had replaced the send_to_char with act statements, but that's the only way I knew how to get that ch->god tag in. And, it also allows for easy future expansion> *** in tables.c *** { "nopray", COMM_NOPRAY, TRUE }, *** in interp.c *** { "pray", do_pray, POS_SLEEPING, 0, LOG_NORMAL, 1 }, *** in interp.h *** DECLARE_DO_FUN( do_pray ); *** in act_wiz.c *** <on this line, it's the same as what's already there, just add the 'god'> send_to_char( " str int wis dex con sex class level god\n\r",ch ); <then, just add this bit somewhere under the /* Set something */> if (!str_prefix(arg2,"god")) { int god; god = god_lookup(arg3); if( god == 0 ) { send_to_char("That is not a valid god for that character.\n\r",ch); return; } victim->god = god; return; } *** in handler.c *** /* returns god number */ int god_lookup (const char *name) { int god; for ( god = 0; god_table[god].name != NULL; god++) { if (LOWER(name[0]) == LOWER(god_table[god].name[0]) && !str_prefix( name,god_table[god].name)) return god; } return 0; } <this one is just added down where the other 'if(comm_flags & COMM_EVERYTHING ELSE )etc... > if (comm_flags & COMM_NOPRAY ) strcat(buf, " no_pray"); *** in const.c *** <Ok, here is the god table, now obviously I'm not going to put up all 21 of my gods, there's enough here for you get an idea of what's going on. Just put in as many as you want, and don't forget to change MAX_GODS in merc.h. Again, if you don't want the alignment/class checks, this table simplifies enormously.> /* god table */ const struct god_type god_table [] = { /* { name, player_good?, player_neutral?, player_evil?, player_mage?, player_thief?, player_warrior?, player_cleric? }, */ { "Nobody", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, { "God1", TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE }, { "God2", FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE }, { "God3", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE }, . . . { "God21", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE } }; *** in act_info.c *** <this is in here just to show the player whom they worship, it goes in do_score, just wherever you want it to show up. Or not at all if you don't.> sprintf( buf, "You worship %s \n\r",(god_table[ch->god].name)); send_to_char( buf, ch); Ok, that should be it. The reason that I'm sending this to the mailing list is because I looked around (pretty extensively) for a system like this to use on my mud and didn't find one. I know that plenty of other people have coded something similar on their muds, I've played on a couple, but I thought I'd throw this up for everyone to use. If anyone wants to put this on their web/ftp page of snippets, great! Now, I know that I don't have a realy firm grasp on a lot of the things that I'm coding, does anyone suggestions/ideas/flames/etc? Jair ######################################################################################### Fix ######################################################################################### void fwrite_char at the tail end add line with +. fprintf( fp, "Affc '%s' %3d %3d %3d %3d %3d %10d\n", skill_table[paf->type].name, paf->where, paf->level, paf->duration, paf->modifier, paf->location, paf->bitvector ); } + fprintf(fp,"God %s~\n",god_table[ch->god].name); fprintf( fp, "End\n\n" ); return; } and in Case G of void fread_char add line with +. KEY( "Ghos", ch->ghost_level, fread_number( fp ) ); + KEY( "God", ch->god, god_lookup(fread_string( fp )) ); KEY( "Gold", ch->gold, fread_number( fp ) ); this should allow gods to be saved and loaded from pfile after log off... its my guess that these 2 lines were just accidently left out...