/*Well, I figured I might as well through this up for open source.
 *What it is, is a channel snippet that replaces all globle channels,
 *Unless you have some odd modifications, but those can be easily worked
 *around. This Channel System was writen by Davvol, and myself Davion.
 *it supports emotes, and socials over the channels. It is also simple
 *to add another, just add a the required parts to the table and so on.
 *anyways, have fun with it :)
*/

//In act_comm.c or where you want to put it-
//Put these at the top, under the #include's.
void do_newchan args ( ( CHAR_DATA *ch, char *argument, int channel) );
bool smote_check args ( (CHAR_DATA *ch, char *argument, char *emote, int channel ) );
bool echo_check args ( (CHAR_DATA *ch, char *argument, char *emote, int channel ) );
bool check_chansocial( CHAR_DATA *ch, char *command, char *argument, int channel );

//These, where ever, top, bottom, up to you :)
void do_ooc( CHAR_DATA *ch, char *argument)	    
{
	do_newchan( ch, argument, CHAN_OOC );
	return;
}
void do_gossip( CHAR_DATA *ch, char *argument)	    
{
	do_newchan( ch, argument, CHAN_GOSSIP );
	return;
}
void do_quote( CHAR_DATA *ch, char *argument)	    
{
	do_newchan( ch, argument, CHAN_QUOTE );
	return;
}
void do_grats( CHAR_DATA *ch, char *argument)	    
{
	do_newchan( ch, argument, CHAN_GRATS );
	return;
}
void do_question( CHAR_DATA *ch, char *argument)	    
{
	do_newchan( ch, argument, CHAN_QA );
	return;
}
void do_auction( CHAR_DATA *ch, char *argument)	    
{
	do_newchan( ch, argument, CHAN_AUCT );
	return;
}
void do_music( CHAR_DATA *ch, char *argument)	    
{
	do_newchan( ch, argument, CHAN_MUSIC );
	return;
}
void do_immtalk( CHAR_DATA *ch, char *argument)	    
{
	do_newchan( ch, argument, CHAN_IMM );
	return;
}
void do_clanchat( CHAR_DATA *ch, char *argument)	    
{
	do_newchan( ch, argument, CHAN_CLAN );
	return;
}

