/****************************************************************************
* ^ +----- | / ^ ^ | | +-\ *
* / \ | | / |\ /| | | | \ *
* / \ +--- |< | \ / | | | | | *
* /-----\ | | \ | v | | | | / *
* / \ | | \ | | +-----+ +-/ *
****************************************************************************
* AFKMud Copyright 1997-2003 by Roger Libiez (Samson), *
* Levi Beckerson (Whir), Michael Ward (Tarl), Erik Wolfe (Dwip), *
* Cameron Carroll (Cam), Cyberfox, Karangi, Rathian, Raine, and Adjani. *
* All Rights Reserved. *
* *
* Original SMAUG 1.4a written by Thoric (Derek Snider) with Altrag, *
* Blodkai, Haus, Narn, Scryn, Swordbearer, Tricops, Gorog, Rennard, *
* Grishnakh, Fireblade, and Nivek. *
* *
* Original MERC 2.1 code by Hatchet, Furey, and Kahn. *
* *
* Original DikuMUD code by: Hans Staerfeldt, Katja Nyboe, Tom Madsen, *
* Michael Seifert, and Sebastian Hammer. *
****************************************************************************
* Color Module -- Allow user customizable Colors. *
* --Matthew *
* Enhanced ANSI parser by Samson *
****************************************************************************/
/*
* The following instructions assume you know at least a little bit about
* coding. I firmly believe that if you can't code (at least a little bit),
* you don't belong running a mud. So, with that in mind, I don't hold your
* hand through these instructions.
*
* You may use this code provided that:
*
* 1) You understand that the authors _DO NOT_ support this code
* Any help you need must be obtained from other sources. The
* authors will ignore any and all requests for help.
* 2) You will mention the authors if someone asks about the code.
* You will not take credit for the code, but you can take credit
* for any enhancements you make.
* 3) This message remains intact.
*
* If you would like to find out how to send the authors large sums of money,
* you may e-mail the following address:
*
* Matthew Bafford & Christopher Wigginton
* wiggy@mudservices.com
*/
/*
* To add new color types:
*
* 1. Edit color.h, and:
* 1. Add a new AT_ define.
* 2. Increment MAX_COLORS by however many AT_'s you added.
* 2. Edit color.c and:
* 1. Add the name(s) for your new color(s) to the end of the pc_displays array.
* 2. Add the default color(s) to the end of the default_set array.
*/
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <dirent.h>
#include "mud.h"
char *const pc_displays[MAX_COLORS] =
{
"black", "dred", "dgreen", "orange",
"dblue", "purple", "cyan", "grey",
"dgrey", "red", "green", "yellow",
"blue", "pink", "lblue", "white",
"blink", "bdred", "bdgreen", "bdorange",
"bdblue", "bpurple", "bcyan", "bgrey",
"bdgrey", "bred", "bgreen", "byellow",
"bblue", "bpink", "blblue", "bwhite",
"plain", "action", "say", "chat",
"yells", "tell", "hit", "hitme",
"immortal", "hurt", "falling", "danger",
"magic", "consider", "report", "poison",
"social", "dying", "dead", "skill",
"carnage", "damage", "fleeing", "rmname",
"rmdesc", "objects", "people", "list",
"bye", "gold", "gtells", "note",
"hungry", "thirsty", "fire", "sober",
"wearoff", "exits", "score", "reset",
"log", "die_msg", "wartalk", "arena",
"muse", "think", "aflags", "who",
"racetalk", "ignore", "whisper", "divider",
"morph", "shout", "rflags", "stype",
"aname", "auction", "score2", "score3",
"score4", "who2", "who3", "who4",
"intermud", "helpfiles", "who5", "score5",
"who6", "who7", "prac", "prac2",
"prac3", "prac4", "mxpprompt", "guildtalk",
"ooc", "avatar", "ship", "clan"
};
/* All defaults are set to Alsherok default scheme, if you don't
like it, change it around to suite your own needs - Samson */
const short default_set[MAX_COLORS] =
{
AT_BLACK, AT_BLOOD, AT_DGREEN, AT_ORANGE, /* 3 */
AT_DBLUE, AT_PURPLE, AT_CYAN, AT_GREY, /* 7 */
AT_DGREY, AT_RED, AT_GREEN, AT_YELLOW, /* 11 */
AT_BLUE, AT_PINK, AT_LBLUE, AT_WHITE, /* 15 */
AT_BLACK_BLINK, AT_BLOOD_BLINK, AT_DGREEN_BLINK, AT_ORANGE_BLINK, /* 19 */
AT_DBLUE_BLINK, AT_PURPLE_BLINK, AT_CYAN_BLINK, AT_GREY_BLINK, /* 23 */
AT_DGREY_BLINK, AT_RED_BLINK, AT_GREEN_BLINK, AT_YELLOW_BLINK, /* 27 */
AT_BLUE_BLINK, AT_PINK_BLINK, AT_LBLUE_BLINK, AT_WHITE_BLINK, /* 31 */
AT_GREY, AT_GREY, AT_BLUE, /* 34 */
AT_GREEN, AT_LBLUE, AT_WHITE, AT_GREY, /* 38 */
AT_GREY, AT_YELLOW, AT_GREY, AT_GREY, /* 42 */
AT_GREY, AT_BLUE, AT_GREY, AT_GREY, /* 46 */
AT_DGREEN, AT_CYAN, AT_GREY, AT_GREY, /* 50 */
AT_BLUE, AT_GREY, AT_GREY, AT_GREY, /* 54 */
AT_RED, AT_GREY, AT_BLUE, AT_PINK, /* 58 */
AT_GREY, AT_GREY, AT_YELLOW, AT_GREY, /* 62 */
AT_GREY, AT_ORANGE, AT_BLUE, AT_RED, /* 66 */
AT_GREY, AT_GREY, AT_GREEN, AT_DGREEN, /* 70 */
AT_DGREEN, AT_ORANGE, AT_GREY, AT_RED, /* 74 */
AT_GREY, AT_DGREEN, AT_RED, AT_BLUE, /* 78 */
AT_RED, AT_CYAN, AT_YELLOW, AT_PINK, /* 82 */
AT_DGREEN, AT_PINK, AT_WHITE, AT_BLUE, /* 86 */
AT_BLUE, AT_BLUE, AT_GREEN, AT_GREY, /* 90 */
AT_GREEN, AT_GREEN, AT_YELLOW, AT_DGREY, /* 94 */
AT_GREEN, AT_PINK, AT_DGREEN, AT_CYAN, /* 98 */
AT_RED, AT_WHITE, AT_BLUE, AT_DGREEN, /* 102 */
AT_CYAN, AT_BLOOD, AT_RED, AT_DGREEN, /* 106 */
AT_GREEN, AT_GREEN, AT_GREEN, AT_GREEN, /* 110 */
AT_GREEN
};
char *const valid_color[] = {
"black",
"dred",
"dgreen",
"orange",
"dblue",
"purple",
"cyan",
"grey",
"dgrey",
"red",
"green",
"yellow",
"blue",
"pink",
"lblue",
"white",
"\0"
};
/* Color align functions by Justice@Aaern */
int const_color_str_len( const char *argument )
{
int str, count = 0;
bool IS_COLOR = FALSE;
for( str = 0; argument[str] != '\0'; str++ )
{
if( argument[str] == '&' )
{
if( IS_COLOR == TRUE )
{
count++;
IS_COLOR = FALSE;
}
else
IS_COLOR = TRUE;
}
#ifdef OVERLANDCODE
else if( argument[str] == '{' )
#else
else if( argument[str] == '^' )
#endif
{
if( IS_COLOR == TRUE )
{
count++;
IS_COLOR = FALSE;
}
else
IS_COLOR = TRUE;
}
else if( argument[str] == '}' )
{
if( IS_COLOR == TRUE )
{
count++;
IS_COLOR = FALSE;
}
else
IS_COLOR = TRUE;
}
else
{
if( IS_COLOR == FALSE )
count++;
else
IS_COLOR = FALSE;
}
}
return count;
}
int const_color_strnlen( const char *argument, int maxlength )
{
int str, count = 0;
bool IS_COLOR = FALSE;
for( str = 0; argument[str] != '\0'; str++ )
{
if( argument[str] == '&' )
{
if( IS_COLOR == TRUE )
{
count++;
IS_COLOR = FALSE;
}
else
IS_COLOR = TRUE;
}
#ifdef OVERLANDCODE
else if( argument[str] == '{' )
#else
else if( argument[str] == '^' )
#endif
{
if( IS_COLOR == TRUE )
{
count++;
IS_COLOR = FALSE;
}
else
IS_COLOR = TRUE;
}
else if( argument[str] == '}' )
{
if( IS_COLOR == TRUE )
{
count++;
IS_COLOR = FALSE;
}
else
IS_COLOR = TRUE;
}
else
{
if( IS_COLOR == FALSE )
count++;
else
IS_COLOR = FALSE;
}
if( count >= maxlength )
break;
}
if( count < maxlength )
return ( ( str - count ) + maxlength );
str++;
return str;
}
int color_str_len( char *argument )
{
int str, count = 0;
bool IS_COLOR = FALSE;
for( str = 0; argument[str] != '\0'; str++ )
{
if( argument[str] == '&' )
{
if( IS_COLOR == TRUE )
{
count++;
IS_COLOR = FALSE;
}
else
IS_COLOR = TRUE;
}
#ifdef OVERLANDCODE
else if( argument[str] == '{' )
#else
else if( argument[str] == '^' )
#endif
{
if( IS_COLOR == TRUE )
{
count++;
IS_COLOR = FALSE;
}
else
IS_COLOR = TRUE;
}
else if( argument[str] == '}' )
{
if( IS_COLOR == TRUE )
{
count++;
IS_COLOR = FALSE;
}
else
IS_COLOR = TRUE;
}
else
{
if( IS_COLOR == FALSE )
count++;
else
IS_COLOR = FALSE;
}
}
return count;
}
int color_strnlen( char *argument, int maxlength )
{
int str, count = 0;
bool IS_COLOR = FALSE;
for( str = 0; argument[str] != '\0'; str++ )
{
if( argument[str] == '&' )
{
if( IS_COLOR == TRUE )
{
count++;
IS_COLOR = FALSE;
}
else
IS_COLOR = TRUE;
}
#ifdef OVERLANDCODE
else if( argument[str] == '{' )
#else
else if( argument[str] == '^' )
#endif
{
if( IS_COLOR == TRUE )
{
count++;
IS_COLOR = FALSE;
}
else
IS_COLOR = TRUE;
}
else if( argument[str] == '}' )
{
if( IS_COLOR == TRUE )
{
count++;
IS_COLOR = FALSE;
}
else
IS_COLOR = TRUE;
}
else
{
if( IS_COLOR == FALSE )
count++;
else
IS_COLOR = FALSE;
}
if( count >= maxlength )
break;
}
if( count < maxlength )
return ( ( str - count ) + maxlength );
str++;
return str;
}
const char *const_color_align( const char *argument, int size, int align )
{
int space = ( size - const_color_str_len( argument ) );
static char buf[MAX_STRING_LENGTH];
if( align == ALIGN_RIGHT || const_color_str_len( argument ) >= size )
snprintf( buf, MAX_STRING_LENGTH, "%*.*s", const_color_strnlen( argument, size ),
const_color_strnlen( argument, size ), argument );
else if( align == ALIGN_CENTER )
snprintf( buf, MAX_STRING_LENGTH, "%*s%s%*s", ( space / 2 ), "", argument,
( ( space / 2 ) * 2 ) == space ? ( space / 2 ) : ( ( space / 2 ) + 1 ), "" );
else
snprintf( buf, MAX_STRING_LENGTH, "%s%*s", argument, space, "" );
return buf;
}
char *color_align( char *argument, int size, int align )
{
int space = ( size - color_str_len( argument ) );
static char buf[MAX_STRING_LENGTH];
if( align == ALIGN_RIGHT || color_str_len( argument ) >= size )
snprintf( buf, MAX_STRING_LENGTH, "%*.*s", color_strnlen( argument, size ), color_strnlen( argument, size ),
argument );
else if( align == ALIGN_CENTER )
snprintf( buf, MAX_STRING_LENGTH, "%*s%s%*s", ( space / 2 ), "", argument,
( ( space / 2 ) * 2 ) == space ? ( space / 2 ) : ( ( space / 2 ) + 1 ), "" );
else if( align == ALIGN_LEFT )
snprintf( buf, MAX_STRING_LENGTH, "%s%*s", argument, space, "" );
return buf;
}
void show_colorthemes( CHAR_DATA * ch )
{
DIR *dp;
struct dirent *dentry;
int count = 0, col = 0;
send_to_pager( "&YThe following themes are available:\r\n", ch );
dp = opendir( COLOR_DIR );
dentry = readdir( dp );
while( dentry )
{
/*
* Added by Tarl 3 Dec 02 because we are now using CVS
*/
if( !str_cmp( dentry->d_name, "CVS" ) )
{
dentry = readdir( dp );
continue;
}
if( dentry->d_name[0] != '.' )
{
count++;
pager_printf( ch, "%s%-15.15s", color_str( AT_PLAIN, ch ), dentry->d_name );
if( ++col % 6 == 0 )
send_to_pager( "\r\n", ch );
}
dentry = readdir( dp );
}
closedir( dp );
if( count == 0 )
send_to_pager( "No themes defined yet.\r\n", ch );
if( col % 6 != 0 )
send_to_pager( "\r\n", ch );
return;
}
void show_colors( CHAR_DATA * ch )
{
short count;
send_to_pager( "&BSyntax: color [color type] [color] | default\r\n", ch );
send_to_pager( "&BSyntax: color _reset_ (Resets all colors to default set)\r\n", ch );
send_to_pager( "&BSyntax: color _all_ [color] (Sets all color types to [color])\r\n", ch );
send_to_pager( "&BSyntax: color theme [name] (Sets all color types to a defined theme)\r\n\r\n", ch );
send_to_pager( "&W********************************[ COLORS ]*********************************\r\n", ch );
for( count = 0; count < 16; ++count )
{
if( ( count % 8 ) == 0 && count != 0 )
send_to_pager( "\r\n", ch );
pager_printf( ch, "%s%-10s", color_str( count, ch ), pc_displays[count] );
}
send_to_pager( "\r\n\r\n&W******************************[ COLOR TYPES ]******************************\r\n", ch );
for( count = 32; count < MAX_COLORS; ++count )
{
if( ( count % 8 ) == 0 && count != 32 )
{
send_to_pager( "\r\n", ch );
}
pager_printf( ch, "%s%-10s%s", color_str( count, ch ), pc_displays[count], ANSI_RESET );
}
send_to_pager( "\r\n\r\n", ch );
send_to_pager( "&YAvailable colors are:\r\n", ch );
for( count = 0; valid_color[count][0] != '\0'; ++count )
{
if( ( count % 8 ) == 0 && count != 0 )
send_to_pager( "\r\n", ch );
pager_printf( ch, "%s%-10s", color_str( AT_PLAIN, ch ), valid_color[count] );
}
send_to_pager( "\r\n\r\n", ch );
show_colorthemes( ch );
return;
}
void do_color( CHAR_DATA * ch, char *argument )
{
bool dMatch, cMatch;
short count = 0, y = 0;
char arg[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char arg3[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
dMatch = FALSE;
cMatch = FALSE;
if( IS_NPC( ch ) )
{
send_to_pager( "Only PC's can change colors.\r\n", ch );
return;
}
if( !argument || argument[0] == '\0' )
{
show_colors( ch );
return;
}
argument = one_argument( argument, arg );
if( !str_cmp( arg, "savetheme" ) && IS_IMMORTAL( ch ) )
{
FILE *fp;
char filename[256];
int x;
if( !argument || argument[0] == '\0' )
{
send_to_char( "You must specify a name for this theme to save it.\r\n", ch );
return;
}
if( strstr( argument, ".." ) || strstr( argument, "/" ) || strstr( argument, "\\" ) )
{
send_to_char( "Invalid theme name.\r\n", ch );
return;
}
snprintf( filename, sizeof( filename ), "%s%s", COLOR_DIR, argument );
if( !( fp = fopen( filename, "w" ) ) )
{
ch_printf( ch, "Unable to write to color file %s\r\n", filename );
return;
}
fprintf( fp, "%s", "#COLORTHEME\n" );
fprintf( fp, "Name %s~\n", argument );
fprintf( fp, "MaxColors %d\n", MAX_COLORS );
fprintf( fp, "%s", "Colors " );
for( x = 0; x < MAX_COLORS; ++x )
fprintf( fp, " %d", ch->colors[x] );
fprintf( fp, "%s", "\nEnd\n" );
fclose( fp );
fp = NULL;
ch_printf( ch, "Color theme %s saved.\r\n", argument );
return;
}
if( !str_cmp( arg, "theme" ) )
{
FILE *fp;
char filename[256];
int max_colors = 0;
if( !argument || argument[0] == '\0' )
{
show_colorthemes( ch );
return;
}
if( strstr( argument, ".." ) || strstr( argument, "/" ) || strstr( argument, "\\" ) )
{
send_to_char( "Invalid theme.\r\n", ch );
return;
}
snprintf( filename, sizeof( filename ), "%s%s", COLOR_DIR, argument );
if( !( fp = fopen( filename, "r" ) ) )
{
ch_printf( ch, "There is no theme called %s.\r\n", argument );
return;
}
while( !feof( fp ) )
{
char *word = fread_word( fp );
if( !str_cmp( word, "MaxColors" ) )
{
int temp = fread_number( fp );
max_colors = UMIN( temp, MAX_COLORS );
continue;
}
if( !str_cmp( word, "Colors" ) )
{
int x;
for( x = 0; x < max_colors; ++x )
ch->colors[x] = fread_number( fp );
fread_to_eol( fp );
continue;
}
if( !str_cmp( word, "End" ) )
{
fclose( fp );
fp = NULL;
ch_printf( ch, "Color theme has been changed to %s.\r\n", argument );
save_char_obj( ch );
return;
}
}
fclose( fp );
fp = NULL;
ch_printf( ch, "An error occured while trying to set color theme %s.\r\n", argument );
return;
}
if( !str_cmp( arg, "ansitest" ) )
{
sprintf( log_buf, "%sBlack\r\n", ANSI_BLACK );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sDark Red\r\n", ANSI_DRED );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sDark Green\r\n", ANSI_DGREEN );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sOrange/Brown\r\n", ANSI_ORANGE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sDark Blue\r\n", ANSI_DBLUE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sPurple\r\n", ANSI_PURPLE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sCyan\r\n", ANSI_CYAN );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sGrey\r\n", ANSI_GREY );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sDark Grey\r\n", ANSI_DGREY );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sRed\r\n", ANSI_RED );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sGreen\r\n", ANSI_GREEN );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sYellow\r\n", ANSI_YELLOW );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sBlue\r\n", ANSI_BLUE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sPink\r\n", ANSI_PINK );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sLight Blue\r\n", ANSI_LBLUE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sWhite\r\n", ANSI_WHITE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sBlack\r\n", BLINK_BLACK );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sDark Red\r\n", BLINK_DRED );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sDark Green\r\n", BLINK_DGREEN );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sOrange/Brown\r\n", BLINK_ORANGE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sDark Blue\r\n", BLINK_DBLUE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sPurple\r\n", BLINK_PURPLE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sCyan\r\n", BLINK_CYAN );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sGrey\r\n", BLINK_GREY );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sDark Grey\r\n", BLINK_DGREY );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sRed\r\n", BLINK_RED );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sGreen\r\n", BLINK_GREEN );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sYellow\r\n", BLINK_YELLOW );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sBlue\r\n", BLINK_BLUE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sPink\r\n", BLINK_PINK );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sLight Blue\r\n", BLINK_LBLUE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%sWhite\r\n", BLINK_WHITE );
write_to_buffer( ch->desc, log_buf, 0 );
write_to_buffer( ch->desc, ANSI_RESET, 0 );
sprintf( log_buf, "%s%sBlack\r\n", ANSI_WHITE, BACK_BLACK );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%s%sDark Red\r\n", ANSI_BLACK, BACK_DRED );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%s%sDark Green\r\n", ANSI_BLACK, BACK_DGREEN );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%s%sOrange/Brown\r\n", ANSI_BLACK, BACK_ORANGE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%s%sDark Blue\r\n", ANSI_BLACK, BACK_DBLUE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%s%sPurple\r\n", ANSI_BLACK, BACK_PURPLE );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%s%sCyan\r\n", ANSI_BLACK, BACK_CYAN );
write_to_buffer( ch->desc, log_buf, 0 );
sprintf( log_buf, "%s%sGrey\r\n", ANSI_BLACK, BACK_GREY );
write_to_buffer( ch->desc, log_buf, 0 );
write_to_buffer( ch->desc, ANSI_RESET, 0 );
return;
}
if( !str_prefix( arg, "_reset_" ) )
{
reset_colors( ch );
send_to_pager( "All color types reset to default colors.\r\n", ch );
return;
}
argument = one_argument( argument, arg2 );
if( arg[0] == '\0' )
{
send_to_char( "Change which color type?\r\n", ch );
return;
}
argument = one_argument( argument, arg3 );
if( !str_prefix( arg, "_all_" ) )
{
dMatch = TRUE;
count = -1;
/*
* search for a valid color setting
*/
for( y = 0; y < 16; y++ )
{
if( !str_cmp( arg2, valid_color[y] ) )
{
cMatch = TRUE;
break;
}
}
}
else if( arg2[0] == '\0' )
{
cMatch = FALSE;
}
else
{
/*
* search for the display type and str_cmp
*/
for( count = 0; count < MAX_COLORS; count++ )
{
if( !str_prefix( arg, pc_displays[count] ) )
{
dMatch = TRUE;
break;
}
}
if( !dMatch )
{
ch_printf( ch, "%s is an invalid color type.\r\n", arg );
send_to_char( "Type color with no arguments to see available options.\r\n", ch );
return;
}
if( !str_cmp( arg2, "default" ) )
{
ch->colors[count] = default_set[count];
sprintf( buf, "Display %s set back to default.\r\n", pc_displays[count] );
send_to_pager( buf, ch );
return;
}
/*
* search for a valid color setting
*/
for( y = 0; y < 16; y++ )
{
if( !str_cmp( arg2, valid_color[y] ) )
{
cMatch = TRUE;
break;
}
}
}
if( !cMatch )
{
if( arg[0] )
{
ch_printf( ch, "Invalid color for type %s.\n", arg );
}
else
{
send_to_pager( "Invalid color.\r\n", ch );
}
send_to_pager( "Choices are:\r\n", ch );
for( count = 0; count < 16; count++ )
{
if( count % 5 == 0 && count != 0 )
send_to_pager( "\r\n", ch );
pager_printf( ch, "%-10s", valid_color[count] );
}
pager_printf( ch, "%-10s\r\n", "default" );
return;
}
else
{
sprintf( buf, "Color type %s set to color %s.\r\n", count == -1 ? "_all_" : pc_displays[count], valid_color[y] );
}
if( !str_cmp( arg3, "blink" ) )
{
y += AT_BLINK;
}
if( count == -1 )
{
int ccount;
for( ccount = 0; ccount < MAX_COLORS; ++ccount )
{
ch->colors[ccount] = y;
}
set_pager_color( y, ch );
sprintf( buf, "All color types set to color %s%s.%s\r\n",
valid_color[y > AT_BLINK ? y - AT_BLINK : y], y > AT_BLINK ? " [BLINKING]" : "", ANSI_RESET );
send_to_pager( buf, ch );
}
else
{
ch->colors[count] = y;
set_pager_color( count, ch );
if( !str_cmp( arg3, "blink" ) )
sprintf( buf, "Display %s set to color %s [BLINKING]%s\r\n", pc_displays[count], valid_color[y - AT_BLINK],
ANSI_RESET );
else
sprintf( buf, "Display %s set to color %s.\r\n", pc_displays[count], valid_color[y] );
send_to_pager( buf, ch );
}
set_pager_color( AT_PLAIN, ch );
return;
}
/*
* If the color directory has a file named "default" this will be used if possible.
* The fallback will go to the hardcoded table in color.h if the "default" file is not available.
*/
void reset_colors( CHAR_DATA * ch )
{
FILE *fp;
int max_colors = 0;
char filename[256];
snprintf( filename, 256, "%s%s", COLOR_DIR, "default" );
if( !( fp = fopen( filename, "r" ) ) )
{
memcpy( &ch->colors, &default_set, sizeof( default_set ) );
return;
}
while( !feof( fp ) )
{
char *word = fread_word( fp );
if( !str_cmp( word, "MaxColors" ) )
{
int temp = fread_number( fp );
max_colors = UMIN( temp, MAX_COLORS );
continue;
}
if( !str_cmp( word, "Colors" ) )
{
int x;
for( x = 0; x < max_colors; ++x )
ch->colors[x] = fread_number( fp );
fread_to_eol( fp );
continue;
}
if( !str_cmp( word, "End" ) )
{
fclose( fp );
fp = NULL;
return;
}
}
fclose( fp );
fp = NULL;
return;
}
char *color_str( short AType, CHAR_DATA * ch )
{
if( !ch )
{
bug( "%s", "color_str: NULL ch!" );
return ( "" );
}
if( IS_NPC( ch ) || !IS_SET( ch->act, PLR_ANSI ) )
return ( "" );
switch ( ch->colors[AType] )
{
case 0:
return ( ANSI_BLACK );
case 1:
return ( ANSI_DRED );
case 2:
return ( ANSI_DGREEN );
case 3:
return ( ANSI_ORANGE );
case 4:
return ( ANSI_DBLUE );
case 5:
return ( ANSI_PURPLE );
case 6:
return ( ANSI_CYAN );
case 7:
return ( ANSI_GREY );
case 8:
return ( ANSI_DGREY );
case 9:
return ( ANSI_RED );
case 10:
return ( ANSI_GREEN );
case 11:
return ( ANSI_YELLOW );
case 12:
return ( ANSI_BLUE );
case 13:
return ( ANSI_PINK );
case 14:
return ( ANSI_LBLUE );
case 15:
return ( ANSI_WHITE );
/*
* 16 thru 31 are for blinking colors
*/
case 16:
return ( BLINK_BLACK );
case 17:
return ( BLINK_DRED );
case 18:
return ( BLINK_DGREEN );
case 19:
return ( BLINK_ORANGE );
case 20:
return ( BLINK_DBLUE );
case 21:
return ( BLINK_PURPLE );
case 22:
return ( BLINK_CYAN );
case 23:
return ( BLINK_GREY );
case 24:
return ( BLINK_DGREY );
case 25:
return ( BLINK_RED );
case 26:
return ( BLINK_GREEN );
case 27:
return ( BLINK_YELLOW );
case 28:
return ( BLINK_BLUE );
case 29:
return ( BLINK_PINK );
case 30:
return ( BLINK_LBLUE );
case 31:
return ( BLINK_WHITE );
default:
return ( ANSI_RESET );
}
}
int colorcode( const char *col, char *code, CHAR_DATA * ch )
{
const char *ctype = col;
int ln;
bool ansi;
if( !ch )
ansi = TRUE;
else
ansi = ( !IS_NPC( ch ) && IS_SET( ch->act, PLR_ANSI ) );
col++;
if( !*col )
ln = -1;
#ifdef OVERLANDCODE
else if( *ctype != '&' && *ctype != '{' && *ctype != '}' )
{
bug( "colorcode: command '%c' not '&', '{' or '}'", *ctype );
ln = -1;
}
#else
else if( *ctype != '&' && *ctype != '^' && *ctype != '}' )
{
bug( "colorcode: command '%c' not '&', '^' or '}'", *ctype );
ln = -1;
}
#endif
else if( *col == *ctype )
{
code[0] = *col;
code[1] = '\0';
ln = 1;
}
else if( !ansi )
ln = 0;
else
{
/*
* Foreground text - non-blinking
*/
if( *ctype == '&' )
{
switch ( *col )
{
default:
code[0] = *ctype;
code[1] = *col;
code[2] = '\0';
return 2;
case 'i': /* Italic text */
case 'I':
strncpy( code, ANSI_ITALIC, 20 );
break;
case 'v': /* Reverse colors */
case 'V':
strncpy( code, ANSI_REVERSE, 20 );
break;
case 'u': /* Underline */
case 'U':
strncpy( code, ANSI_UNDERLINE, 20 );
break;
case 's': /* Strikeover */
case 'S':
strncpy( code, ANSI_STRIKEOUT, 20 );
break;
case 'd': /* Player's client default color */
strncpy( code, ANSI_RESET, 20 );
break;
case 'D': /* Reset to custom color for whatever is being displayed */
strncpy( code, ANSI_RESET, 20 ); /* Yes, this reset here is quite necessary to cancel out other things */
if( ch && ch->desc )
strncat( code, color_str( ch->desc->pagecolor, ch ), 20 );
break;
case 'x': /* Black */
strncpy( code, ANSI_BLACK, 20 );
break;
case 'O': /* Orange/Brown */
strncpy( code, ANSI_ORANGE, 20 );
break;
case 'c': /* Cyan */
strncpy( code, ANSI_CYAN, 20 );
break;
case 'z': /* Dark Grey */
strncpy( code, ANSI_DGREY, 20 );
break;
case 'g': /* Dark Green */
strncpy( code, ANSI_DGREEN, 20 );
break;
case 'G': /* Light Green */
strncpy( code, ANSI_GREEN, 20 );
break;
case 'P': /* Pink/Light Purple */
strncpy( code, ANSI_PINK, 20 );
break;
case 'r': /* Dark Red */
strncpy( code, ANSI_DRED, 20 );
break;
case 'b': /* Dark Blue */
strncpy( code, ANSI_DBLUE, 20 );
break;
case 'w': /* Grey */
strncpy( code, ANSI_GREY, 20 );
break;
case 'Y': /* Yellow */
strncpy( code, ANSI_YELLOW, 20 );
break;
case 'C': /* Light Blue */
strncpy( code, ANSI_LBLUE, 20 );
break;
case 'p': /* Purple */
strncpy( code, ANSI_PURPLE, 20 );
break;
case 'R': /* Red */
strncpy( code, ANSI_RED, 20 );
break;
case 'B': /* Blue */
strncpy( code, ANSI_BLUE, 20 );
break;
case 'W': /* White */
strncpy( code, ANSI_WHITE, 20 );
break;
}
}
/*
* Foreground text - blinking
*/
if( *ctype == '}' )
{
switch ( *col )
{
default:
code[0] = *ctype;
code[1] = *col;
code[2] = '\0';
return 2;
case 'x': /* Black */
strncpy( code, BLINK_BLACK, 20 );
break;
case 'O': /* Orange/Brown */
strncpy( code, BLINK_ORANGE, 20 );
break;
case 'c': /* Cyan */
strncpy( code, BLINK_CYAN, 20 );
break;
case 'z': /* Dark Grey */
strncpy( code, BLINK_DGREY, 20 );
break;
case 'g': /* Dark Green */
strncpy( code, BLINK_DGREEN, 20 );
break;
case 'G': /* Light Green */
strncpy( code, BLINK_GREEN, 20 );
break;
case 'P': /* Pink/Light Purple */
strncpy( code, BLINK_PINK, 20 );
break;
case 'r': /* Dark Red */
strncpy( code, BLINK_DRED, 20 );
break;
case 'b': /* Dark Blue */
strncpy( code, BLINK_DBLUE, 20 );
break;
case 'w': /* Grey */
strncpy( code, BLINK_GREY, 20 );
break;
case 'Y': /* Yellow */
strncpy( code, BLINK_YELLOW, 20 );
break;
case 'C': /* Light Blue */
strncpy( code, BLINK_LBLUE, 20 );
break;
case 'p': /* Purple */
strncpy( code, BLINK_PURPLE, 20 );
break;
case 'R': /* Red */
strncpy( code, BLINK_RED, 20 );
break;
case 'B': /* Blue */
strncpy( code, BLINK_BLUE, 20 );
break;
case 'W': /* White */
strncpy( code, BLINK_WHITE, 20 );
break;
}
}
/*
* Background color
*/
#ifdef OVERLANDCODE
if( *ctype == '{' )
#else
if( *ctype == '^' )
#endif
{
switch ( *col )
{
default:
code[0] = *ctype;
code[1] = *col;
code[2] = '\0';
return 2;
case 'x': /* Black */
strncpy( code, BACK_BLACK, 20 );
break;
case 'r': /* Dark Red */
strncpy( code, BACK_DRED, 20 );
break;
case 'g': /* Dark Green */
strncpy( code, BACK_DGREEN, 20 );
break;
case 'O': /* Orange/Brown */
strncpy( code, BACK_ORANGE, 20 );
break;
case 'b': /* Dark Blue */
strncpy( code, BACK_DBLUE, 20 );
break;
case 'p': /* Purple */
strncpy( code, BACK_PURPLE, 20 );
break;
case 'c': /* Cyan */
strncpy( code, BACK_CYAN, 20 );
break;
case 'w': /* Grey */
strncpy( code, BACK_GREY, 20 );
break;
}
}
ln = strlen( code );
}
if( ln <= 0 )
*code = '\0';
return ln;
}
/* Moved from comm.c */
void set_char_color( short AType, CHAR_DATA * ch )
{
if( !ch || !ch->desc )
return;
write_to_buffer( ch->desc, color_str( AType, ch ), 0 );
if( !ch->desc )
{
bug( "set_char_color: NULL descriptor after WTB! CH: %s", ch->name ? ch->name : "Unknown?!?" );
return;
}
ch->desc->pagecolor = ch->colors[AType];
}
void set_pager_color( short AType, CHAR_DATA * ch )
{
if( !ch || !ch->desc )
return;
write_to_pager( ch->desc, color_str( AType, ch ), 0 );
if( !ch->desc )
{
bug( "set_pager_color: NULL descriptor after WTP! CH: %s", ch->name ? ch->name : "Unknown?!?" );
return;
}
ch->desc->pagecolor = ch->colors[AType];
}
void write_to_pager( DESCRIPTOR_DATA * d, const char *txt, int length )
{
int pageroffset; /* Pager fix by thoric */
if( length <= 0 )
length = strlen( txt );
if( length == 0 )
return;
if( !d->pagebuf )
{
d->pagesize = MAX_STRING_LENGTH;
CREATE( d->pagebuf, char, d->pagesize );
}
if( !d->pagepoint )
{
d->pagepoint = d->pagebuf;
d->pagetop = 0;
d->pagecmd = '\0';
}
if( d->pagetop == 0 && !d->fcommand )
{
d->pagebuf[0] = '\n';
d->pagebuf[1] = '\r';
d->pagetop = 2;
}
pageroffset = d->pagepoint - d->pagebuf; /* pager fix (goofup fixed 08/21/97) */
while( d->pagetop + length >= d->pagesize )
{
if( d->pagesize > MAX_STRING_LENGTH * 16 )
{
bug( "%s", "Pager overflow. Ignoring.\r\n" );
d->pagetop = 0;
d->pagepoint = NULL;
DISPOSE( d->pagebuf );
d->pagesize = MAX_STRING_LENGTH;
return;
}
d->pagesize *= 2;
RECREATE( d->pagebuf, char, d->pagesize );
}
d->pagepoint = d->pagebuf + pageroffset; /* pager fix (goofup fixed 08/21/97) */
strncpy( d->pagebuf + d->pagetop, txt, length );
d->pagetop += length;
d->pagebuf[d->pagetop] = '\0';
return;
}
/* Writes to a descriptor, usually best used when there's no character to send to ( like logins ) */
void send_to_desc_color( const char *txt, DESCRIPTOR_DATA * d )
{
char *colstr;
const char *prevstr = txt;
char colbuf[20];
int ln;
if( !d )
{
bug( "%s", "send_to_desc_color: NULL *d" );
return;
}
if( !txt || !d->descriptor )
return;
#ifdef OVERLANDCODE
while( ( colstr = strpbrk( prevstr, "&{}" ) ) != NULL )
#else
while( ( colstr = strpbrk( prevstr, "&^}" ) ) != NULL )
#endif
{
if( colstr > prevstr )
write_to_buffer( d, prevstr, ( colstr - prevstr ) );
ln = colorcode( colstr, colbuf, d->character );
if( ln < 0 )
{
prevstr = colstr + 1;
break;
}
else if( ln > 0 )
write_to_buffer( d, colbuf, ln );
prevstr = colstr + 2;
}
if( *prevstr )
write_to_buffer( d, prevstr, 0 );
return;
}
/*
* Write to one char. Convert color into ANSI sequences.
*/
void send_to_char_color( const char *txt, CHAR_DATA * ch )
{
char *colstr;
const char *prevstr = txt;
char colbuf[20];
int ln;
if( !ch )
{
bug( "%s", "send_to_char_color: NULL ch!" );
return;
}
if( txt && ch->desc )
{
#ifdef OVERLANDCODE
while( ( colstr = strpbrk( prevstr, "&{}" ) ) != NULL )
#else
while( ( colstr = strpbrk( prevstr, "&^}" ) ) != NULL )
#endif
{
if( colstr > prevstr )
write_to_buffer( ch->desc, prevstr, ( colstr - prevstr ) );
ln = colorcode( colstr, colbuf, ch );
if( ln < 0 )
{
prevstr = colstr + 1;
break;
}
else if( ln > 0 )
write_to_buffer( ch->desc, colbuf, ln );
prevstr = colstr + 2;
}
if( *prevstr )
write_to_buffer( ch->desc, prevstr, 0 );
}
return;
}
void send_to_pager_color( const char *txt, CHAR_DATA * ch )
{
char *colstr;
const char *prevstr = txt;
char colbuf[20];
int ln;
if( !ch )
{
bug( "%s", "send_to_pager_color: NULL ch!" );
return;
}
if( txt && ch->desc )
{
DESCRIPTOR_DATA *d = ch->desc;
ch = d->original ? d->original : d->character;
if( IS_NPC( ch ) || !IS_SET( ch->pcdata->flags, PCFLAG_PAGERON ) )
{
send_to_char_color( txt, d->character );
return;
}
#ifdef OVERLANDCODE
while( ( colstr = strpbrk( prevstr, "&{}" ) ) != NULL )
#else
while( ( colstr = strpbrk( prevstr, "&^}" ) ) != NULL )
#endif
{
if( colstr > prevstr )
write_to_pager( ch->desc, prevstr, ( colstr - prevstr ) );
ln = colorcode( colstr, colbuf, ch );
if( ln < 0 )
{
prevstr = colstr + 1;
break;
}
else if( ln > 0 )
write_to_pager( ch->desc, colbuf, ln );
prevstr = colstr + 2;
}
if( *prevstr )
write_to_pager( ch->desc, prevstr, 0 );
}
return;
}
void send_to_char( const char *txt, CHAR_DATA * ch )
{
send_to_char_color( txt, ch );
return;
}
void send_to_pager( const char *txt, CHAR_DATA * ch )
{
send_to_pager_color( txt, ch );
return;
}
void ch_printf( CHAR_DATA * ch, char *fmt, ... )
{
char buf[MAX_STRING_LENGTH * 2];
va_list args;
va_start( args, fmt );
vsnprintf( buf, MAX_STRING_LENGTH * 2, fmt, args );
va_end( args );
send_to_char_color( buf, ch );
}
void pager_printf( CHAR_DATA * ch, char *fmt, ... )
{
char buf[MAX_STRING_LENGTH * 2];
va_list args;
va_start( args, fmt );
vsnprintf( buf, MAX_STRING_LENGTH * 2, fmt, args );
va_end( args );
send_to_pager_color( buf, ch );
}
/*
* The primary output interface for formatted output.
*/
/* Major overhaul. -- Alty */
void ch_printf_color( CHAR_DATA * ch, char *fmt, ... )
{
char buf[MAX_STRING_LENGTH * 2];
va_list args;
va_start( args, fmt );
vsnprintf( buf, MAX_STRING_LENGTH * 2, fmt, args );
va_end( args );
send_to_char( buf, ch );
}
void pager_printf_color( CHAR_DATA * ch, char *fmt, ... )
{
char buf[MAX_STRING_LENGTH * 2];
va_list args;
va_start( args, fmt );
vsnprintf( buf, MAX_STRING_LENGTH * 2, fmt, args );
va_end( args );
send_to_pager( buf, ch );
}