/* * Channel history! Very simple to plug into any Merc/Diku derived MUD using talk_channel() to pass all the info. * It could probably be more elegant, like storing the output directly from act(), but hey, it works :) * Thanks to Abel of StormHunters for the bv_log routine! * * Feel free to modify this code to suit your needs, and if you have a great improvement I wouldn't mind if you * shared it with me either, if you're so inclined :D. All I ask is to give me credit for the code if you do * choose to use it. * * --Kline (Matt Goff) */ STEP 1 Add the following define in a .h someplace: #define MAX_HISTORY 20 /* History per channel */ STEP 2 In your main .h (merc.h, ack.h, etc) add the following with the other structs: struct chanhistory { time_t time[30][MAX_HISTORY]; char message[30][MAX_HISTORY][MAX_STRING_LENGTH]; /* 30 channels, each with MAX_HISTORY, length of MSL */ }; STEP 3 Add the following whereever you keep your typedefs (typedefs.h in ack): typedef struct chanhistory CHAN_HISTORY; STEP 4 Add the following in some .c file (probably db.c with the other mud-wide structs): CHAN_HISTORY chan_history; INFO My MUD uses bitvectors to toggle channels, if yours doesn't, skip directly to STEP 5 and remove references to bv_log. Just replace that with the int value of the channel, or whatever you use If you use bitvectors for channels, too, this will work as-is. STEP 5 Also add the following somewhere near all the db.c functions: int bv_log args( ( int n ) ); STEP 6 In db.c, add the following to the bottom of the file: int bv_log( int n ) { int result = 0; while( n > 0 ) { n >>= 1; result++; } return result; } STEP 7 Find the talk_channel() function, probably in act_comm.c. Below the block if( argument[0] == '0' ) add: if( !str_cmp(argument,"history") ) { sh_int x,y = 0; bool found = FALSE; x = (bv_log(channel)-1); for( y = 0; y < MAX_HISTORY; y++ ) if( chan_history.message[x][y][0] != '\0' ) { if( IS_IMMORTAL(ch) ) { found = TRUE; sprintf(buf,"[%s",ctime(&chan_history.time[x][y])); buf[(strlen(buf)-1)] = '\0'; /* I realize how ugly this chunk looks but it was */ strcat(buf,"] "); /* necessary to get around ctime adding a newline --Kline */ strcat(buf,chan_history.message[x][y]); send_to_char(buf,ch); } else if( ch->logon <= chan_history.time[x][y] ) { found = TRUE; send_to_char(chan_history.message[x][y],ch); } } if( !found ) send_to_char("No history available for that channel yet.\n\r",ch); return; } STEP 8 At the bottom of talk_channel, right above the return;, add the following: { sh_int x,y = 0; x = (bv_log(channel)-1); for( y = 0; y < MAX_HISTORY; y++ ) { if( chan_history.message[x][y] == '\0' ) { sprintf(chan_history.message[x][y],"%s: %s@@N\n\r",IS_NPC(ch) ? ch->short_descr : ch->name,argument); chan_history.time[x][y] = current_time; break; } if( y == (MAX_HISTORY -1) ) { int i = 0; for( i = 1; i < MAX_HISTORY; i++ ) { sprintf(chan_history.message[x][(i-1)],chan_history.message[x][i]); chan_history.time[x][(i-1)] = chan_history.time[x][i]; } chan_history.message[x][y][0] = '\0'; chan_history.time[x][y] = 0; sprintf(chan_history.message[x][y],"%s: %s@@N\n\r",IS_NPC(ch) ? ch->short_descr : ch->name,argument); chan_history.time[x][y] = current_time; } } } That's it! All done! You can adjust parameters as needed, and can view history per channel by using ' history'. Enjoy :) Suggestions for improvement are welcome!