void do_newchan( CHAR_DATA *ch, char *argument, int channel)
{
	char arg[MSL];
	char arg2[MSL];
	char talk[2*MSL], pre[MSL];
	char emote[2*MSL];
	char buf[MAX_STRING_LENGTH];
    DESCRIPTOR_DATA *d;

	if (channel == CHAN_CLAN)
	{
		if (!is_clan(ch) || clan_table[ch->clan].independent)
		{
		send_to_char("You aren't in a clan.\n\r",ch);
		return;
		}
	}

    if (argument[0] == '\0' )
    {
      if (IS_SET(ch->comm,chan_table[channel].bit))
      {
		sprintf( buf, "The %s {xchannel is now ON.\n\r", chan_table[channel].chan_pre );
		send_to_char( buf, ch );
		REMOVE_BIT(ch->comm,chan_table[channel].bit);
		return;
      }
      else
      {
		sprintf( buf, "The %s {xchannel is now OFF.\n\r", chan_table[channel].chan_pre );
		send_to_char( buf, ch );
		SET_BIT(ch->comm,chan_table[channel].bit);
		return;
      }
    }
    else  /* message sent, toggle channel on/off */
	{
		if (IS_SET(ch->comm,COMM_QUIET))
		{
		  send_to_char("You must turn off quiet mode first.\n\r",ch);
		  return;
		}

		if (IS_SET(ch->comm,COMM_NOCHANNELS))
		{
		send_to_char("The gods have revoked your channel priviliges.\n\r",ch);
		return;
		}

		if (IS_SET(ch->comm,chan_table[channel].bit))
		{
		send_to_char("Try turning the channel on?\n\r",ch);
		return;
		}
    }

    arg2[0] = '\0';
	sprintf( talk, "%s", argument );
    one_argument(argument, arg);
    argument = one_argument(argument,arg);
	sprintf( emote, "%s", argument );
    argument = one_argument(argument,arg2);

      if(check_chansocial(ch,arg,arg2,channel))
	     return;

	if(!strcmp(arg, "emote"))
    {
		argument = one_argument(argument,arg);

		if(channel != CHAN_CLAN)
			sprintf( buf, "%s {%s$n %s{x", chan_table[channel].chan_pre, chan_table[channel].chan_name, emote);  
		else
			sprintf( buf, "%s {%s$n %s{x", clan_table[ch->clan].who_name, chan_table[channel].chan_name, emote);  
	 
		act_new(buf,ch,argument,NULL,TO_CHAR,POS_DEAD);	
		for ( d = descriptor_list; d != NULL; d = d->next )
		{
			if ( d->connected == CON_PLAYING &&
				 d->character != ch &&
				 !IS_SET(d->character->comm,chan_table[channel].bit) &&
				 !IS_SET(d->character->comm,COMM_QUIET) )
				 {
					if ((channel == CHAN_IMM) && (!IS_IMMORTAL(d->character)))
						continue;
					if (channel == CHAN_CLAN && !is_same_clan(ch,d->character))
						continue;
					act_new(buf, ch, argument, d->character, TO_VICT, POS_DEAD);
				}	
			}
		 return;
    }

    if(!strcmp(arg, "smote"))
    {
		if(smote_check(ch, arg, emote, channel))
			return;
    }   

	if(!strcmp(arg, "echo"))
    {
		if(echo_check(ch,arg,emote,channel))
			return;
    }

    if(channel == CHAN_CLAN)
		sprintf(pre, "%s", clan_table[ch->clan].who_name);
    else
		sprintf(pre, "%s", chan_table[channel].chan_pre);

    sprintf( buf, "%s {%s$n says '{%s%s{%s'{x", 
	  	pre,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		talk,
		chan_table[channel].chan_name);

	printf_to_char( ch, "%s {%sYou say '{%s%s{%s'{x\n\r", pre, chan_table[channel].chan_name,
		chan_table[channel].chan_say, talk, chan_table[channel].chan_name );
	
    for ( d = descriptor_list; d != NULL; d = d->next )
    {
		if ( d->connected == CON_PLAYING &&
			 d->character != ch &&
			 !IS_SET(d->character->comm,chan_table[channel].bit) &&
			 !IS_SET(d->character->comm,COMM_QUIET) )
		{
			if ((channel == CHAN_IMM) && (!IS_IMMORTAL(d->character)))
				continue;
			if (channel == CHAN_CLAN && !is_same_clan(ch,d->character))
				continue;

			act_new(buf, ch, argument, d->character, TO_VICT, POS_DEAD);
 		}
    }
}


