SRL Archive - OSR Advanced Scripting Tutorials

How to design Autocolor Functions (Along with examples and tools!)


Pure1993

2008-07-17 10:53:58

UPDATE 2: Introduction into HSL colors and how to apply them in Autocolor functions! I added it at the end of this tutorial!

Heya all,

Before we get started, there are two things I would like to warn you off, first off, this tut is quite long, so I would take break in between while reading it. Also, I edited some stuff around after I finished it, so some major grammar mistakes might have happened, or stuff could be mentioned where it shouldn't be, which could make part of this hard to understand. If such an error occured, please let me know. Thanks and enjoy the tut ^^.

We all know that Runescape has made the Minimap much more colorful (obviously to our disadvantage) thus as scripters we have to design a few autocolor functions ourselves when we are writing scripts.

I have seen and read many great Autocoloring tutorials, ranging from the very simple ColorFromBitmap (or whatever it was called), all the way to objects, dtms, ddtms, rgb, and a few more. All of those tutorials do a great job of getting the knowledge across in their own way, and today, I will try my own way, not in rivalry to the others, but more as an addition and a refresher. :)

Because RGBs are used more often than anything else, I will try to explain it.

You know how in real life (yeah, that still exists, or so I have been told ;)), when mixing certain colors, you will get others out of them (referring to colors you paint with real colors). Here is a picture of the "color wheel":


Well, on your pc, and the light for that matter, it is quite different, there the colors are made up of Red, Green, and Blue (thus the name RGB…). Here is a picture:


Alright, as you have probably already noticed, every existing color can be written in RGB values. Now, you might ask, HOW can we define the values????
Well, the answer is quite easy: You should already know that SCAR records colors with numbers (if you don't know this, read some beginner tuts and come back in a few weeks). Well, the number of the color is not random, but there is a pre defined system. In order to turn any recorded color into RGB values, simply follow this:

red := (TheColor mod 256);
green := ((TheColor / 256) mod 256);
blue := ((TheColor / 256) / 256);

Easy, ey? Well, to make that even easier, I designed a very simple script for ya:

program ColorsToRGBTool;
{.include srl/srl.scar}

const
TheColor = 16777215; //white background of the Scar program, substitute it with any color you want.

var
Red, Blue, Green: Integer;

begin
Red := (TheColor mod 256);
Green := ((TheColor / 256) mod 256);
Blue := ((TheColor / 256) / 256);
Writeln('----------------------------------------------');
Writeln('The color '+IntToStr(TheColor));
Writeln('Was turned into the following values: ');
Writeln('Red = '+IntToStr(Red));
Writeln('Green = '+IntToStr(Green));
writeln('Blue = '+IntToStr(Blue));
Writeln('----------------------------------------------');
end.

The result should look something like this:

Successfully compiled (1580 ms)
----------------------------------------------
The color 16777215
Was turned into the following values:
Red = 255
Green = 255
Blue = 255
----------------------------------------------
Successfully executed

Well, now some know it all SRL member will come up and say: Well, you do know there is a ColorToRGB function, why not use that one? My answer to that: This tut is not made for people to just copy every step and function, but to understand what they do, and maybe even create their own ideas out of this principle.

Well, back on topic: As you can see, the result was 255 for every value. 255 is the maximum number each value can have. You might have heard somewhere in school once that all colors together (considering the light again), add to a white light. This is exactly the same thing, all colors at their maximum added together equal white (side note: because black is the opposite of white, it is obviously 0,0,0).

Now, we are moving on to the part you are here for: Making autocolor functions with them!

The color changes in Rs are subtle, so it would affect the script if we were looking for the actual value of a color, but when we use RGBs, we can split the color up, and look for certain ranges, although, here is a new block of information: The colors are first subtracted. This follows a simple principle. Simply choose a color, split it into the RGB values, and then perform all subtractions, although they should only be between two colors, for now. To save you the work, I did it already for you:
program ColorsToRGBTool;
{.include srl/srl.scar}

const
TheColor = 15654101; //Chose a different color this time

var
Red, Blue, Green: Integer;
RMB, RMG, BMR, BMG, GMR, GMB: Integer;

begin
Red := (TheColor mod 256);
Green := ((TheColor / 256) mod 256);
Blue := ((TheColor / 256) / 256);
Writeln('----------------------------------------------');
Writeln('The color '+IntToStr(TheColor));
Writeln('Was turned into the following values: ');
Writeln('Red = '+IntToStr(Red));
Writeln('Green = '+IntToStr(Green));
writeln('Blue = '+IntToStr(Blue));
Writeln('----------------------------------------------');
RMB := Red - Blue;
RMG := Red - Green;
BMR := Blue - Red;
BMG := Blue - Green;
GMR := Green - Red;
GMB := Green - Blue;
Writeln('----------------Results------------------------');
Writeln('Red - Blue = '+IntToStr(RMB));
Writeln('Red - Green = '+IntToStr(RMG));
Writeln('Blue - Red = '+IntToStr(BMR));
Writeln('Blue - Green = '+IntToStr(BMG));
Writeln('Green - Red = '+IntToStr(GMR));
writeln('Green - Blue = '+IntToStr(GMB));
Writeln('----------------------------------------------');
end.

As a result, you should get this:
Successfully compiled (1672 ms)
----------------------------------------------
The color 15654101
Was turned into the following values:
Red = 213
Green = 220
Blue = 238
----------------------------------------------
----------------Results------------------------
Red - Blue = -25
Red - Green = -7
Blue - Red = 25
Blue - Green = 18
Green - Red = 7
Green - Blue = -18
----------------------------------------------
Successfully executed

Now, for the ranges, you want to use the positive results. Now that we have covered all the information, let's design our function. Save the last document, and open up a new scar window (don't close the old one, we will still have use for it).

program TutorialExample;
{.include srl/srl.scar}

function FindPureLumbyColor: Integer;
var
i, Red, Green, Blue, GC, TestColor: Integer;
P: TPointArray;
begin
end;

begin
end.

First of all, we name the program, then we name the function (we will use it to find the lumby road color, but seeing as that name is already used in the SRL, I will use FindPureLumbyColor, but you can name it as you will), then we declare TestColor, Red, Green, and Blue as integers, as well as GC ("Generic Color", but you can name it how ever you want) and "i". We also need a TPA, so go ahead and declare a TPA (i will call it simply "P").


program TutorialExample;
{.include srl/srl.scar}

function FindPureLumbyColor: Integer;
var
i, Red, Green, Blue, GC, TestColor: Integer;
P: TPointArray;
begin
GC := 6847874;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 40);
for i:=0 to High(p)-1 do
begin
end;

begin
end.

Now we declare the color as the color of the Lumby road you picked manually. Because it is always a good idea to wait before looking for anything, use the FFlag(0) or just Flag, your choice. Then we will search for the colors with the FindColorsSpiralTolerance function. We should start looking at the center of the Minimap, an with quite a high tolerance. It will be refined later. Then we need a loop with a "for … to … do" statement, in order to check all the found colors.


program TutorialExample;
{.include srl/srl.scar}

function FindPureLumbyColor: Integer;
var
i, Red, Green, Blue, GC, TestColor: Integer;
P: TPointArray;
begin
GC := 6847874;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 40);
for i:=0 to High(p)-1 do
begin
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
end;

begin
end.

Now we'll check if the current found location if on the minimap (better save than sorry) with the RS_OnMinimap function. To have it more organized and shorter than in the examples/tools, we will use the official function of ColorToRGB function now.

