/***************************************************************************** * Chatmode.c - Merc-based confrence system. * * * * Full chat-mode setup for Merc based MUDS, or could be used separately if * * you cut and pasted the needed parts from Merc code. * * -- Altrag Dalosein, Lord of the Dragons.. * *****************************************************************************/ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <ctype.h> #include <stdio.h> #include <string.h> #include <time.h> #include "chatmode.h" /* * Externals */ bool check_social args( ( CHAR_DATA *ch, char *command, char *argument ) ); extern int port; /* * Locals */ void start_chat_mode args( ( DESCRIPTOR_DATA *d ) ); void init_chat args( ( void ) ); void dispose_room args( ( CHAT_ROOM *room ) ); CHAT_ROOM *chat_rooms; CHAT_ROOM *last_chat_room; CHAR_DATA *chat_list; CHAR_DATA *old_chars; void start_chat_mode( DESCRIPTOR_DATA *d ) { CHAR_DATA *ch; if ( !d || !d->character ) return; if ( !chat_rooms ) init_chat( ); if ( d->original ) do_return( d->character, "" ); if ( d->pEdit ) { d->pEdit = NULL; d->editor = 0; } if ( d->inEdit ) { d->inEdit = NULL; d->editin = 0; } for ( ch = char_list; ch; ch = ch->next ) { if ( ch->reply == d->character ) ch->reply = NULL; if ( ch->master == d->character ) stop_follower( ch ); if ( ch->leader == d->character ) ch->leader = NULL; if ( ch->hunting == d->character ) ch->hunting = NULL; if ( ch->fighting == d->character ) stop_fighting( ch, FALSE ); } if ( d->character == char_list ) char_list = char_list->next; else { for ( ch = char_list; ch; ch = ch->next ) if ( ch->next == d->character ) break; if ( ch ) ch->next = d->character->next; } if ( d->character->was_in_room ) { if ( !d->character->in_room ) char_to_room( d->character, d->character->was_in_room ); } if ( d->character->in_room ) { d->character->was_in_room = d->character->in_room; char_from_room( d->character ); } d->original = d->character; /* * These are the freaks who go link_dead (and lose their descriptor) * from inside chat mode. * -- Altrag */ d->character->next = old_chars; old_chars = d->character; ch = alloc_mem( sizeof( *ch ) ); ch->desc = d; ch->name = str_dup( d->character->name ); ch->act = d->character->act; ch->sex = d->character->sex; ch->position = POS_STANDING; ch->hit = 1; ch->max_hit = 1; ch->next = chat_list; chat_list = ch; d->character = ch; d->connected = CON_CHATTING; char_to_room(ch, chat_rooms->pRoom); act(num_color(ch), "$n &Yhas entered the room.", ch, NULL, NULL, TO_ROOM); send_room_stuff( ch ); return; } void stop_chat_mode( CHAR_DATA *ch ) { DESCRIPTOR_DATA *d; CHAT_ROOM *room; d = ch->desc; act(num_color(ch), "$n &Yhas left the room.", ch, NULL, NULL, TO_ROOM); char_from_room( ch ); if ( ch == chat_list ) chat_list = ch->next; else { CHAR_DATA *gch; for ( gch = chat_list; gch; gch = gch->next ) if ( gch->next == ch ) break; if ( gch ) gch->next = ch->next; } for ( room = chat_rooms; room; room = room->next ) if (!str_prefix( ch->name, room->pRoom->name ) || is_name( ch->name, room->pRoom->name )) break; if ( room ) { if ( room == chat_rooms ) chat_rooms = room->next; else { CHAT_ROOM *rprev; for ( rprev = chat_rooms; rprev; rprev = rprev->next ) if ( rprev->next == room ) break; if ( rprev ) rprev->next = room->next; if ( !rprev->next ) last_chat_room = rprev; } dispose_room(room); } /* save_char_chat( ch );*/ free_char( ch ); if ( !d ) { return; } if ( !d->original ) { close_socket( d ); return; } d->character = d->original; d->original = NULL; if ( d->character == old_chars ) old_chars = old_chars->next; else { CHAR_DATA *gch; for ( gch = old_chars; gch; gch = gch->next ) if ( gch->next == d->character ) break; if ( gch ) gch->next = d->character->next; } d->character->next = char_list; char_list = d->character; if ( d->character->was_in_room ) char_to_room(d->character, d->character->was_in_room); else char_to_room(d->character, get_room_index(ROOM_VNUM_TEMPLE) ); d->character->was_in_room = NULL; d->connected = CON_PLAYING; do_look(d->character, ""); return; } void chat_interp( CHAR_DATA *ch, char *argument ) { while ( isspace(*argument) ) ++argument; if ( !*argument ) { send_room_stuff( ch ); return; } if ( chat_command( ch, argument ) ) return; if ( *argument == ',' ) { do_emote(ch, argument + 1); return; } if ( *argument == '.' ) { char arg[MAX_INPUT_LENGTH]; char *p_arg; p_arg = one_argument( argument, arg ); if ( check_social( ch, arg + 1, p_arg ) ) return; } act( num_color(ch), "$n&Y: &G$t", ch, argument, NULL, TO_ROOM ); send_to_char( AT_RED, "-- &CMessage sent &R--\n\r",ch); return; } CHAR_DATA *get_char_chat( CHAR_DATA *ch, char *name ) { CHAR_DATA *vch; if ( !str_prefix( name, ch->name ) || is_name( name, ch->name ) ) return ch; for ( vch = ch->in_room->people; vch; vch = vch->next_in_room ) if ( !str_prefix( name, vch->name ) || is_name( name, vch->name ) ) return vch; for ( vch = chat_list; vch; vch = vch->next ) if ( !str_prefix( name, vch->name ) || is_name( name, vch->name ) ) return vch; return NULL; } void send_room_stuff( CHAR_DATA *ch ) { int width = 0; CHAR_DATA *vch; int num = 0; if ( !ch->in_room ) return; send_to_char( AT_WHITE, ch->in_room->name, ch ); send_to_char( C_DEFAULT, "\n\r", ch ); if ( ch->in_room->description[0] != '\0' ) send_to_char(AT_YELLOW, ch->in_room->description, ch ); send_to_char( C_DEFAULT, "\n\r", ch ); for ( vch = ch->in_room->people; vch; vch = vch->next_in_room ) { if ( vch == ch ) continue; num++; width += strlen( vch->name ); if ( width >= 79 ) { send_to_char(C_DEFAULT, "\n\r", ch ); width = 0; } send_to_char(num_color(vch), vch->name, ch ); send_to_char(C_DEFAULT, " ", ch ); } if ( num == 0 ) send_to_char(AT_PURPLE, "You are all alone.",ch); send_to_char(C_DEFAULT, "\n\r\n\r", ch ); return; } void do_conference( CHAR_DATA *ch, char *argument ) { if ( IS_NPC(ch) && (!ch->desc || !ch->desc->original ) ) return; if ( ch->fighting || ch->position == POS_FIGHTING ) { send_to_char( AT_WHITE, "No way! You are fighting!.\n\r",ch); return; } if ( ch->combat_timer ) { send_to_char(AT_WHITE, "You can't right now.\n\r",ch); return; } if ( ch->position < POS_STUNNED && ch->level < L_APP ) { send_to_char(AT_WHITE, "You're not DEAD yet!\n\r",ch); return; } /* if ( IS_SET( ch->act, PLR_QUEST ) ) REMOVE_BIT( ch->act, PLR_QUEST );*/ ch->hunting = NULL; save_char_obj( ch, FALSE ); start_chat_mode( ch->desc ); } void init_chat( void ) { if ( chat_rooms ) return; chat_rooms = alloc_mem( sizeof( *chat_rooms ) ); chat_rooms->pRoom = alloc_mem(sizeof(*chat_rooms->pRoom)); chat_rooms->invited = str_dup(""); chat_rooms->pRoom->name = str_dup( "Main" ); chat_rooms->pRoom->description = str_dup( "&GEye of the &BS&Ct&Wo&Cr&Bm " "&GMain teleconference channel\n\r" "Type /h for help." ); last_chat_room = chat_rooms; return; } int num_color( CHAR_DATA *ch ) { switch ( ch->sex ) { case SEX_NEUTRAL: return AT_GREEN; case SEX_MALE: return AT_BLUE; case SEX_FEMALE: return AT_RED; } return C_DEFAULT; } char *get_color( CHAR_DATA *ch ) { switch ( ch->sex ) { case SEX_NEUTRAL: return "G"; case SEX_MALE: return "B"; case SEX_FEMALE: return "R"; } return "w"; } /* * Update the chat_list and the old_chars lists. Just kicks out linkdeads * if this becomes too much lag, you could just make a modified version * of check_reconnect in comm.c to check those lists as well as the char_list * list. -- Altrag */ void chat_update( void ) { CHAR_DATA *ch; CHAR_DATA *ch_next; for ( ch = old_chars; ch; ch = ch_next ) { ch_next = ch->next; if ( !ch->desc ) /* i.e. They went into chat but dropped link */ { if ( ch == old_chars ) old_chars = ch->next; else { CHAR_DATA *och; for ( och = old_chars; och; och = och->next ) if ( och->next == ch ) break; if ( och ) och->next = ch->next; } ch->next = char_list; char_list = ch; if ( ch->was_in_room ) char_to_room( ch, ch->was_in_room ); } } for ( ch = chat_list; ch; ch = ch_next ) { ch_next = ch->next; if ( !ch->desc ) { stop_chat_mode( ch ); } } return; } void dispose_room( CHAT_ROOM *room ) { CHAR_DATA *ch; CHAR_DATA *ch_next; for ( ch = room->pRoom->people; ch; ch = ch_next ) { ch_next = ch->next_in_room; chat_command(ch, "/join Main"); } free_string(room->pRoom->name); free_string(room->pRoom->description); free_mem(room->pRoom, sizeof(*room->pRoom)); free_string(room->invited); free_mem(room, sizeof(*room)); return; }