bool smote_check(CHAR_DATA *ch, char *argument, char *emote, int channel )
{
    CHAR_DATA *vch;
    char *letter,*name;
    char last[MAX_INPUT_LENGTH], temp[MAX_STRING_LENGTH];
    int matches = 0;
    char pre[MSL], buf[MSL];
    DESCRIPTOR_DATA *d; 
    if ( !IS_NPC(ch) && IS_SET(ch->comm, COMM_NOEMOTE) )
    {
	return FALSE;
    }
 
    if ( argument[0] == '\0' )
    {
	return FALSE;
    }
    
    if (strstr(emote,ch->name) == NULL)
    {
	send_to_char("You must include your name in an smote.\n\r",ch);
	return TRUE;
    }
    if(channel == CHAN_CLAN)
       strcat(pre, clan_table[ch->clan].who_name);
    else
	 strcat(pre, chan_table[channel].chan_pre);
    sprintf( buf, "%s {%s%s{x", 
		pre,
		chan_table[channel].chan_name,
	      emote); 

    send_to_char(buf,ch);
    send_to_char("\n\r",ch);
 
    for ( d = descriptor_list; d != NULL; d = d->next )
    {
        vch = d->original ? d->original : d->character; 
		if ( d->connected == CON_PLAYING &&
			 d->character != ch &&
			 !IS_SET(d->character->comm,chan_table[channel].bit) &&
			 !IS_SET(d->character->comm,COMM_QUIET) )
		{
			if ((channel == CHAN_IMM) && (!IS_IMMORTAL(d->character)))
			{
				return TRUE;
			}
			if (channel == CHAN_CLAN && !is_same_clan(ch,d->character))
			{
				return TRUE;
			}
        if (vch->desc == NULL || vch == ch)
            continue;
 
        if ((letter = strstr(argument,vch->name)) == NULL)
        {
		act_new(buf,ch,NULL,vch,TO_VICT,POS_DEAD);
            continue;
        }
 
        strcpy(temp,emote);
        temp[strlen(emote) - strlen(letter)] = '\0';
        last[0] = '\0';
        name = vch->name;
 
        for (; *letter != '\0'; letter++)
        {
            if (*letter == '\'' && matches == strlen(vch->name))
            {
                strcat(temp,"r");
                continue;
            }
 
            if (*letter == 's' && matches == strlen(vch->name))
            {
                matches = 0;
                continue;
            }
 
            if (matches == strlen(vch->name))
            {
                matches = 0;
            }
 
            if (*letter == *name)
            {
                matches++;
                name++;
                if (matches == strlen(vch->name))
                {
                    strcat(temp,"you");
                    last[0] = '\0';
                    name = vch->name;
                    continue;
                }
                strncat(last,letter,1);
                continue;
            }
 
            matches = 0;
            strcat(temp,last);
            strncat(temp,letter,1);
            last[0] = '\0';
            name = vch->name;
        }
 
		act_new(buf,ch,NULL,vch,TO_VICT,POS_DEAD);


    }
	return TRUE;
  } 
    return FALSE;
}
bool echo_check(CHAR_DATA *ch, char *argument, char *emote, int channel)
{
    DESCRIPTOR_DATA *d;
    char pre[MSL], buf[MSL];

    if ( argument[0] == '\0' )
    {
	return FALSE;
    }
    if(!IS_IMMORTAL(ch));
	return FALSE;

    if(channel == CHAN_CLAN)
       strcat(pre, clan_table[ch->clan].who_name);
    else
	 strcat(pre, chan_table[channel].chan_pre);    
    sprintf( buf, "%s {%s%s{x", 
		pre,
		chan_table[channel].chan_name,
	      emote); 
	send_to_char(buf,ch);
	send_to_char("\n\r",ch);
    for ( d = descriptor_list; d != NULL; d = d->next )
    {
	CHAR_DATA *vch;
        vch = d->original ? d->original : d->character; 
		if ( d->connected == CON_PLAYING &&
			 d->character != ch &&
			 !IS_SET(d->character->comm,chan_table[channel].bit) &&
			 !IS_SET(d->character->comm,COMM_QUIET) )
		{
			if ((channel == CHAN_IMM) && (!IS_IMMORTAL(d->character)))
			{
				return TRUE;
			}
			if (channel == CHAN_CLAN && !is_same_clan(ch,d->character))
			{
				return TRUE;
			}
			act_new(buf,ch,NULL,vch,TO_VICT,POS_DEAD);
   		}
	return TRUE;
    }
    return FALSE;
}