Alright, now we will take a short break from designing this autocolor function, in order to find out the ranges which we will need in a minute. Open up the old SCAR window again, open a Runescape screen log onto one of your characters, and pick the Lumby road color manually. Log out, choose a different world, log in, take the color, and repeat that until you have 4 to 6 samples of the color. Let those colors run through our ColorToRGBTool program. The operations that should return 0 or higher (positiv values) should be "red - blue", "red - green", and "green - blue". After running this program over all the colors, you should have all the different attempts listed in the Debug box. Now, find the highest value that returned for the "red - blue" operation, and then find the lowest for the same operation, do that for the other two also. Alright, just as a reminder, I would write something like:


Red - Blue: {insert highest value} to {insert lowest value}
Red - Green: {insert highest value} to {insert lowest value}
Green - Blue: {insert highest value} to {insert lowest value}


Into the debug box of the autocoloring script. Obviously you should have the main window open again. Moving on…


program TutorialExample;
{.include srl/srl.scar}

function FindPureLumbyColor: Integer;
var
i, Red, Green, Blue, GC, TestColor: Integer;
P: TPointArray;
begin
GC := 6847874;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 40);
for i:=0 to High(p)-1 do
begin
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
if InRange(Red - Blue, 24, 30) then
if InRange(Red - Green, 4, 14) then
if InRange(Green - Blue, 15, 23) then
end;

begin
end.

Well, those are just the values I got out of it, actually, no, that isn't quite correct, because you have to add 3 to 6 to the highest value, and decrease 3 to 6 from the lowest value, because there might be a bigger color change one day, and if the ranges are too small, it wouldn't find the color.

program TutorialExample;
{.include srl/srl.scar}

function FindPureLumbyColor: Integer;
var
i, Red, Green, Blue, GC, TestColor: Integer;
P: TPointArray;
begin
GC := 6847874;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 40);
for i:=0 to High(p)-1 do
begin
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
if InRange(Red - Blue, 24, 30) then
if InRange(Red - Green, 4, 14) then
if InRange(Green - Blue, 15, 23) then
if GetColor(P[i].x + 2, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 1) = TestColor then
if GetColor(P[i].x, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 2, P[i].y) = TestColor then
if GetColor(P[i].x, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y) = TestColor then
if GetColor(P[i].x + 2, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 2) = TestColor then
begin
end;

begin
end.

This is just to make sure that it wasn't a single pixel which just happened to be closer to you than the road color, and which looks almost exactly like it, gets chosen, which could end up messing up everything.

program TutorialExample;
{.include srl/srl.scar}

function FindPureLumbyColor: Integer;
var
i, Red, Green, Blue, GC, TestColor: Integer;
P: TPointArray;
begin
GC := 6847874;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 40);
for i:=0 to High(p)-1 do
begin
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
if InRange(Red - Blue, 24, 30) then
if InRange(Red - Green, 4, 14) then
if InRange(Green - Blue, 15, 23) then
if GetColor(P[i].x + 2, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 1) = TestColor then
if GetColor(P[i].x, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 2, P[i].y) = TestColor then
if GetColor(P[i].x, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y) = TestColor then
if GetColor(P[i].x + 2, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 2) = TestColor then
begin
Result := TestColor;
Writeln(' Lumbridge Road Color = '+IntToStr(Result));
exit;
end;
end;
end;
WriteLn('Lumbridge Road Color could NOT be Found!');
Result := 0;
end;

begin
end.

Now to the end spurt: if all the tests are passed, the color that was found will be returned as the result of your function, it will write the result in the debug box, and exit the function.
If no color was found at all which passed all the tests, the resulting color will be defined as 0 and it will write in the debug box that it failed to find the color.

Well, let me say one thing now:

CONGRATULATIOS!

You have just learned how to create your own Autocolor functions! Feel free to design your own, for anything and any time! Just keep in mind, nothing is set in stone, you are not forced to use this exact methode, it is only a standardized one, so i thought I would use it here.

Well, now that you know how to create your own functions, I will show off a bit with the work I have done xD (these are ALL autocolor functions you will probably need in Lumbridge ^^)

program New;
{.include srl/srl.scar}
//Little note: feel free to edit the useless Writelns out if you want

{*******************************************************************************
function FindPureLumbyRoadColor: integer;
By: Pure1993
Description: Finds the roadcolor in Lumbridge.
*******************************************************************************}
function FindPureLumbyRoadColor: integer;
var
EC, i, testcolor, red,green,blue: Integer;
P : TPointArray;
begin
EC := 6847874;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, EC, MMX1, MMY1, MMX2, MMY2, 40);
for i:=0 to High(p)-1 do
begin
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
if InRange(Red - Blue, 24, 30) then
if InRange(Red - Green, 4, 14) then
if InRange(Green - Blue, 15, 23) then
if GetColor(P[i].x + 2, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 1) = TestColor then
if GetColor(P[i].x, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 2, P[i].y) = TestColor then
if GetColor(P[i].x, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y) = TestColor then
if GetColor(P[i].x + 2, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 2) = TestColor then
begin
Result := TestColor;
Writeln(' Lumbridge Road Color = '+IntToStr(Result));
Writeln('-----------------Note From Creator----------------')
Writeln(' This function is still in beta testing!');
Writeln(' If this function failed, please do the following:');
Writeln(' 1) Stop the Script. ');
Writeln(' 2) Record the actual color');
Writeln(' 3) Record the the "found" color (if any)');
Writeln(' 4) Please post the data on my thread.');
Writeln(' Optional) Check my thread every once in a while for a fix');
Writeln('------------------Thank You-----------------------');
exit;
end;
end;
end;
WriteLn('Lumbridge Road Color could NOT be Found!');
Result := 0;
Writeln('-----------------Note From Creator----------------')
Writeln(' This function is still in beta testing!');
Writeln(' If this function failed, please do the following:');
Writeln(' 1) Stop the Script. ');
Writeln(' 2) Record the actual color');
Writeln(' 3) Record the the "found" color (if any)');
Writeln(' 4) Please post the data on my thread.');
Writeln(' Optional) Check my thread every once in a while for a fix');
Writeln('------------------Thank You-----------------------');
end;

{*******************************************************************************
function FindLumbyFloorColor: Integer;
By: Pure1993
Description: Finds the floor color in the Lumbridge castle.
*******************************************************************************}
function FindLumbyFloorColor: Integer;
var
EC, i, testcolor, red,green,blue: Integer;
P : TPointArray;
begin
EC := 7699326;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, EC, MMX1, MMY1, MMX2, MMY2, 40);
for i:=0 to High(p)-1 do
begin
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
if InRange(Red - Blue, 6, 12) then
if InRange(Red - Green, 2, 5) then
if InRange(Green - Blue, 4, 9) then
if GetColor(P[i].x + 2, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 1) = TestColor then
if GetColor(P[i].x, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 2, P[i].y) = TestColor then
if GetColor(P[i].x, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y) = TestColor then
if GetColor(P[i].x + 2, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 2) = TestColor then
begin
Result := TestColor;
WriteLn('Lumbridge Floor Color = '+IntToStr(Result));
Writeln('-----------------Note From Creator----------------')
Writeln(' This function is still in beta testing!');
Writeln(' If this function failed, please do the following:');
Writeln(' 1) Stop the Script. ');
Writeln(' 2) Record the actual color');
Writeln(' 3) Record the the "found" color (if any)');
Writeln(' 4) Please post the data on my thread.');
Writeln(' Optional) Check my thread every once in a while for a fix');
Writeln('------------------Thank You-----------------------');
exit;
end;
end;
end;
WriteLn('Lumbridge Floor Color could NOT be Found!');
Result := 0;
Writeln('-----------------Note From Creator----------------')
Writeln(' This function is still in beta testing!');
Writeln(' If this function failed, please do the following:');
Writeln(' 1) Stop the Script. ');
Writeln(' 2) Record the actual color');
Writeln(' 3) Record the the "found" color (if any)');
Writeln(' 4) Please post the data on my thread.');
Writeln(' Optional) Check my thread every once in a while for a fix');
Writeln('------------------Thank You-----------------------');
end;

