AFKMud Message Boards
---------------------

Prerequisite Requirements
-------------------------

Terms of Use
------------

1. You may use this snippet in your code provided that any included
comment headers in the code are left intact. You may add your own, but
do not take mine out.

2. This snippet may not be posted for redistribution on any site
without obtaining prior written consent from the Alsherok team.

3. ( optional ) Register with the forums at http://www.smaugmuds.org
Registration is not required to make use of the snippet, but since I no
longer provide email support for any of the code I release, forum posts
are your only avenue for direct support. This may seem overly stupid,
but you can blame the continuing abuse I suffer from spammers for this.
Don't post stuff to TMC or TMS asking about my code. I'm highly unlikely
to ever notice it there on the rare ocassions I skim posts in either place.

If forum registration doesn't appeal to you, then you can try to get ahold
of me via IMC on the code channel.

If you can't agree to these terms, don't use this code, and don't expect
me to help if something breaks while installing it. Harsh? Hardly. I'm
tired of people who come crawling to whine and complain when they haven't
bothered to comply with the terms first.

What this code does
-------------------

This code replaces the standard board system in Smaug with a more modern system that
behaves more like an actual web forum with topics and linear replies. Boards can be
either local and require an object to function, or globals that do not require objects.
It basically takes the best of both systems and merges it into one.

This code also replaces the existing projects code with a new version since the projects
code relies heavily on the board code to operate. The player comments code is also covered
by this as it uses the note system to operate.

Existing data from *UNMODIFIED* stock boards should be converted into the new system when
the code has been installed and the game boots up.

Installation Instructions
-------------------------

Before getting started, make backups of you code. For the love of God, don't ignore this step.

1. Upload boards.c, boards.h, and comments.c to your src directory. Overwrite the files that are there now.
(You did backup first, yes?)

2. In mud.h, locate and remove the following lines:

typedef struct note_data NOTE_DATA;
typedef struct board_data BOARD_DATA;
typedef struct project_data PROJECT_DATA;

extern BOARD_DATA *first_board;
extern BOARD_DATA *last_board;

extern PROJECT_DATA *first_project;
extern PROJECT_DATA *last_project;

#define BOARD_FILE      "boards.txt"   /* For bulletin boards   */

/* boards.c */
void load_boards args( ( void ) );
BD *get_board args( ( OBJ_DATA * obj ) );
void free_note args( ( NOTE_DATA * pnote ) );

Find and remove struct project_data, struct note_data, and struct board_data

In struct char_data, locate the following:

   NOTE_DATA *pnote;
   NOTE_DATA *comments;

Replace it with:

   struct note_data *pnote;

[Yes, remove the *comments pointer]

In struct pc_data, add the following with the other pointer definitions:

   struct board_chardata *first_boarddata;
   struct board_chardata *last_boarddata;
   struct note_data *first_comment;
   struct note_data *last_comment;
   struct board_data *board;

Locate the following:

CON_EDITING

Add the following constate to the list:

CON_BOARD

Locate the following:

   SUB_PROJ_DESC, SUB_NEWS_POST, SUB_NEWS_EDIT,

Below that line, add:

   SUB_BOARD_TO, SUB_BOARD_SUBJECT,
   SUB_BOARD_STICKY, SUB_BOARD_TEXT, SUB_BOARD_CONFIRM, SUB_BOARD_REDO_MENU,
   SUB_EDIT_ABORT,

Locate the following:

/*
 * Command functions.
 * Defined in act_*.c (mostly).
 */

Below that, add:

DECLARE_DO_FUN( do_board_alert );
DECLARE_DO_FUN( do_board_list );
DECLARE_DO_FUN( do_board_make );
DECLARE_DO_FUN( do_board_remove );
DECLARE_DO_FUN( do_board_set );
DECLARE_DO_FUN( do_board_stat );
DECLARE_DO_FUN( do_checkboards );
DECLARE_DO_FUN( do_note_list );
DECLARE_DO_FUN( do_note_read );
DECLARE_DO_FUN( do_note_remove );
DECLARE_DO_FUN( do_note_set );
DECLARE_DO_FUN( do_note_write );

3. In act_wiz.c, locate and remove the following functions:

do_project, get_project_by_number, and get_log_by_number

Then locate the following at the top of the file and remove it:

PROJECT_DATA *get_project_by_number( int pnum );
NOTE_DATA *get_log_by_number( PROJECT_DATA * pproject, int pnum );

4. In act_info.c, locate the following code fragments and remove them:

   BOARD_DATA *board;

      if( ( board = get_board( obj ) ) != NULL )
      {
         if( board->num_posts )
            ch_printf( ch, "There are about %d notes posted here.  Type 'note list' to list them.\r\n", board->num_posts );
         else
            send_to_char( "There aren't any notes posted here.\r\n", ch );
      }

5. In comm.c, locate the following:

const char echo_off_str[] = { ( char )IAC, ( char )WILL, TELOPT_ECHO, '\0' };
const char echo_on_str[] = { ( char )IAC, ( char )WONT, TELOPT_ECHO, '\0' };
const char go_ahead_str[] = { ( char )IAC, ( char )GA, '\0' };

void save_sysdata( SYSTEM_DATA sys );

Below that, add:

void board_parse( DESCRIPTOR_DATA * d, char *argument );

Then locate the following code in nanny:


      case CON_READ_MOTD:
         nanny_read_motd( d, argument );
         break;

Below that, add:

      case CON_BOARD:
         board_parse( d, argument );
         break;

6. in db.c, locate and remove the following:

PROJECT_DATA *first_project;
PROJECT_DATA *last_project;

PROJECT_DATA *read_project( FILE * fp );
NOTE_DATA *read_log( FILE * fp );

