[go: up one dir, main page]

Menu

[897c37]: / mlib / lib / colours.lpc  Maximize  Restore  History

Download this file

193 lines (177 with data), 3.8 kB

/*
 * Colours server.
 * Shattered World Mudlib
 *
 * This object maintains a collection of colour names, and their
 * RGB (Red Blue Green) components.
 *
 * Upon loading, this object will try to restore itself. If it
 * fails, it will attempt to rebuild itself from /lib/rgb.txt
 */

inherit "RO/Servers";

const RGBfile = "lib/rgb.txt";
const ColoursSavefile = "lib/colours";

/*
 * an array of strings - the names of the colours
 */
array colours;
array RGB;	/* Red-Green-Blue component */
array normalizedRGB;	/* RGB such that R+G+B=1 */
array HSI;	/* Hue-Saturation-Intensity component */
array CMYK;	/* Cyan-Magenta-Yellow-Black component */

reset(argh)
{
    if (!argh)
    {
	restore_object( ColoursSavefile, this_object() );
	if (intp(colours))
	{
	    call_out("load_colours", 0);
	}
    }
}

static
contains_numbers(string foo)
{
int i;
    for (i = 0; i < 10; i ++)
    {
	if (index(foo, i+"") != -1)
	    return 1;
    }
    return 0;
}

static
contains_uppercase(string foo)
{
int i;
    for (i = 0; i < sizeof(foo); i ++)
    {
	if (foo[i..i] != " " && foo[i..i] == capitalize(foo[i..i]))
	    return 1;
    }
    return 0;
}

static
new_colour( string col, int R, int G, int B )
{
/* this function is *very* *very* array intensive.
 * But, a rebuild of the arrays is anticipated to be a once-off,
 * ever, event. So, I'm lazy. -Hunter
 */
    colours += [ col ];
    RGB += [ ({ R, G, B ] });
#if 0
    normalizedRGB += [ ({ (R+0.0)/(R+G+B), 
	(G+0.0)/(R+G+B), 
	(B+0.0)/(R+G+B) ] });
#endif
}

load_colours()
{
array colourfile = explode(grab_file(RGBfile), "\n");
int i;
array foo;
string colname;
    colours = [ ];
    RGB = [ ];
    normalizedRGB = [ ];
    for (i = 0; i < sizeof(colourfile); i ++)
    {
	foo = explode( strip_string(colourfile[i]), " ");
  	colname = implode(foo[3..], " ");
    	if (!contains_numbers(colname) && !contains_uppercase(colname))
	{
	    new_colour( colname, 
		atoi(colourfile[i][0..2]),	/* red */
		atoi(colourfile[i][4..6]), 	/* green */
		atoi(colourfile[i][8..10])	/* blue */
		);
	}
    }
    /* save the object now, it does not need to be saved regularly */
    save_object( ColoursSavefile, this_object());
}

query_colours() { return colours; }


string strip_string(string foo)
{
string bar = "";
int i;
int last_space = 1;
    for ( i = 0; i < sizeof(foo); i ++ )
    {
	if ( (foo[i..i] == " ") || (foo[i..i] == "\t") )
	{
	    if (last_space)
	    {
	    }
	    else
	    {
	    	bar += " ";
		last_space = 1;
	    }
	}
	else
	{
	    bar += foo[i..i];
	    last_space = 0;
	}
    }
    return bar;
}

/*
 * query_rgb:
 *  given a colour, what is its RGB components?
 */
(int|array)
query_rgb( string colour )
{
int i;
    i = index( colours, colour );
    if (i == -1)
	return 0;	/* no such colour */
    return RGB[i];
}

/*
 * query_colours_near:
 *  given a colour, what are other similar colours.
 * 'colour' is the name of the colour, and 'range' is 0..255, the smaller
 * the number, the closer the selection.
 */
(array)
query_colours_near( string colour, int range )
{
array cols;
int numcols;
int i;
int distance;
int nearRGB;
int dR;
int dG;
int dB;
int j;
    cols = allocate(20);		/* preallocate */
    nearRGB = query_rgb( colour );
    if ( !pointerp(nearRGB) )
	return [ ];	/* unknown colour, so no matches */
    for (i = 0; i < sizeof(colours); i ++)
    {
	/* use Euclidian method to determine closeness */
	dR = nearRGB[0] - RGB[i][1];
	dG = nearRGB[1] - RGB[i][1];
	dB = nearRGB[2] - RGB[i][2];
 	distance = "lib/imath"->sqrt( dR*dR + dG*dG + dB*dB );
	if (distance <= range)
	{
	    numcols ++;
	    j = index(cols, 0);
	    if (j == -1)
	    {
		j = sizeof(cols);
		cols = cols + allocate(sizeof(cols));
	    }
	    cols[j] = colours[i];
	}
    }
    return cols[..numcols-1];
}