{*******************************************************************************
function FindLumbyBridgeColor: Integer;
By: Pure1993
Description: Find the Lumbridge bride color, this also works for the great
dining room and the dark squares in the cook's room.
*******************************************************************************}
function FindLumbyBridgeColor: Integer;
var
EC, i, testcolor, red,green,blue: Integer;
P : TPointArray;
begin
EC := 6910321;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, EC, MMX1, MMY1, MMX2, MMY2, 40);
for i:=0 to High(p)-1 do
begin
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
if InRange(Red - Blue, 4, 12) then
if InRange(Red - Green, -2, 3) then
if InRange(Green - Blue, 4, 12) then
if GetColor(P[i].x + 2, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 1) = TestColor then
if GetColor(P[i].x, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 2, P[i].y) = TestColor then
if GetColor(P[i].x, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y) = TestColor then
if GetColor(P[i].x + 2, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 2) = TestColor then
begin
Result := TestColor;
WriteLn('Lumbridge Bridge Color = '+IntToStr(Result));
Writeln('-----------------Note From Creator----------------')
Writeln(' This function is still in beta testing!');
Writeln(' If this function failed, please do the following:');
Writeln(' 1) Stop the Script. ');
Writeln(' 2) Record the actual color');
Writeln(' 3) Record the the "found" color (if any)');
Writeln(' 4) Please post the data on my thread.');
Writeln(' Optional) Check my thread every once in a while for a fix');
Writeln('------------------Thank You-----------------------');
exit;
end;
end;
end;
WriteLn('Lumbridge Bridge Color could NOT be Found!');
Result := 0;
Writeln('-----------------Note From Creator----------------')
Writeln(' This function is still in beta testing!');
Writeln(' If this function failed, please do the following:');
Writeln(' 1) Stop the Script. ');
Writeln(' 2) Record the actual color');
Writeln(' 3) Record the the "found" color (if any)');
Writeln(' 4) Please post the data on my thread.');
Writeln(' Optional) Check my thread every once in a while for a fix');
Writeln('------------------Thank You-----------------------');
end;

{*******************************************************************************
function FindLumbyLightSquareColor: Integer;
By: Pure1993
Description: Finds the color of the light squares in the Lumbridge cook's room.
*******************************************************************************}
function FindLumbyLightSquareColor: Integer;
var
EC, i, testcolor, red,green,blue: Integer;
P : TPointArray;
begin
EC := 12303300;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, EC, MMX1, MMY1, MMX2, MMY2, 40);
for i:=0 to High(p)-1 do
begin
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
if InRange(Red - Blue, 5, 13) then
if InRange(Red - Green, 5, 13) then
if InRange(Green - Blue, -2, 4) then
if GetColor(P[i].x + 2, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 1) = TestColor then
if GetColor(P[i].x, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 2, P[i].y) = TestColor then
if GetColor(P[i].x, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y) = TestColor then
if GetColor(P[i].x + 2, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 2) = TestColor then
begin
Result := TestColor;
WriteLn('Lumbridge Light Square Color = '+IntToStr(Result));
Writeln('-----------------Note From Creator----------------')
Writeln(' This function is still in beta testing!');
Writeln(' If this function failed, please do the following:');
Writeln(' 1) Stop the Script. ');
Writeln(' 2) Record the actual color');
Writeln(' 3) Record the the "found" color (if any)');
Writeln(' 4) Please post the data on my thread.');
Writeln(' Optional) Check my thread every once in a while for a fix');
Writeln('------------------Thank You-----------------------');
exit;
end;
end;
end;
WriteLn('Lumbridge Light Square Color could NOT be Found!');
Result := 0;
Writeln('-----------------Note From Creator----------------')
Writeln(' This function is still in beta testing!');
Writeln(' If this function failed, please do the following:');
Writeln(' 1) Stop the Script. ');
Writeln(' 2) Record the actual color');
Writeln(' 3) Record the the "found" color (if any)');
Writeln(' 4) Please post the data on my thread.');
Writeln(' Optional) Check my thread every once in a while for a fix');
Writeln('------------------Thank You-----------------------');
end;

begin
end.

And here is where you can apply each one:


Please keep in mind that they haven't been tested for too long (actually, apart from the road one, I wrote all of them today :D), so they might not always work, feel free to edit or/and use them, as long as I get creddited :D.

If you are intrested in how I keep all the data organised, feel free to look at the word documents in the attachment. This is optional ;)
EDIT: Sorry, the files are too big to be uploaded, well, I can still send them via e-mail, if you want to see them, just let me know ^^.

Well, thanks a lot for reading this tut, I hope you liked it (it took forever to write :D). If you liked it, feel free to +Rep me, to rate, and to comment. :)

Update 1:
Welcome back again folks! :D

After teaching a bit about RGB coloring, I would now like to introduce you to a new way of Autocoloring. It is quite similar to RGB, and yet completely different. It can also be used to refine the search for colors, thus making it safer!

This new magic thing has been called HSL, each letter representing the first letter of the three words (ZOMG! Such a creative idea!). Well, ya guesed it, it is Hue, Saturation, and Luminance. With those three values, each color in the entire color spectrum can be created.

I will now post a picture and post the explanation below it, so for the headache's sake, read the text while looking at the picture, don't try to understand them one by one on your own. ;)



