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:
SCAR Code:
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:
SCAR Code:
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:
SCAR Code:
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:
SCAR Code:
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).
SCAR Code:
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").
SCAR Code:
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.
SCAR Code:
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:
SCAR Code:
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...
SCAR Code:
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.
SCAR Code:
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.
SCAR Code:
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 ^^)
SCAR Code:
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 ), so they might not always work, feel free to edit or/and use them, as long as I get creddited .
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 ). If you liked it, feel free to +Rep me, to rate, and to comment.
Update 1:
Welcome back again folks!
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 ).
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? ):
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? )! 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 )
SCAR Code:
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 ), so we will use the easy way for once... don't get used to it...
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!
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:
SCAR Code:
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:
SCAR Code:
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:
SCAR Code:
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
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