Changes v1.0 What this does: This will put several commands in your MUD that will keep your MUD updated with the changes you have made. I made this because I noticed a lot of MUDs use help files for their changes, after a while it builds up. Oh well, here is your solution. What you will need to change: changes.c <-- needs to be created mud.h tables.c What you will need to add: This is pretty much straight forward. You can add other things for your changes. This is what I used and thought everyone could put to use. ------------------------------------------------------------------------------------------------- pico changes.c to create this file copy and paste all of this into that file, #if defined(macintosh) #include #else #include #include #endif #include #include #include #include #include #include #include #include #include "mud.h" #include "changes.h" /* * Globals */ char * current_date args( ( void ) ); int num_changes args( ( void ) ); /* * Local Functions */ int maxChanges; #define NULLSTR( str ) ( str == NULL || str[0] == '\0' ) CHANGE_DATA * changes_table; void load_changes( ) { FILE *fp; int i; if ( !(fp = fopen( CHANGE_FILE, "r")) ) { bug( "Could not open Changes File for reading.", 0 ); return; } fscanf( fp, "%d\n", &maxChanges ); /* Use malloc so we can realloc later on */ changes_table = malloc( sizeof( CHANGE_DATA) * (maxChanges+1) ); for( i = 0; i < maxChanges; i++ ) { changes_table[i].change = fread_string( fp ); changes_table[i].coder = fread_string( fp ); changes_table[i].date = fread_string( fp ); changes_table[i].mudtime = fread_number( fp ); } changes_table[maxChanges].coder = str_dup(""); fclose(fp); return; /* just return */ } char * current_date( ) { static char buf [ 128 ]; struct tm * datetime; datetime = localtime( ¤t_time ); strftime( buf, sizeof( buf ), "%x", datetime ); return buf; } void save_changes(void) { FILE *fp; int i; if ( !(fp = fopen( CHANGE_FILE,"w")) ) { perror( CHANGE_FILE ); return; } fprintf( fp, "%d\n", maxChanges ); for( i = 0; i < maxChanges; i++ ) { fprintf (fp, "%s~\n", changes_table[i].change); fprintf (fp, "%s~\n", changes_table[i].coder); fprintf (fp, "%s~\n", changes_table[i].date); fprintf (fp, "%ld\n", changes_table[i].mudtime ); fprintf( fp, "\n" ); } fclose(fp); return; } void delete_change(int iChange) { int i,j; CHANGE_DATA * new_table; new_table = malloc( sizeof( CHANGE_DATA ) * maxChanges ); if( !new_table ) { return; } for ( i= 0, j = 0; i < maxChanges+1; i++) { if( i != iChange ) { new_table[j] = changes_table[i]; j++; } } free( changes_table ); changes_table = new_table; maxChanges--; return; } void do_addchange(CHAR_DATA *ch, char *argument ) { char buf1[MAX_STRING_LENGTH]; CHANGE_DATA * new_table; if ( IS_NPC( ch ) ) return; if ( argument[0] == '\0' ) { send_to_char( "&YSyntax&G: &WAddchange ChangeString\n\r", ch ); send_to_char( "&YType &R'&wchanges&R'&Y to view the list.&d\n\r", ch ); return; } maxChanges++; new_table = realloc( changes_table, sizeof( CHANGE_DATA ) *(maxChanges+1) ); if (!new_table) /* realloc failed */ { send_to_char ("Memory allocation failed. Brace for impact.\n\r",ch); return; } changes_table = new_table; changes_table[maxChanges-1].change = str_dup( argument ); changes_table[maxChanges-1].coder = str_dup( ch->name ); changes_table[maxChanges-1].date = str_dup(current_date()); changes_table[maxChanges-1].mudtime = current_time; send_to_char("&GChanges Created.\n\r",ch); send_to_char("&YType &R'&wchanges&Y'&Y to see the changes.\n\r",ch); do_echo(ch, "&R[&CUPDATE&R] &WNew Change added to the mud, type &R'&wchanges&R'&W to see it.&w"); save_changes(); sprintf(buf1, "
  • %s

    ", argument); // prepend_to_file(CHANGEHTML_FILE, buf1); return; } void do_chsave( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char buf[MSL]; char buf1[MAX_STRING_LENGTH]; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( IS_NPC(ch) ) return; if (!ch->desc || NULLSTR(arg1) ) { send_to_char("Syntax: chsave load/save\n\r",ch); send_to_char("Syntax: chsave delete (change number)\n\r",ch); return; } if ( !str_cmp(arg1,"load") ) { load_changes( ); send_to_char("Changes Loaded.\n\r",ch); return; } if ( !str_cmp(arg1,"save") ) { save_changes( ); sprintf(buf1, "
  • %s

    ", argument); // prepend_to_file(CHANGEHTML_FILE, buf1); send_to_char("&GChanges Saved.\n\r",ch); return; } if ( !str_cmp(arg1, "delete")) { int num; if ( NULLSTR(arg2) || !is_number( arg2 ) ) { send_to_char("&wFor chsave delete, you must provide a change number.{x\n\r",ch); send_to_char("Syntax: chsave delete (change number)\n\r",ch); return; } num = atoi( arg2 ); if ( num < 0 || num > maxChanges ) { sprintf( buf, "Valid changes are from 0 to %d.\n\r", maxChanges ); send_to_char( buf, ch ); return; } delete_change( num ); send_to_char("&RChange deleted.\n\r",ch); return; } return; } /* * The following format code has been adapted from KaViR's justify * snippet -- Dreimas */ static void AddSpaces( char **ppszText, int iNumber ) { int iLoop; for ( iLoop = 0; iLoop < iNumber; iLoop++ ) { *(*ppszText)++ = ' '; } } char *change_justify( char *pszText, int iAlignment ) { static char s_szResult[4096]; char * pszResult = &s_szResult[0]; char szStore[4096]; int iMax; int iLength = iAlignment-1; int iLoop = 0; if ( strlen( pszText ) < 10 ) { strcpy( s_szResult, "BUG: Justified string cannot be less than 10 characters long." ); return( &s_szResult[0] ); } while ( *pszText == ' ' ) pszText++; szStore[iLoop++] = *pszText++; if ( szStore[iLoop-1] >= 'a' && szStore[iLoop-1] <= 'z' ) szStore[iLoop-1] = UPPER( szStore[iLoop] ); /* The first loop goes through the string, copying it into szStore. The * string is formatted to remove all newlines, capitalise new sentences, * remove excess white spaces and ensure that full stops, commas and * exclaimation marks are all followed by two white spaces. */ while ( *pszText ) { switch ( *pszText ) { default: szStore[iLoop++] = *pszText++; break; case ' ': if ( *(pszText+1) != ' ' ) { /* Store the character */ szStore[iLoop++] = *pszText; } pszText++; break; case '.': case '?': case '!': szStore[iLoop++] = *pszText++; switch ( *pszText ) { default: szStore[iLoop++] = ' '; szStore[iLoop++] = ' '; /* Discard all leading spaces */ while ( *pszText == ' ' ) pszText++; /* Store the character */ szStore[iLoop++] = *pszText++; if ( szStore[iLoop-1] >= 'a' && szStore[iLoop-1] <= 'z' ) szStore[iLoop-1] &= ~32; break; case '.': case '?': case '!': break; } break; case ',': /* Store the character */ szStore[iLoop++] = *pszText++; /* Discard all leading spaces */ while ( *pszText == ' ' ) pszText++; /* Commas shall be followed by one space */ szStore[iLoop++] = ' '; break; case '$': szStore[iLoop++] = *pszText++; while ( *pszText == ' ' ) pszText++; break; case '\n': case '\r': pszText++; break; } } szStore[iLoop] = '\0'; /* Initialise iMax to the size of szStore */ iMax = strlen( szStore ); /* The second loop goes through the string, inserting newlines at every * appropriate point. */ while ( iLength < iMax ) { /* Go backwards through the current line searching for a space */ while ( szStore[iLength] != ' ' && iLength > 1 ) iLength--; if ( szStore[iLength] == ' ' ) { szStore[iLength] = '\n'; iLength += iAlignment; } else break; } /* Reset the counter */ iLoop = 0; /* The third and final loop goes through the string, making sure that there * is a \r (return to beginning of line) following every newline, with no * white spaces at the beginning of a particular line of text. */ while ( iLoop < iMax ) { /* Store the character */ *pszResult++ = szStore[iLoop]; switch ( szStore[iLoop] ) { default: break; case '\n': *pszResult++ = '\r'; while ( szStore[iLoop+1] == ' ' ) iLoop++; /* Add spaces to the front of the line as appropriate */ AddSpaces( &pszResult, 25 ); break; } iLoop++; } *pszResult++ = '\0'; return( &s_szResult[0] ); } int num_changes( void ) { char *test; int today; int i; i = 0; test = current_date(); today = 0; for ( i = 0; i < maxChanges; i++) if (!str_cmp(test,changes_table[i].date)) today++; return today; } void do_changes(CHAR_DATA *ch, char *argument) { char arg[MAX_INPUT_LENGTH]; char buf[MSL]; char *test; int today; int i; bool fAll; one_argument( argument, arg ); if (IS_NPC(ch)) return; if( maxChanges < 1 ) return; i = 0; test = current_date(); today = 0; for ( i = 0; i < maxChanges; i++) if (!str_cmp(test,changes_table[i].date)) today++; if( NULLSTR( arg ) ) fAll = FALSE; else fAll = !str_cmp( arg, "all" ); send_to_char("&YNo. Coder Date Change&d\n\r",ch ); send_to_char("&b---------------------------------------------------------------------------\n\r", ch ); for (i = 0; i < maxChanges; i++) { if( !fAll && changes_table[i].mudtime + (7*24L*3600L) < current_time ) continue; sprintf( buf,"&R[&w%2d&Y]&W %-9s &C*%-6s &d%-55s&d\n\r", (i+1), changes_table[i].coder , changes_table[i].date, changes_table[i].change ); //change_justify( changes_table[i].change, 55 )); send_to_char( buf, ch ); } send_to_char("&b---------------------------------------------------------------------------\n\r", ch ); sprintf(buf, "&YThere is a total of &R[ &w%3d &R] &Ychanges in the database.&d\n\r", maxChanges); send_to_char( buf, ch ); send_to_char("&YAlso see&B: &R'&wchanges all&R'&Y for a list of all the changes.&z\n\r",ch); send_to_char("&b---------------------------------------------------------------------------\n\r", ch ); sprintf(buf, "&YThere is a total of &R[ &w%2d &R] &Ynew changes that have been added today.&d\n\r", today); send_to_char( buf, ch ); send_to_char("&b---------------------------------------------------------------------------\n\r", ch ); return; } ------------------------------------------------------------------------------------------------- mud.h Find, typedef struct killed_data KILLED_DATA; Below it add, typedef struct changes_data CHANGE_DATA; Find this structure data, struct killed_data { int vnum; char count; }; Below it add, struct changes_data { char * change; char * coder; char * date; time_t mudtime; }; Find, DECLARE_DO_FUN( do_affected ); Above it add, DECLARE_DO_FUN( do_addchange ); Find, DECLARE_DO_FUN( do_channels ); Below it add, DECLARE_DO_FUN( do_changes ); Find, DECLARE_DO_FUN( do_check_vnums ); Below it add, DECLARE_DO_FUN( do_chsave ); Find, #define IDEA_FILE SYSTEM_DIR "ideas.txt" /* For 'idea' */ Below it add, #define CHANGE_FILE SYSTEM_DIR "changes.txt" /* Changes file - txt */ Find, /* build.c */ This part should have a bunch of declarations for the build.c file Below all of the declarations add, /* changes.c */ void load_changes args( (void) ); void save_changes args( (void) ); void delete_change args( (int num) ); ------------------------------------------------------------------------------------------------- tables.c Find, if ( !str_cmp( name, "do_addbounty" )) return do_addbounty; Below it add, if ( !str_cmp( name, "do_addchange" )) return do_addchange; Find, if ( !str_cmp( name, "do_chaff" )) return do_chaff; Below it add, if ( !str_cmp( name, "do_changes" )) return do_changes; Find, if ( !str_cmp( name, "do_check_vnums" )) return do_check_vnums; Below it add, if ( !str_cmp( name, "do_chsave" )) return do_chsave; Find, if ( skill == do_addpilot ) return "do_addpilot"; Below it add, if ( skill == do_addchange ) return "do_addchange"; Find, if ( skill == do_chat ) return "do_chat"; Below it add, if ( skill == do_changes ) return "do_changes"; Find, if ( skill == do_check_vnums ) return "do_check_vnums"; Below it add, if ( skill == do_chsave ) return "do_chsave"; ------------------------------------------------------------------------------------------------- Go to your system directory, which can be found by typing, cd
    /system pico changes.txt type something in it and erase it all, just so it asks you to save when you exit. You must type something or it won't ask, save that file as changes.txt ------------------------------------------------------------------------------------------------- make clean make copyover/reboot your mud cedit addchange create cedit chset create cedit changes create cedit addchange level (preferred level) cedit chset level (preferred level) cedit changes level 1 -,,,.,,,,- _'Diablo'_ Star Wars Development '''''' [*]------------------------------------------------[*] ||| If you have any problems please contact me at: ||| ||| crazy_mike_316@hotmail.com ||| [*]------------------------------------------------[*]