Alright, sorry about the messed up quality (it's always the same with these free image hosting sites…). First of all, what do each of these values represent? Well, funny that you should ask that question, because the answer is right in the next few sentences:

-Hue: The original color.
-Saturation: How clear the color is.
-Luminance: How much light the color reflects (going way back into those physics classes ^^), or how bright the color is (in commoner speak :p).

So, um, yeah, no to the picture I guess… As you can see (looking at the big color square), the Hue will not change as you move down, neither will the luminance. The thing that is changing is the Saturation! Yeah, you see, when the saturation is at the maximum of 240, the color is as clear as it gets, but when you move down, it get's greyisch and duller. When you move right or left, only the Hue changes, and when you scroll up and down on that little scroll bar, the color get's brighter or darker. Here are some examples I prepared for you to make this easier to understand (hehe, am I prepared or what? :D):



As you can see, each one of those values can also be presented in RGB. and, there is a slight correspondens, for example (ah well, showing off my observation skills ftw xD), if you always use maximum Saturation and medium Luminance (exactly 120 is the middle), always one of the RGB values will be 0. At full Luminance, all values will always be 255, at minimum Luminance, all colors will be at 0, if you use minimum saturation, all RGB values will be the same, no matter how high or low the Luminance or Hue is.

Update 2:

Well hello there,

If you are still reading this, then I am sorry for the headache and eye ache I probably caused you by this point… and if you tried to print this tut I am sorry that you lost so much ink… but life keeps on going and so will this tut ^^ (I'm sorry, but I'm not god, I can't make it stop… :S)

Today, we will add HSL into our already created coloring function! YAY (show some enthusiasm people!…. Please? :D)! To start out, I will show you the Tool which we will be using during this session, I simply edited our old tool around and added the new one to it! Prepare to be stunned by amazment! (well, um, not really, but heck, I am way over motivated at the moment for no aparent reason, so deal with it ;))

program ColorsToAnythingTool;
{.include srl/srl.scar}

const
TheColor = 6847874; //I already chose the color we will be working with,
//how convenient is that? :D
var
Red, Blue, Green: Integer;
RMB, RMG, BMR, BMG, GMR, GMB: Integer;
H, S, L: Extended;
HMS, HML, SMH, SML, LMH, LMS: Integer;

procedure RGBTools;
begin
Red := (TheColor mod 256);
Green := ((TheColor / 256) mod 256);
Blue := ((TheColor / 256) / 256);
Writeln('----------------------------------------------');
Writeln(' The color '+IntToStr(TheColor));
Writeln(' Was turned into the following values: ');
Writeln(' Red = '+IntToStr(Red));
Writeln(' Green = '+IntToStr(Green));
writeln(' Blue = '+IntToStr(Blue));
Writeln('----------------------------------------------');
RMB := Red - Blue;
RMG := Red - Green;
BMR := Blue - Red;
BMG := Blue - Green;
GMR := Green - Red;
GMB := Green - Blue;
Writeln('----------------Results------------------------');
Writeln(' Red - Blue = '+IntToStr(RMB));
Writeln(' Red - Green = '+IntToStr(RMG));
Writeln(' Blue - Red = '+IntToStr(BMR));
Writeln(' Blue - Green = '+IntToStr(BMG));
Writeln(' Green - Red = '+IntToStr(GMR));
writeln(' Green - Blue = '+IntToStr(GMB));
Writeln('----------------------------------------------');
end;

procedure HSLTools;
begin
ColorToHSL(TheColor,H,S,L);
Writeln('----------------------------------------------');
Writeln(' The color '+IntToStr(TheColor));
Writeln(' H = '+FloatToStr(H));
Writeln(' S = '+FloatToStr(S));
Writeln(' L = '+FloatToStr(L));
Writeln('----------------------------------------------');
HMS := Round(H - S);
HML := Round(H - L);
SMH := Round(S - H);
SML := Round(S - L);
LMH := Round(L - H);
LMS := Round(L - S);
Writeln('----------------Results------------------------');
Writeln(' H - S = '+IntToStr(HMS));
Writeln(' H - L = '+IntToStr(HML));
Writeln(' S - H = '+IntToStr(SMH));
Writeln(' S - L = '+IntToStr(SML));
Writeln(' L - H = '+IntToStr(LMH));
Writeln(' L - S = '+IntToStr(LMS));
Writeln('----------------------------------------------');
end;

begin
HSLTools;
end.

Well, the problem here is that I don't know the mathematical functions which are used to define the HSL values (if anyone knows, please post, I would love to add it :D), so we will use the easy way for once… don't get used to it… :p

Also, there is another small change, HSL values are extended, so we need to declare them as such. This is also the reason why we round them in our math part ^^.

IMPORTANT: also round them in the real function later on when using InRange!

Hmm… what are you waiting for? You know the drill, run the script, login your runescape person, pick the lumby road color, log out, run the program with the new color, switch worlds, log back in and so forth until you have collected the data in 5 to 6 different worlds. Alright, go take a break now from reading this tutorial, you have earned it. (not only over motivated but also kind.. this is my best day so far xD)

Welcome back! After your relaxing break (I hope you took it, cause if you didn't, you'll wish you had), it is back on track! :D

Open up a new scar window and open the last Autocolor function we designed together. In case you don't have it anymore, here it is again:

program TutorialExample;
{.include srl/srl.scar}

function FindPureLumbyColor: Integer;
var
i, Red, Green, Blue, GC, TestColor: Integer;
P: TPointArray;
begin
GC := 6847874;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 40);
for i:=0 to High(p)-1 do
begin
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
if InRange(Red - Blue, 24, 30) then
if InRange(Red - Green, 4, 14) then
if InRange(Green - Blue, 15, 23) then
if GetColor(P[i].x + 2, P[i].y + 2) = TestColor then { <--- }
if GetColor(P[i].x + 1, P[i].y + 1) = TestColor then
if GetColor(P[i].x, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 2, P[i].y) = TestColor then
if GetColor(P[i].x, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y) = TestColor then
if GetColor(P[i].x + 2, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 2) = TestColor then
begin
Result := TestColor;
Writeln(' Lumbridge Road Color = '+IntToStr(Result));
exit;
end; { <--- }
end;
end;
WriteLn('Lumbridge Road Color could NOT be Found!');
Result := 0;
end;

begin
end.

Now, did you realise my 2 green arrows? Well, I put them there for a purpose, space every line on and between the two arrows 6 spaces further, and add 3 white lines right before the first arrow, so it looks like this:

program TutorialExample;
{.include srl/srl.scar}

function FindPureLumbyColor: Integer;
var
i, Red, Green, Blue, GC, TestColor: Integer;
P: TPointArray;
begin
GC := 6847874;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 40);
for i:=0 to High(p)-1 do
begin
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
if InRange(Red - Blue, 24, 30) then
if InRange(Red - Green, 4, 14) then
if InRange(Green - Blue, 15, 23) then



if GetColor(P[i].x + 2, P[i].y + 2) = TestColor then { <--- }
if GetColor(P[i].x + 1, P[i].y + 1) = TestColor then
if GetColor(P[i].x, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 2, P[i].y) = TestColor then
if GetColor(P[i].x, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y) = TestColor then
if GetColor(P[i].x + 2, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 2) = TestColor then
begin
Result := TestColor;
Writeln(' Lumbridge Road Color = '+IntToStr(Result));
exit;
end; { <--- }
end;
end;
WriteLn('Lumbridge Road Color could NOT be Found!');
Result := 0;
end;

begin
end.

Do you realise something? Yeah, you are probably right, it looks like there are three more steps to be added in! The question is, which ones? Well, it is quite simply, and practically, we have already discussed it before, get the minimum and maximum ranges of the three substraction operations which resulted in positive values, the same we did with the RGB ones, this time, "H-L", "S - H", and "S - L" should return positive, so use those ^^, and add 3 to 4 to the maximum, and decrease 3 to 4 from the minimum. Now, add them in with the InRange function, now, it is 23PM here and I don't have the time to do all the tests, so I will just fill in my best educated guess… Well, we forgot one thing, declaring H,S,L as extended variables, and add a new function called ColorToHSL, in order for the script to know what we are talking about. Also, I told you to remember to Round them in the InRange function, for speed's sake, so yeah, should look something like this:

program TutorialExample;
{.include srl/srl.scar}

function FindPureLumbyColor: Integer;
var
i, Red, Green, Blue, GC, TestColor: Integer;
P: TPointArray;
H, S, L: Extended;
begin
GC := 6847874;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 40);
for i:=0 to High(p)-1 do
begin
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
ColorToHSL(TestColor, H, S, L);
if InRange(Red - Blue, 24, 30) then
if InRange(Red - Green, 4, 14) then
if InRange(Green - Blue, 15, 23) then
if InRange(Round(H - L), 0, 8) then
if InRange(Round(S - H), -2, 5) then
if InRange(Round(S - L), 1, 9) then
if GetColor(P[i].x + 2, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 1) = TestColor then
if GetColor(P[i].x, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 2, P[i].y) = TestColor then
if GetColor(P[i].x, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y) = TestColor then
if GetColor(P[i].x + 2, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 2) = TestColor then
begin
Result := TestColor;
Writeln(' Lumbridge Road Color = '+IntToStr(Result));
exit;
end;
end;
end;
WriteLn('Lumbridge Road Color could NOT be Found!');
Result := 0;
end;

begin
end.

CONGRATULATIOS!
On completing anoter one if the Autocolor functions! this is not the only way to apply HSL and/or RGB, so try around a bit, and if you want, you can look through the Autocolor.Scar for inspirations. gl :D

Well, that's it for today, I am gone over the weekend, so it might take until Monday for my new update to be released.

If anything in this tut is misleading or wrong, please contact me.

Edit: I know the High(p)-1 is still wrong, but first of all it doesn't matter (not the way we autocolor in this tut), and second of all I don't have the time right now to fix it, will do so when I get back :)

Hope to c ya soon,

-Pure1993

Scaper

2008-07-17 11:02:14

i accidentily clicked not so ggod from the main screen but it is absloute amazing from what i have seen

rep++

Pure1993

2008-07-17 11:05:20

Hehe thanks a lot :D and never mind the poll, as long as there as no one presses the 2 lower options purposfully, it doesn't matter. :)