bool check_chansocial( CHAR_DATA *ch, char *command, char *argument, int channel )
{
    char arg[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;
    int cmd;
    bool found;
    char buf[MSL];
    int counter;
    int count;
    char buf2[MSL];        
    char buf3[MSL];
    DESCRIPTOR_DATA *d;
    buf[0] = '\0';
    buf2[0] = '\0';
    buf3[0] = '\0';
    found  = FALSE;
    for ( cmd = 0; social_table[cmd].name[0] != '\0'; cmd++ )
    {
	if ( command[0] == social_table[cmd].name[0]
	&&   !str_prefix( command, social_table[cmd].name ) )
	{
	    found = TRUE;
	    break;
	}
    }

    if ( !found )
	return FALSE;

    one_argument( argument, arg );
    victim = NULL;
    if ( arg[0] == '\0' )
    {
      if(channel != CHAN_CLAN)    
	{
      sprintf( buf, "%s {%s{%s%s{%s{x",
		chan_table[channel].chan_pre,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].others_no_arg,
		chan_table[channel].chan_name);

      sprintf( buf2, "%s {%s{%s%s{%s{x\n\r",
		chan_table[channel].chan_pre,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].char_no_arg,
		chan_table[channel].chan_name);
	}
	else
	{
      sprintf( buf, "%s {%s{%s%s{%s{x",
		clan_table[ch->clan].who_name,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].others_no_arg,
		chan_table[channel].chan_name);

      sprintf( buf2, "%s {%s{%s%s{%s{x\n\r",
		clan_table[ch->clan].who_name,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].char_no_arg,
		chan_table[channel].chan_name);
	}
	for (d = descriptor_list; d != NULL; d = d->next)
	{
	    CHAR_DATA *vch;
	    vch = d->original ? d->original : d->character;
	    if (d->connected == CON_PLAYING &&
		  d->character != ch &&
		  !IS_SET(vch->comm,chan_table[channel].bit) &&
	 	  !IS_SET(vch->comm,COMM_QUIET))
	    {
          	if ((channel == CHAN_IMM) && (!IS_IMMORTAL(d->character)))
          	{
            return TRUE;
            }
            if (channel == CHAN_CLAN && !is_same_clan(ch,d->character))
            {
            return TRUE;
            } 
		act_new(buf,ch,NULL,vch,TO_VICT,POS_DEAD);
          }
       }
	send_to_char(buf2,ch);	
    }
    else if ( ( victim = get_char_world( ch, arg ) ) == NULL || IS_NPC(victim))
    {
	return FALSE;
    }	
    else if(IS_SET(victim->comm,chan_table[channel].bit))
    	{
	    send_to_char("They cannot see this channel, therefor you cannot do that to them.\n\r",ch);
    	    return TRUE;
      }
    else if ( victim == ch )
    {
	if(channel != CHAN_CLAN)
	{
      sprintf( buf, "%s {%s{%s%s{%s{x",
		chan_table[channel].chan_pre,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].others_auto,
		chan_table[channel].chan_name);

      sprintf( buf2, "%s {%s{%s%s{%s{x\n\r",
		chan_table[channel].chan_pre,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].char_auto,
		chan_table[channel].chan_name);	
	}
	else
	{
      sprintf( buf, "%s {%s{%s%s{%s{x",
		clan_table[ch->clan].who_name,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].others_auto,
		chan_table[channel].chan_name);

      sprintf( buf2, "%s {%s{%s%s{%s{x\n\r",
		clan_table[ch->clan].who_name,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].char_auto,
		chan_table[channel].chan_name);	
	}	
	send_to_char(buf2,ch);

      for ( d = descriptor_list; d != NULL; d = d->next )
      {
		CHAR_DATA *vch;
        	vch = d->original ? d->original : d->character;
       	if ((channel == CHAN_IMM) && (!IS_IMMORTAL(d->character)))
            return TRUE;
            
            if ((channel == CHAN_CLAN) && (!is_same_clan(ch,d->character)))
            return TRUE;
 
        if ( d->connected == CON_PLAYING &&
             d->character != ch &&
		 victim->name != arg &&
             !IS_SET(vch->comm,chan_table[channel].bit) &&
             !IS_SET(vch->comm,COMM_QUIET) )
        {
	    act_new(buf,ch,NULL,vch,TO_VICT,POS_DEAD);
        }
      }
    }
    else
    {
	if(channel != CHAN_CLAN)
	{
      sprintf( buf, "%s {%s{%s%s{%s{x",
		chan_table[channel].chan_pre,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].others_found,
		chan_table[channel].chan_name);

      sprintf( buf2, "%s {%s{%s%s{%s{x",
		chan_table[channel].chan_pre,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].char_found,
		chan_table[channel].chan_name);

      sprintf( buf3, "%s {%s{%s%s{%s{x",
		chan_table[channel].chan_pre,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].vict_found,
		chan_table[channel].chan_name);
      }
      else
	{
	        sprintf( buf, "%s {%s{%s%s{%s{x",
		clan_table[ch->clan].who_name,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].others_found,
		chan_table[channel].chan_name);

      sprintf( buf2, "%s {%s{%s%s{%s{x",
		clan_table[ch->clan].who_name,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].char_found,
		chan_table[channel].chan_name);

      sprintf( buf3, "%s {%s{%s%s{%s{x",
		clan_table[ch->clan].who_name,
		chan_table[channel].chan_name,
		chan_table[channel].chan_say,
		social_table[cmd].vict_found,
		chan_table[channel].chan_name);
      }
	  act_new(buf3,ch,NULL,victim,TO_VICT,POS_DEAD);
	  act_new(buf2,ch,NULL,victim,TO_CHAR,POS_DEAD);
        for (counter = 0; buf[counter+1] != '\0'; counter++)
        {
            if (buf[counter] == '$' && buf[counter + 1] == 'N')
            {
                strcpy(buf2,buf);
                buf2[counter] = '\0';
                strcat(buf2,victim->name);
                for (count = 0; buf[count] != '\0'; count++)
                {
                    buf[count] = buf[count+counter+2];
                }
                strcat(buf2,buf);
                strcpy(buf,buf2);

            }
            else if (buf[counter] == '$' && buf[counter + 1] == 'E')
            {
                switch (victim->sex)
                {
                default:
                    strcpy(buf2,buf);
                    buf2[counter] = '\0';
                    strcat(buf2,"it");
                    for (count = 0; buf[count] != '\0'; count ++)
                    {
                        buf[count] = buf[count+counter+2];
                    }
                    strcat(buf2,buf);
                    strcpy(buf,buf2);
                    break;
                case 1:
                    strcpy(buf2,buf);
                    buf2[counter] = '\0';
                    strcat(buf2,"it");
                    for (count = 0; buf[count] != '\0'; count++)
                    {
                        buf[count] = buf[count+counter+2];
                    }
                    strcat(buf2,buf);
                    strcpy(buf,buf2);
                    break;
                case 2:
                    strcpy(buf2,buf);
                    buf2[counter] = '\0';
                    strcat(buf2,"it");
                    for (count = 0; buf[count] != '\0'; count++)
                    {
                        buf[count] = buf[count+counter+2];
                    }
                    strcat(buf2,buf);
                    strcpy(buf,buf2);
                    break;
                }
            }
            else if (buf[counter] == '$' && buf[counter + 1] == 'M')
            {
                buf[counter] = '%';
                buf[counter + 1] = 's';
                switch (victim->sex)
                {
                default:
                    strcpy(buf2,buf);
                    buf2[counter] = '\0';
                    strcat(buf2,"it");
                    for (count = 0; buf[count] != '\0'; count++)
                    {
                        buf[count] = buf[count+counter+2];
                    }
                    strcat(buf2,buf);
                    strcpy(buf,buf2);
                    break;
                case 1:
                    strcpy(buf2,buf);
                    buf2[counter] = '\0';
                    strcat(buf2,"him");
                    for (count = 0; buf[count] != '\0'; count++)
                    {
                        buf[count] = buf[count+counter+2];
                    }
                    strcat(buf2,buf);
                    strcpy(buf,buf2);
                    break;
                case 2:
                    strcpy(buf2,buf);
                    buf2[counter] = '\0';
                    strcat(buf2,"her");
                    for (count = 0; buf[count] != '\0'; count++);
                    {
                        buf[count] = buf[count+counter+2];
                    }
                    strcat(buf2,buf);
                    strcpy(buf,buf2);
                    break;
                }
            }
            else if (buf[counter] == '$' && buf[counter + 1] == 'S')
            {
                switch (victim->sex)
                {
                default:
                strcpy(buf2,buf);
                buf2[counter] = '\0';
                strcat(buf2,"its");
                for (count = 0;buf[count] != '\0'; count++)
                {
                    buf[count] = buf[count+counter+2];
                }
                strcat(buf2,buf);
                strcpy(buf,buf2);
                break;
                case 1:
                    strcpy(buf2,buf);
                    buf2[counter] = '\0';
                    strcat(buf2,"his");
                    for (count = 0; buf[count] != '\0'; count++)
                    {
                        buf[count] = buf[count+counter+2];
                    }
                    strcat(buf2,buf);
                    strcpy(buf,buf2);
                    break;
                case 2:
                    strcpy(buf2,buf);
                    buf2[counter] = '\0';
                    strcat(buf2,"hers");
                    for (count = 0; buf[count] != '\0'; count++)
                    {
                        buf[count] = buf[count+counter+2];
                    }
                    strcat(buf2,buf);
                    strcpy(buf,buf2);
                    break;
                }
            }

        }

      for ( d = descriptor_list; d != NULL; d = d->next )
      {
	  CHAR_DATA *vch;
        vch = d->original ? d->original : d->character;
 
        if ( d->connected == CON_PLAYING &&
             d->character != ch &&
			  victim != vch &&
             !IS_SET(vch->comm,chan_table[channel].bit) &&
             !IS_SET(vch->comm,COMM_QUIET) )
        {
          	if ((channel == CHAN_IMM) && (!IS_IMMORTAL(d->character)))
          	{
            return TRUE;
            }
            if (channel == CHAN_CLAN && !is_same_clan(ch,d->character))
            {
            return TRUE;
            } 
	    act_new(buf,ch,NULL,vch,TO_VICT,POS_DEAD);
        }
      }	
    }

    return TRUE;
}