In db.c where the other external prototypes are, add:

void load_boards( void );
void free_comments( CHAR_DATA * ch );
void free_pcboards( CHAR_DATA * ch );
void free_note( struct note_data * pnote );

The locate and remove the following functions:

load_projects, read_project, read_log, and write_projects

Find the free_char function and remove:

   NOTE_DATA *comments, *comments_next;

Then locate this block of code:

      if( ch->pcdata->pet )
      {
         extract_char( ch->pcdata->pet, TRUE );
         ch->pcdata->pet = NULL;
      }

Below that, add:

      free_comments( ch );
      free_pcboards( ch );

Then locate this block of code and remove it:

   for( comments = ch->comments; comments; comments = comments_next )
   {
      comments_next = comments->next;
      STRFREE( comments->text );
      STRFREE( comments->to_list );
      STRFREE( comments->subject );
      STRFREE( comments->sender );
      STRFREE( comments->date );
      DISPOSE( comments );
   }

7. In mapout.c, add the following to the includes list:

#include "boards.h"

Then in do_mapout, locate and remove:

      STRFREE( ch->pnote->date );

8. In save.c, add the following to the includes list at the top:

#include "boards.h"

Then locate the following code in fwrite_char:

   /*
    * Save color values - Samson 9-29-98 
    */
   {
      int x;
      fprintf( fp, "MaxColors    %d\n", MAX_COLORS );
      fprintf( fp, "Colors       " );
      for( x = 0; x < MAX_COLORS; x++ )
         fprintf( fp, "%d ", ch->colors[x] );
      fprintf( fp, "\n" );
   }

Below that, add the following:

   if( ch->pcdata->first_boarddata )
   {
      BOARD_CHARDATA *chboard, *chboard_next;

      for( chboard = ch->pcdata->first_boarddata; chboard; chboard = chboard_next )
      {
         chboard_next = chboard->next;

         /*
          * Ugh.. is it worth saving that extra board_chardata field on pcdata? 
          */
         /*
          * No, Xorith, it wasn't. So I changed it - Samson 10-15-03 
          */
         if( !chboard->board_name )
         {
            UNLINK( chboard, ch->pcdata->first_boarddata, ch->pcdata->last_boarddata, next, prev );
            STRFREE( chboard->board_name );
            DISPOSE( chboard );
            continue;
         }
         fprintf( fp, "Board_Data   %s~ %ld %d\n", chboard->board_name, ( long int )chboard->last_read, chboard->alert );
      }
   }

Then locate the following code in fread_char:

            KEY( "Bamfin", ch->pcdata->bamfin, fread_string_nohash( fp ) );
            KEY( "Bamfout", ch->pcdata->bamfout, fread_string_nohash( fp ) );
            KEY( "Bestowments", ch->pcdata->bestowments, fread_string_nohash( fp ) );
            KEY( "Bio", ch->pcdata->bio, fread_string( fp ) );

Below that, add:

            if( !str_cmp( word, "Board_Data" ) )
            {
               BOARD_CHARDATA *pboard;
               BOARD_DATA *board;

               word = fread_flagstring( fp );
               if( !( board = get_board( NULL, word ) ) )
               {
                  log_printf( "Player %s has board %s which apparently doesn't exist?", ch->name, word );
                  ch_printf( ch, "Warning: the board %s no longer exsists.\n\r", word );
                  fread_to_eol( fp );
                  fMatch = TRUE;
                  break;
               }
               CREATE( pboard, BOARD_CHARDATA, 1 );
               pboard->board_name = QUICKLINK( board->name );
               pboard->last_read = fread_number( fp );
               pboard->alert = fread_number( fp );
               LINK( pboard, ch->pcdata->first_boarddata, ch->pcdata->last_boarddata, next, prev );
               fMatch = TRUE;
               break;
            }

Then locate the following code in save_char_obj:

      if( ch->comments )   /* comments */
         fwrite_comments( ch, fp ); /* comments */

Change it to:

      if( ch->pcdata->first_comment )   /* comments */
         fwrite_comments( ch, fp ); /* comments */

Then locate the following code in load_char_obj:

   ch->comments = NULL; /* comments */

Change it to:

   ch->pcdata->first_comment = ch->pcdata->last_comment = NULL;

9. Make clean, recompile.

10. Once done compiling, boot the game and create the following commands using cedit:

User commands:

boards, code = do_board_list
alert, code = do_board_alert
read, code = do_note_read
write, code = do_note_write
review, code = do_note_list
erase, code = do_note_remove
checkboards, code = do_checkboards

Staff commands:

makeboard, code = do_board_make
deleteboard, code = do_board_remove
bset, code = do_board_set
bstat, code = do_board_stat
nset, code = do_note_set
bmod, code = do_board_moderate

If some of these commands already exist, replace their existing code with the new one.

11. Add the help files to the help.are file that are included in afkboards.help.
Replace any existing entries as needed with the new ones.

If there are any problems with this installation, feel free to post your
question to the forums at http://www.smaugmuds.org

This code has been installed and tested on Smaug 1.9 FUSS, which is a bugfixed
and cleaned up version of the base Smaug 1.4a code. The Smaug FUSS Project is
maintained on servers which run the Redhat and Fedora family of Linux. Limited
testing has also been done on the Cygwin package under WindowsXP SP1 and SP2.
Users of BSD, MSVC, MSVC++, or Macintosh platforms are on their own as The
Smaug FUSS Project does not have access to these development environments for testing.
The Smaug FUSS Project can be found at: http://www.smaugmuds.org

No guarantees are made that this code will be compatible with your codebase and any
modifications you may have made to it. No warranty of any kind is expressed or implied
by the use of this code, and we are not responsible for any damages which may result
from the application of this snippet to your codebase.