UPDATE 3: Introduction on how to use auto coloring to create your very own Minimap Door finding procedure!

Welcome Back to my tutorial on Auto coloring!

After a very long break, I have decided to return and to add to this tutorial. The problem is, that I am not allowed to have more than 20 pictures per post, so I am not able to edit or add to the previous post, without removing some pictures, which I won't do, because I don't want to change the things I have written so far.

Anyway, this time I will focus on auto coloring doors. I am aware of the DoorProfiles.scar included in the "core" includes, but I want to give some inspirations on what you can add to auto coloring. Some of the additional features are:

-including/creating a type
-reversing the "neighbor-pixel-test"
-using the color finding function twice (once with a variable box)
-adding coordinates to the found color

I'll get you started with setting up the Type, which needs to include a color and a destination. The color is (of course) an integer, and for the destination we'll use a TPoint, in order to make it look neater. Your program should now look something like this:


program New;
{.include srl/srl.scar}

type
TDoor = Record
loc : TPoint;
color : Integer;
end;

begin
end.


If You don't know what a type is/how to create a type/what they are used for, I would suggest you read the following tutorial before continuing on with this one: Records and Pseudo-OOP -By Tniffoc

Alright, now that we have the type, we'll just add the function with its name, output, begin and end. It should look like this now:


program New;
{.include srl/srl.scar}

type
TDoor = Record
loc : TPoint;
color : Integer;
end;

function FindDoorMM: TDoor;
begin
end;

begin
end.


Now that we have that covered, let's add the variables. We will be using RGB for this, because the door color is distinctively red (The green and blue values are usually at 0, and the read value above 240). So, we will be using the usual variables: Red, Green, Blue, i, GC, TestColor, and P.
What you can't expect at this point, is that we will be using 2 new variables, the "Unlikely" integer, and the "v" TPointArray. We will come across their usage later on. We can also add the standard beginning, so it will look somewhat like this:


program New;
{.include srl/srl.scar}

type
TDoor = Record
loc : TPoint;
color : Integer;
end;

function FindDoorMM: TDoor;
var
i, Red, Green, Blue, GC, TestColor, unlikely: Integer;
P, V: TPointArray;
begin
begin
GC := 246;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 20);
Writeln( IntToStr(High(p)));
for i:=0 to High(p)-1 do
begin
Unlikely := 0;
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
end;

begin
end.

As you can see here, two things have changed, first of all, the tolerance has been lowered, this is because doors don't have such a wide color range. You may also notice the definition of "Unlikely" to zero. This is because we will need it to reset every time the loop restarts.

By testing the door color with a little tool I have presented you in my first post (or because I have already told you), the red value of the door is always above 240, and the green and blue values always at 0. This is why we are going to use a slightly different method of ironing out the colors with a wrong RGB mix.


if (Red > 195) then
if (Blue < 5) then
if (Green < 5) then

Pretty simple, ey?
Now, depending upon the compass angle, the door pixel which has been found will have between 2 to 4 neighboring pixels with the same color, while the walking flag would have something close to 9, and a drop might have none, or quite a high number, but probably nothing in between. This is why we will reverse the "neighbor-pixel-test" (I have just invented that phrase :D). Your script should now look like this:


program New;
{.include srl/srl.scar}

type
TDoor = Record
loc : TPoint;
color : Integer;
end;

function FindDoorMM: TDoor;
var
i, Red, Green, Blue, GC, TestColor, unlikely: Integer;
P, V: TPointArray;
begin
begin
GC := 246;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 20);
Writeln( IntToStr(High(p)));
for i:=0 to High(p)-1 do
begin
Unlikely := 0;
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
if (Red > 195) then
if (Blue < 5) then
if (Green < 5) then
begin
if GetColor(P[i].x + 1, P[i].y + 1) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x + 1, P[i].y - 1) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x + 1, P[i].y) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x, P[i].y + 1) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x, P[i].y - 1) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x, P[i].y) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x - 1, P[i].y + 1) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x - 1, P[i].y - 1) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x - 1, P[i].y) = TestColor then
unlikely := unlikely + 1;
writeln( IntToStr(unlikely));
if (Unlikely < 5) and (Unlikely > 0) then
begin
end;

begin
end.


Now you can see the reason why we had to reset the "unlikely" value earlier.
Yet, there is still a problem which has remained unfixed: The pixel which might have the guessed color, might be on the edge of the walking flag, thus returning 3 to 4 neighbor pixels. This is why we are searching again, but only for that color, and in an area of 9 square pixels. The flag would return quite a large number of found colors, while a door can return a maximum of 8 or so. Now we just have to add the limitations of the number of the colors that can be found, add the results, and add the part which happens if the finding should fail.


program New;
{.include srl/srl.scar}

type
TDoor = Record
loc : TPoint;
color : Integer;
end;


function FindDoorMM: TDoor;
var
i, Red, Green, Blue, GC, TestColor, unlikely: Integer;
P, V: TPointArray;
begin
GC := 246;
FFlag(0);
FindColorsSpiralTolerance(MMCX, MMCY, P, GC, MMX1, MMY1, MMX2, MMY2, 20);
Writeln( IntToStr(High(p)));
for i:=0 to High(p)-1 do
begin
Unlikely := 0;
if rs_OnMinimap(P[i].x,P[i].y) then
begin
TestColor := GetColor(P[i].x,P[i].y);
ColorToRGB(TestColor, Red, Green, Blue);
if (Red > 195) then
if (Blue < 5) then
if (Green < 5) then
begin
if GetColor(P[i].x + 1, P[i].y + 1) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x + 1, P[i].y - 1) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x + 1, P[i].y) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x, P[i].y + 1) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x, P[i].y - 1) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x, P[i].y) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x - 1, P[i].y + 1) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x - 1, P[i].y - 1) = TestColor then
unlikely := unlikely + 1;
if GetColor(P[i].x - 1, P[i].y) = TestColor then
unlikely := unlikely + 1;
writeln( IntToStr(unlikely));
if (Unlikely < 5) and (Unlikely > 0) then
begin
FindColorsSpiralTolerance(P[i].x, P[i].y, V, TestColor, P[i].x-3, P[i].y-3, P[i].x+3, P[i].y+3, 0);
Writeln( IntToStr(High(v)));
if (High(v) < 12) then
if (High(v) > 3) then
begin
Result.Color := TestColor;
Result.Loc := P[i];
Writeln(' Door Minimap Color = '+IntToStr(Result.Color));
Writeln(' Found at: ('+IntToStr(Result.Loc.x)+'|'+IntToStr(Result.Loc.y)+')');
exit;
end;
end;
end;
end;
end;
WriteLn('Door Minimap Color could NOT be Found!');
Result.Color := 0;
Result.Loc := Point( 0, 0);
end;
begin
end.


Now guess what? You are finished! You have just done something yourself, which you could have taken out of the SRL library, but now you have two benefits, first of all, you learned something new/a new usage, and secondly, you now understand the code which you are using. I don't think I need to tell anyone that for intermediate scripters, the DoorProfiles.Scar file is just plain gibberish.

CONGRATULATIONS! upon completing another tutorial! :)

Claymore

2008-07-17 11:31:36

Very nice guide! I also liked the script for finding the RGB. Not only does it find the RGB, but it also helps us calculate the Results. (R-G etc..) Very nice guide, infact! 4 Stars and a "Nice Good Job"

LOL forgot about the new update on the Tutorail.

lordsaturn

2008-07-17 11:38:47

Wow pure, amazing tutorial, very detailed, and nice functions.

Pure1993

2008-07-17 11:48:59

Thanks a bunch for all the positiv review you guys! The work did pay off ^^

Although, about me maybe being dev someday, I think that wouldn't be the right place for me.. I've heard they are trying to get new SRL versions out faster now than they were up until 4 days ago, and I am wayyyyy to lazy ;)

