/* This follows a similar idea to the grenade damage. Whomever wrote it gets my kudos, I've only converted it over for
 * casual speech. I used this for shout/yell, but it can be used for other channels as well, such
 * as hollar, etc. This can all be input directly into act_comm.c
 * -Lajos
 */

/* Put this somewhere after the includes */
#if defined(BFS_MARK)
#undef BFS_MARK
#endif
#define BFS_MARK         BV01

/* With the function definitions. */
void    transfer_speech args( ( CHAR_DATA *ch, char * argument, ROOM_INDEX_DATA *startroom, char speech[MAX_STRING_LENGTH], int range, int channel) );
void    clear_bfs_mark  args( ( ROOM_INDEX_DATA *firstroom, int range ) );/* Clear the bfs mark within radius */

/* Put this in talk_channel after the log channel stuff */
    /* The range is the number after the buf, its very easy to change, should you want to tweak the max
     * room distance.
     */
    if (channel == CHANNEL_YELL || channel == CHANNEL_SHOUT )
    {
        if(channel == CHANNEL_YELL )
        {
           transfer_speech( ch, argument, ch->in_room, buf, 5, CHANNEL_YELL);
           clear_bfs_mark( ch->in_room, 5 );
        }
        else
        {
           transfer_speech( ch, argument, ch->in_room, buf, 10, CHANNEL_SHOUT );
           clear_bfs_mark( ch->in_room, 10 ); 
        }
        return;
    }


/* Just install the rest here at the end of the file */
/* A command I created so that I can send speech in a radius without being shitty or wasteful.
 * -Arcturus
 */
void transfer_speech( CHAR_DATA *ch, char *argument, ROOM_INDEX_DATA *startroom, char speech[MAX_STRING_LENGTH], int range, int channel )
{
    EXIT_DATA *pexit;
    CHAR_DATA *rch;
    CHAR_DATA *rnext;

    if ( IS_SET( startroom->room_flags, BFS_MARK ) ) /* so that rooms don't repeat. */
        return;
    if ( IS_SET( startroom->room_flags, ROOM_SILENCE ) ) /* Don't cross into silent rooms... */
        return;

    SET_BIT( startroom->room_flags , BFS_MARK );

    for ( rch = startroom->first_person ; rch ;  rch = rnext )
    {
       rnext = rch->next_in_room;
       if ( rch != ch
       &&  !IS_SET(rch->deaf, channel) )
       {
          char *sbuf = argument;
          if (  !knows_language( rch, ch->speaking, ch ) &&
             ( !IS_NPC(ch) || ch->speaking != 0 ) )
             sbuf = scramble(argument, ch->speaking);
          act( AT_GOSSIP, speech, ch, sbuf, rch, TO_VICT );
      }
    }

    for ( pexit = startroom->first_exit; pexit; pexit = pexit->next )
    { /* Exit loop */
        if ( pexit->to_room
        &&   pexit->to_room != startroom )
        { /* If its an exit that hasn't been checked... */
             if ( range > 0 ) /* if its been used, and theres a range, keep going */
                transfer_speech( ch, argument, pexit->to_room, speech, range - 1, channel );
        }
    }
}


/* Just like any good code that uses a BFS_MARK, we have to be able to clear it.
 * -Arcturus
 */
void clear_bfs_mark( ROOM_INDEX_DATA *firstroom, int range ) /* Clear the bfs mark within radius */
{
    EXIT_DATA *pexit;
    if ( !IS_SET( firstroom->room_flags, BFS_MARK ) ) /* so that rooms don't repeat. */
        return;
    REMOVE_BIT( firstroom->room_flags , BFS_MARK );

    for ( pexit = firstroom->first_exit; pexit; pexit = pexit->next )
    { /* Exit loop */
        if ( pexit->to_room
        &&   pexit->to_room != firstroom )
        { /* If its an exit that hasn't been checked... */
             if ( range > 0 ) /* if its been used, and theres a range, keep going */
                clear_bfs_mark( pexit->to_room, range - 1 );
        }
    }
}

#undef BFS_MARK