/*
* 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 '<channel> history'. Enjoy :) Suggestions for improvement are welcome!