ZephyrsFury

2008-07-17 11:53:50

I'm pretty sure GC stands for Generic Colour :p

Also using RGB and GetColors isn't the only way to filter out the incorrect colours. It really depends on what you're trying to autocolour and the colour/objects unique characteristics. Its only the most common method.

Other than that it a great tutorial. Nicely set out and detailed. :D

Claymore

2008-07-17 11:54:25

LOL, thats too bad then.

Lee Lok Hin

2008-07-17 11:58:21

Nice! Finally realised how autocolors worked. Rep nad nice work.

Incidentally, I think I might use one of your lumby colors if possibly?

Queso

2008-07-17 12:01:43

Now only if we could turn the road color red and blue like you did :p

Nice tut! Helped me!

Pure1993

2008-07-17 12:03:50

@ Zeph: ummmm, yeah… i knew that with GC… just tried to see if you knew it… so… umm… yeah, alright, i edited my post with the reason "ownt by zep xD", you pleased now? :D Did I say that it was the only way? geesh, gotta read through my thread again… but thanks for the comment :)

@lee lok hin: [Kingly Voice] Yes, you may use it.[/Kingly Voice] xD
Always glad to help :)

ZephyrsFury

2008-07-17 12:09:35

From: Pure1993
@ Zeph: ummmm, yeah… i knew that with GC… just tried to see if you knew it… so… umm… yeah, alright, i edited my post with the reason "ownt by zep xD", you pleased now? :D Did I say that it was the only way? geesh, gotta read through my thread again… but thanks for the comment :)


:p

No you did not say it was the only way however you concentrated on that one method throughout. Perhap it would be better to show a couple more examples using different methods but of course that would make it a lot longer. :)

Pure1993

2008-07-17 13:50:56

Hmm… I might be able to add something there… Give me a few days to look at other autocolor function and to write my own, and then one more day to expand this tut ;)

Edit: Moved to a real section! Thanks to whoever did it :D

The_Shermanator

2008-07-17 23:27:28

VERY NICE!!!
Thank you soo much, it really helped me make mine(which worked perfectly)!

Rep++

Hobbit

2008-07-18 00:18:27

From: Pure1993
Edit: Moved to a real section! Thanks to whoever did it :D


I see people still don't understand the new tutorial Island.
Well I will be making a new more detailed announcement about it in a few days after I'm finished cleaning it up.

Your Welcome ;)

BobboHobbo

2008-07-18 02:30:41

All i can say is… WOW. Good job!

EvilChicken!

2008-07-18 04:05:12

Wooow.
Expect a cup soon, my friend.
(Tutorial writer's, that is.)

I am sad because I can't rep+ you twice.
VERY good job, hoping to see more of these from you.

And, why not add the new autocolorthingy that came in rev 18 or 19?

I know Sum already has a tut about it, but you could do it too :)

Dusk412

2008-07-18 04:15:13

Thank you, I have been looking around at different autocolor tutorials (cuz I suck at it :D) but this one explained it quite clearly. It took me a second to understand that bit about making sure pixels above and below, etc. were the same color but then i remembered it was in a for statement so the whole function would not fail if it picked a pixel at the edge of the road. Hehe oops. Anyways thanks again. You did a great job :D. Maybe do an XYZ next for me :p?

Pure1993

2008-07-18 04:20:48

Wow, so many good replies, never though that possible :D
@ Hobbit: I do understand it, but I was wondering when posting this, how long it would take for a mod to move this into the appropriate section. :D
@EvilChicken: Sweetness, now we only need to get the higher ups to think that it deserves a cup, as well ;)
Although, I am not sure if I should write a new tut for this new function (I always foget the name, lol), Sum's tut is quite good, but maybe I will add it to this guide eventually. Right now I am looking into ColorSpeedmodifiers a bit, and at the other Autocolor concepts in the Autocolor.scar… still lots of work ahead of me (trying to get at least a small update to this thread every day or two, let's see if I can keep my goal :))
@ All the others: Sorry I didn't reply to each of you individually, but all I can always say is: Thanks a lot for the great feedback. This really gets me in the mood to write more, and to improve what I already wrote :D (btw, I am not any less thankful, no matter how often I say it ^^)
@ Dusk: There is an idea… :D

Pure1993

2008-07-18 07:44:26

ATTENTION: Update 1 Released!!!!!!!!!
(sorry for bumb, simply had to get some attention ;))

Naike

2008-07-18 08:30:50

Nice work ork rk k
I think i be learning this by tommorow :O
Need to fix up my computer first xD

ShowerThoughts

2008-07-18 08:56:36

I just get where u r talking about 0_o

Gu3st...

2008-07-18 10:25:03

HERMPIE! :D

YAY! now i finally get it! but.. High(P)-1 is not the way to do it, high finds the highest index, that means GetArrayLength(P)-1

Pure1993

2008-07-18 12:07:32

Oh yeah, thanks for clearing that up zytex… I guess it doesn't make any difference at all ("High" returns one number less than "GetArrayLength", and seeing as that there always need to be at least 9 pixels of the same color around for the methode I introduced), but I guess formalities are formalities ;).
Hey, and also, I finally learned the difference between "high" ang "getarraylength", thanks ^^
@ Hermpie: Why does your post make no sense to me at all? :confused: lol
@ N1ke: good luck with your comp ^^

tarajunky

2008-07-18 12:50:49

This tutorial definitely gets the Tarajunky seal of approval.


Well done.

Gu3st...

2008-07-18 12:55:40

that means a tutorial writer cup?

Claymore

2008-07-18 14:04:36

I printed this tutorial =3 Now to read it WITHOUT hurting my eyes by looking at the screen too close :3

ALSO, very nice! HSL, great job!

i printed 10 pages of the tutorial..this is the last time i am going to print a tutorial… my binder is full, im almost out of lined paper (I ran out of blank white papers), i can;t use the color printer (My dad said he uses it for photographs and that i can't use it :(), and i got 4 tutorials (TPA, Auto Color, and i forgot the other 2 :3) and 2 scripts. (Maple Forest Fire, and the other one is a s3cr3T, but i need help with it…. My TAutoColor wont find the Varrock Road Color (I know I should use FindVarrockRoadColor, but come on… Sometimes you got to be more original right? :3). Well time to read HSL pce.

Pure1993

2008-07-18 15:26:32

@Deathsytex: I'm glad you like this tut and, um, yeah, um, sorry for making this tut so long, but if I would have shortened it, I might have missed some crutial setps. ;)

@Tara: Hehe, with all these comments I could make a commercial advertising this tut! Tara's seal of Approval, 14 out of 14 vote "great" (the one point at "not so good" was a mistake ^^), and lots of other comments.

@Zytex: Probably not (…yet (at least :D)). But heck, the only difference between the official cup, and the non-official "cups" is that it displays the official ones next to your avy. And if you consider that the tut writer cup is the only cup that doesn't increase your avy (well, apart from best newcommer, and there was another one I think…), who cares ^^. (Don't get me wrong mods/admins, I would still be greatly honored to recieve an official cup, so don't let this post influence any sort of maybe futur decision… xD)

Claymore

2008-07-18 15:30:02

So are you going to add (Im not expert but i have heard of these things.) XYZ colors? (Is it even related to colors =p)

Pure1993

2008-07-18 15:36:43

I am going to add XYZ colors eventually, and yes, their prinziple in Autocoloring is the same as the one listed. But first I will finish the HSL one's with a few examples, and how to add it into our already existing one's, and not to forget, the tool will be expanded ^^. The only problem is that I will be gone over the Weekend, so I will try to Finish the HSL one now (already 9:30 PM here), post it, and then catch up when I'm back. The problem from that point on is that I am learning along with this tut, because my knowledge about XYZ colors could be summed up in 3 to 4 statements at the moment ^^

Claymore

2008-07-18 16:49:25

LoL, how much of XYZ do you know? Well you don't have to rush, people can wait. It is infact the quality of the guide that matters :3

Good luck on finding a way to explain XYZ and finishing off HSL

Pure1993

2008-07-18 17:20:00

Update 3 Completed! I Finished The Hsl Autocoloring! Come And Take A Look!

C ya all on Monday. :)