// Then in tables.c add-
/*table for ooc, gossip, quote, music, question, auction, grats, immchat*/
const	struct	chan_type chan_table[] =
{
	{	"{w[{WOOC{w]",    "W",	"W",	COMM_NOOOC},
	{	"{d[{DGossip{D]",	"D",	"D",	COMM_NOGOSSIP},
	{	"{w[Quote]",	"w",	"w",	COMM_NOQUOTE},
	{	"{b[{BMusic{b]",	"B",	"b",	COMM_NOMUSIC},
	{	"{g[{GQ&A{g]",	"g",	"g",	COMM_NOQUESTION},
	{	"{r[{RAuction{r]","R",	"R",	COMM_NOAUCTION},
	{	"{b[Grats]",	"b",	"b",	COMM_NOGRATS},
	{	"{W[{DImmChat{W]","W",	"W",	COMM_NOWIZ},
	{	"{y[{YClan{y]",	"y",	"y",	COMM_NOCLAN},
	{	NULL,	" ",	" ",	0			}
};



// In tables.h add-
extern 	const struct	chan_type   chan_table[];

struct chan_type
{
	char *chan_pre;
	char *chan_name;
	char *chan_say;
	int bit;
};



// In merc.h-
#define CHAN_OOC		0
#define CHAN_GOSSIP		1
#define CHAN_QUOTE		2
#define CHAN_MUSIC		3
#define CHAN_QA			4
#define CHAN_AUCT		5
#define CHAN_GRATS		6
#define CHAN_IMM		7
#define CHAN_CLAN		8

// Thats all you need. Have fun!