silverstreek

2008-07-18 17:37:10

Amazing tutorial I had to read some parts over a few times to understand it, but its great. Ty!

Pure1993

2008-07-22 18:40:11

No problem, always happy to help, but if some certain parts gave you some troubles, I'd be happy for you to tell me, so I can make it easier to understand. :)

Because these froums have been down for a few days, I did not get a chance to update this. Also, I have a visitor over for a few days, so I will not be able to post updates regulary, but i will try as often as possible. I'm sorry for any inconvinience this might have caused. (hehe, that sounded professional ;))

Laur€ns

2008-07-23 09:56:23

Give this guy a cup! Rep+'d, now I understand it. Always wondered how it works.. :)

Hobbit

2008-07-26 16:14:07

From: Pure1993
@ Hobbit: I do understand it, but I was wondering when posting this, how long it would take for a mod to move this into the appropriate section. :D


Fairly fast.

Ghostman

2008-07-26 19:48:10

Nice Tut, I wish i could turn the road a different color but anyway back to the point, very nice and detailed.


Rep++

tarajunky

2008-07-31 14:16:36

I've never used HSL autocoloring before, but I'm not sure if H-S, S-L, and H-L are the correct operations to use, or if they help you at all.

When I first designed FindRoadColor long ago, there was one fundamental problem with it. When you first logged into a world, the minimap would be dark. You had to refresh the screen one time to get the 'normal' colors. So, if you hopped worlds and picked colors, you wouldn't get one range, you would get two. Like for Red, the first dark colors might be between 60-80 while the normal lighter colors would be 100-120. It was easily fixed by just refreshing the screen one time before autoing, but I noticed something. I noticed that ALL the values were reduced by a similar amount. So even though Red or Green values might be very different, Red-Green would be in a stable range for all the road colors.

So that's the history behind using Red - Green, etc. I don't know if Hue - Saturation actually helps anything. The simplest thing to do would be to plug all the values into a script those you posted here and see if doing a subtraction or addition or any other mathematical operation with the values helps you to identify a unique color. For example, it might be the Hue alone is a better characteristic for autocoloring purposes than Hue - Saturation would be. You want whatever gives you the narrowest, most unique range to check your color against.

Pure1993

2008-08-01 16:51:15

Yeah, you have a good point. The thing is: I personally only use RGB autocoloring the way you applied it in your autocoloring (btw, great fan of your autocolor.scar functions :D), and I'm content with that. But, HSL is a different perspectiv on colors, and even if it isn't really needed at all, and I don't want to teach "this is one way and it is the only way" in my tutorials, but rather create a full view perspective. That way you can be more creative while scripting and experiment around a bit. And hey, there is no punishment for not reading the HSL part ^^.

EvilChicken!

2008-08-02 20:17:08

@Update2: Fail:
procedure HSLTools;
begin
ColorToXYZ(TheColor,H,S,L); <–


XYZ?

Otherwise REALLY great tut.

Make another one like this one and I'll kill myself if you don't get a cup.

Pure1993

2008-08-03 04:41:53

Omg, I must have been REALLY sidetracked when I wrote that part… -.-
Thanks a lot for pointing that out :D
Hmm… I might write another tut, but first of all I'll keep my tut runner up and running (or better yet GET him up and running as well as I want it :D)… but, don't kill yourself if I don't get a cup, it won't be the same without you! ;)

jas0npc

2008-08-03 05:09:03

Have got to say fantastic, Now that I have started to learn to script, tut`s like these that explain why we do the things we do, Make learning easier. keep it up.

rep added as soon as i figure out how. lol

EvilChicken!

2008-08-03 06:31:12

Small suggestion: add a table of contents at the very start of that sexy tut to make it somewhat more organized.

From: jas0npc
Have got to say fantastic, Now that I have started to learn to script, tut`s like these that explain why we do the things we do, Make learning easier. keep it up.

rep added as soon as i figure out how. lol


Blue box next to the red cross beneath the "location" thingy in his name, to the very right.

Pure1993

2008-08-03 06:40:05

Hmm, sounds like a good idea… I'll post it after the update of my script, which should be quite soon :D
Thanks for all the suggestions/notifications on problems ^^

jas0npc

2008-08-03 07:07:36

[QUOTE=Blue box next to the red cross beneath the "location" thingy in his name, to the very right.

Many thanks, its very well hidden.:duh:

Scaper

2008-08-05 23:35:30

wow man just wow massive improvement since last time i saw it

"you deserve the tut writer cup for this tutorial man";)

rep++ again

Macrosoft

2008-08-11 13:35:31

Me thinks me gets it!!!!
Me wants to gives you thanks!
I is much happy that me did a good grammar :)!

Ok, now Im going to be a "know it all SRL member":)

Correct me if im wrong but i believe this:

      if InRange(Red - Blue, 24, 30) then
if InRange(Red - Green, 4, 14) then
if InRange(Green - Blue, 15, 23) then
if InRange(Round(H - L), 0, 8) then
if InRange(Round(S - H), -2, 5) then
if InRange(Round(S - L), 1, 9) then
if GetColor(P[i].x + 2, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 1) = TestColor then
if GetColor(P[i].x, P[i].y + 2) = TestColor then
if GetColor(P[i].x + 2, P[i].y) = TestColor then
if GetColor(P[i].x, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y) = TestColor then
if GetColor(P[i].x + 2, P[i].y + 1) = TestColor then
if GetColor(P[i].x + 1, P[i].y + 2) = TestColor then
begin
Result := TestColor;
Writeln(' Lumbridge Road Color = '+IntToStr(Result));
exit;
end;

can be this:

      if InRange(Red - Blue, 24, 30)
and InRange(Red - Green, 4, 14)
and InRange(Green - Blue, 15, 23)
and InRange(Round(H - L), 0, 8)
and InRange(Round(S - H), -2, 5)
and InRange(Round(S - L), 1, 9)
and GetColor(P[i].x + 2, P[i].y + 2) = TestColor
and GetColor(P[i].x + 1, P[i].y + 1) = TestColor
and GetColor(P[i].x, P[i].y + 2) = TestColor
and GetColor(P[i].x + 2, P[i].y) = TestColor
and GetColor(P[i].x, P[i].y + 1) = TestColor
and GetColor(P[i].x + 1, P[i].y) = TestColor
and GetColor(P[i].x + 2, P[i].y + 1) = TestColor
and GetColor(P[i].x + 1, P[i].y + 2) = TestColor then
begin
Result := TestColor;
Writeln(' Lumbridge Road Color = '+IntToStr(Result));
exit;
end;

I just like it better that way for some reason…lol


Now that I have pissed you off…Amazing tutorial! I finally understand autocolor. The visuals really help! It looks like you put a lot of time and effort into this and trust me, it paid off. Thanks so much for making this tut!:)

Now that Iv made you feel good about yourself:

I sort of got this when I read the tutorial, not everyone is a genius like you and me ;). So you may want to put, as a conclusion:

In conclusion, autocolor uses a special kind of tolerance to find a color. This tolerance is customized to have more tolerance for certain parts of a color (such as red blue and green) based on how Jagex randomizes that specific color.

I know, im pwnage :)

Also, is there a function that goes through the procedure that this thread suggests? If there isnt; I call dibs on making it ;).

Pure1993

2008-08-12 13:35:16

@Scaper: thanks, me is honored. :D

@Macrosoft: Wow, you gets it! me thinks now that you be smart! But me be pissed because you not likes me standardz…. xD
[Correct grammar from this point onwards ;)]
Well, everyone can choose their own style, BUT what if someone came along and had this porblem:
"ZOMG! IT FAILS! ME NOT 1337 ANYM0RZ! ME N33D2 2 KN0W WH@TS WR0NG!" well, if that should happen, you could put a begin and end at the "if"'s, and make it write "found 1", found 2", found 3", etc. and find his incorrect value then, thats how I got around to get a feel for the right ranges ^^.
Alright, now I have to say np at the thx's you gave me… hmmm… what next… oh yeah, now I need to feel smart because you said something like that, and I have to be pissed again because you downgraded me down to the same "stage" you are in (you called both of ous genius… -.-) :p /jk xD

Now I have to say: good idea, I will add that as an intro though :p

and about a function to go through these procedures??? me be confused, me gots no glue whatz you meanz… :confused: :D

tarajunky

2008-08-12 14:36:16

The problem with 1 and 2 and 3 and 4 and 5 and 6 is that it will have to check the validity of all 6 every time.

If you use if .. then for each of them, then the first time it missed one it skips all the rest. If you're checking through thousands of pixels, then it can add up.

'And' works, but it's not as efficient.

Macrosoft

2008-08-12 19:49:10

my gets owned :(

What I mean is a function you input like 4 or five colors (same color but from different worlds) that does the red-green green-blue etc thing and then finds the three positive ones and adds to the highest and subtracts from the lowest and then does the whole if if if if thingy.

Basically its an autocolor function where you input the 4-6 colors and it does the rest for you.

footballjds

2008-12-24 07:02:05

very NICE! rep++
i still don't understand why you subtract red-blue or w/e??
but its still nice

Pure1993

2008-12-26 18:33:45

Alright, well, here I am again and back to answering those questions (sorry, I know this stuff is sort old by now, but heck, it might still help someone ^^).

The whole system is elimination. Basically, it searches for something similar to the color given. Now, let's say you want to find the road color. Now, the building color, the road color, and the castle color might all fit into that wide tolerance. Then it does the substraction in order to widen the gap of difference between those similar colors. For example, the road and the building color might look very similar, so that even the RGB values are quite similar. But, after the substraction of certain values (which you can easily find out by testing), the difference is big enough to sort out and eliminate very similar but wrong colors (e.g. a rock, road, building colors).

This might sound a bit confusing, especially if you don't have a very good idea of what RGB actually is and what range of values affects a color in a certain way. If that's the case, I'd advise you to open Paint, or any other graphical program and find some way to "create" a color. There you should find an RGB option with sliders. Have fun playing around.^^

footballjds

2008-12-28 20:48:55

From: Pure1993
Alright, well, here I am again and back to answering those questions (sorry, I know this stuff is sort old by now, but heck, it might still help someone ^^).

The whole system is elimination. Basically, it searches for something similar to the color given. Now, let's say you want to find the road color. Now, the building color, the road color, and the castle color might all fit into that wide tolerance. Then it does the substraction in order to widen the gap of difference between those similar colors. For example, the road and the building color might look very similar, so that even the RGB values are quite similar. But, after the substraction of certain values (which you can easily find out by testing), the difference is big enough to sort out and eliminate very similar but wrong colors (e.g. a rock, road, building colors).

This might sound a bit confusing, especially if you don't have a very good idea of what RGB actually is and what range of values affects a color in a certain way. If that's the case, I'd advise you to open Paint, or any other graphical program and find some way to "create" a color. There you should find an RGB option with sliders. Have fun playing around.^^


nieslie auto color ftw? :D thats what ill do

Gearsnare

2009-04-06 19:21:04

Finally I understand autocoloring, all thanks to you and your great tutorial.

Thank you very much!

ShowerThoughts

2009-04-16 21:45:52

Epic!
You could go a little bit deeper into the why do you divide and multiply those RGB etc.

Gu3st...

2009-04-17 01:05:37

How do I convert R G and B into scar color? (A)

Pure1993

2009-04-17 23:32:44

Lol, I haven't checked this tutorial in ages… didn't think anyone is still visiting it. :D

@Zyt3x: Did you try to do the following: Open Scar.exe >> Help >> Help F1 >> [ctrl + f] {Type:} RGB >> {Click on:} "Search" ?
There you will find the following option:

function RGBtoColor(R, G, B: Integer): TColor;
Converts RGB values to a color.
;)

But I am interested in the code of that function… so if anyone knows it, feel free to post here… :D

@Hermpie: Where am I dividing/multiplying? I haven't multiplied a single time in the entire tutorial, but if you are reffering to this:

program ColorsToRGBTool;
{.include srl/srl.scar}

const
TheColor = 16777215; //white background of the Scar program, substitute it with any color you want.

var
Red, Blue, Green: Integer;

begin
Red := (TheColor mod 256);
Green := ((TheColor / 256) mod 256);
Blue := ((TheColor / 256) / 256);
Writeln('----------------------------------------------');
Writeln('The color '+IntToStr(TheColor));
Writeln('Was turned into the following values: ');
Writeln('Red = '+IntToStr(Red));
Writeln('Green = '+IntToStr(Green));
writeln('Blue = '+IntToStr(Blue));
Writeln('----------------------------------------------');
end.
Then the reason is simple: This is the exact same thing as "ColorToRGB", which is a function included in the "Help" section of Scar, it is the first function in the "Color conversion functions:" section. ;)

Well, since this tutorial is still being used, I'll update the picture links which have appearently become obsolete.

ShowerThoughts

2009-04-18 00:02:43

Yes, but why do you divide? I see it as a trick I know how it works, but what's the reason.
You still got msn?

Pure1993

2009-04-18 01:05:19

Yeah, I still have MSN, but quite honestly, I forgot my password :(
I'll create a new account tomorrow

Anyway, I'll try to explain it one last time, just for you ;)
When you are picking a color with scar, it converts the color into an integer. You might be aware of that. Now, if you have read the tutorial, you know, that every color is made up of red, green, and blue colors.
Now, the integers, which Scar returns when selecting a color, aren't random, neither has every existing color been specificly named. It goes through a little process of identification, and then combines the values of the certain characteristics (including HSL and RGB) to make a single number out of it. The ColorToRGB simply reverses that process.

I hope this is somewhat understandable, and that it is correct, because I have not done a single second of research on what I have just written, so it is only my best guess. :p

Gu3st...

2009-04-18 01:05:21

From: Pure1993
Lol, I haven't checked this tutorial in ages… didn't think anyone is still visiting it. :D

@Zyt3x: Did you try to do the following: Open Scar.exe >> Help >> Help F1 >> [ctrl + f] {Type:} RGB >> {Click on:} "Search" ?

woah.. lol :)
Thank you :P

EDIT: Omfg it works! :D
EDIT2:
From: Hermpie
Yes, but why do you divide? I see it as a trick I know how it works, but what's the reason.
You still got msn?

He divides to get the correct answer

Pure1993

2009-04-18 01:09:46

No problem mate ;)

Pure1993

2009-04-18 16:25:08

NEW UPDATE 3: Introduction on how to use auto coloring to create your very own Minimap Door finding procedure!
You will find this on the second reply to this thread, because my first post had too many pictures for this new forum board, so I can't edit it without removing the pictures, which I don't feel like doing.

PS: Sorry for the double Post ;)

x[Warrior]x3500

2009-04-20 05:08:26

thx for finally adding the HSL thing. i checked up on this about 2-3weeks back and it didnt have it yet. but thx. and dang… i wish i know about colortorgb/colortohsl a long time ago.

Pure1993

2009-04-20 15:39:57

erm, tbh, the HSL thing has been there for ages now, the new thing I added has been the different ways to apply the principle of autocoloring. You'll find it on the second reply, because there wasn't enough space on the main post. ;)