SRL Archive - SRL Archives

SmartColorsCustom


Sir R. M8gic1an

2008-02-23 06:17:51

well, to those who haven't heard about SmartColors tarajunky was the one who first made it. it'll look for you colors with absolutely no tol first, if it doesn't find them then it'll look with tol. the smart part is that when it finds what you're looking for it'll remember to color of where it found and look for that color in future times. it uses an array and the best colors will come first, and when a color gets a hit it'll move up the array.
Tarajunky's Thread

but some people found that principle and the code confusing and hard to understand. i studied the code, asked tara a few questions a came up with SmartColorsCustom.

It's as good as SmartColors, as fast as TPA's and as simple as FindObjCustom!


//by RM
Function CheckAndClick(var x, y:integer; text:TStringArray): boolean;
var
m:integer;
FoundIt:boolean;
begin
MMouse(x, y, 3, 3);
wait(100);
for m:=0 to high(text) do
begin
if IsUpText(text[m]) then
begin
writeln('text is up, '+text[m]);
FoundIt:=True;
break;
end;
end;

if FoundIt then
begin
GetMousePos(x, y);
Mouse(x, y, 3, 3, True);
Result := True;
end else
Result :=False;

end;

//Smart Colors By Tarajunky, Edited by Rasta Magician
Function SmartColorsCustom(name:string; UpText:TStringArray; colors:TIntegerArray):boolean;
var
j, k:integer;
b, Found:boolean;
var RMInt, RMx, RMy:integer;
var x,y,TestColor,a,l,m,i,red,green,blue, ClickColor:integer;
var p: array of Tpoint;

begin
for i:=0 to High(Find) do
begin
if lowercase(name) = Find[i].Name then
begin
b := True;
k := i;
end;
end;

if not b then //we have to add it.
begin
k:=GetArrayLength(Find);
SetArrayLength(Find, k+1);
Find[k].Name:= lowercase(name);
Find[k].UpText := UpText;
Find[k].Colors := colors;
end;

FFlag(0);
Wait(50);
Status('Finding '+name);
l:=GetArrayLength(Find[k].Colors); //Checks known colors first
if l>0 then
begin
for i:= 0 to l-1 do
begin
writeln('finding color: '+IntToStr(Find[k].Colors[i]));
FindColorsSpiralTolerance(MSCX,MSCY,p,Find[k].Colors[i],MSX1,MSY1,MSX2,MSY2,0);
m:=GetArrayLength(p);
if m>0 then
begin
if m > 30 then exit;
for a:= 0 to m-1 do
begin
if CheckAndClick(p[a].x,p[a].y, Find[k].UpText) then //Moves mouse to position, checks uptext and clicks if correct.
begin
result:=true;
if i>0 then //if the color is not in the first position of the array...
Swap(Find[k].Colors[i], Find[k].Colors[i-1]);
// Swap found color with the one ahead of it in the array
exit; // We found our color, so we exit the function completely.
end;
end;
end;
end;
end;
//We didn't find any known colors, so continue on to the tolerance search
for j:=0 to High(Find[k].Colors) do
begin
writeln('finding color '+IntToStr(Find[k].Colors[j])+' with tol: ');
FindColorsSpiralTolerance(MSCX, MSCY, p, Find[k].Colors[j],MSX1,MSY1,MSX2,MSY2,25);
l:=GetArrayLength(p);
if l>0 then
begin
if l > 30 then exit;
for i:= 0 to l-1 do
begin
TestColor:=GetColor(p[i].x,p[i].y); //Additional autocoloring to reduce wrong points. (Optional)
red:=(TestColor mod 256);
green:=((TestColor/256) mod 256);
blue:=((TestColor/256) / 256);
if ((green-blue)<=46) then if ((green-blue)>=24) then
if ((red-green)>=26) then if ((red-green)<=51) then
if ((red-blue)>55) then if ((red-blue)<=94) then
begin
Wait(20);
ClickColor:=GetColor(p[i].x,p[i].y);

for RMInt:=0 to High(Find[k].Colors) do
begin
if RMInt <> j then
if FindColorSpiralTolerance(RMx, RMy, Find[k].Colors[RMInt],x-5,y-5,x+5,y+5, 20) then
begin
Found:=True;
break;
end;
end;

If Found then
if CheckAndClick(p[a].x,p[a].y, Find[k].UpText) then //Move mouse, check uptext and click
begin
result:=true;
FindColorsSpiralTolerance(x,y,p,ClickColor,MSX1,MSY1,MSX2,MSY2,0);
if GetArrayLength(p)<20 then //Make sure that the color is somewhat rare, and doesn't take up half the screen
begin
a:=GetArrayLength(Find[k].Colors);
for i:= 0 to a-1 do
begin
if ClickColor=Find[k].Colors[i] then //If color is already in the array...
begin
if i>0 then
begin // Move it up one spot in the array search priority
Swap(Find[k].Colors[i], Find[k].Colors[i-1]);
end;
exit;
end;
end;
// if it's not in the array yet, then add it to the end of the array
SetArrayLength(Find[k].Colors,a+1);
Find[k].Colors[a]:=ClickColor;
Writeln(IntToStr(ClickColor)+' added to '+name+' array');
end;
exit;
end;
end;
end;
end;
end;
end;
that's the two functions you need. now there's also a Type Record that needs to be global:

type
Monster = record
Name: string;
UpText: TStringArray;
Colors: TIntegerArray;
end;
var
Find: Array of Monster;

i was killing chickens with just this earlier, worked wonderfully. and here's a very practical example of how to use it:


function FindMonster(name:string):boolean;
begin
case lowercase(name) of
'chicken':
Result := SmartColorsCustom('chicken', ['ttack', 'hicken', 'Chicken'], [2907004, 8036277, 3627894]);
'goblin':
Result := SmartColorsCustom('goblin', ['ttack','obl','goblin'], [000,000,000]);
'cow':
Result := SmartColorsCustom('cow', ['ttack','ow','Cow'], [000, 000, 000]);
end;
end;

begin
SetupSRL;
repeat
FindMonster('Chicken');
wait(4000);
until (IsFKeyDown(12))
end.


Pick the colors just before you run and you'll be amazed. This SmartColors is just as good as the One Tara uses in his chicken killer. Have fun, Script, and be glad of how simple SmartColors Now Is.

note: if your looking for similar things like rocks it's betther to do:
['mithril','mine','rock'] than ['mine','rock','mithril']; or even just['mithril'] to make sure it doesn't mess up with other rocks.

Ps: you can use this for anything, like rocks and trees.
PPs: if you use this remember to credit tarajunky and me, and please only use SmartColorsCustom is members-only scripts. this is very powerful and simple to use, and we need more member only scripts.

~RM

n3ss3s

2008-02-23 06:32:18

Try not to do multiple FindColorsSpirals in a loop, do one and use something similar to my GrabTPA or so…

Sir R. M8gic1an

2008-02-23 06:37:23

could you please be a bit more specific? but this is the way tara does it, and all the FindColorsSpiral are for different reasons:
1st - Finding known colors with no tol
2nd - Finding Known colors WITH tol
3rd - Finding if there are other known colors close to the one we found with tol
4th - checking if the one we found with tol is rare so it can be added to the array.

and each time any loop restarts it's a different color

i don't see how a tpa would be usefull here, because of all the different reasons, tols and colors we are looking for?

~RM

oliver1205

2008-02-23 11:16:20

looks good, ill be sure to add this in, the next time i script.

Prince

2008-02-23 11:44:33

first of all it didnt work, and i dont know why but it wouldnt add tolerance, and it just kept trying to pick the flax

color x
adding tol: {blank}
color y
adding tol: {blank}
color z
adding tol: {blank}

thats what it did in an inifinite loop lol, so i repicked the colors that were onscreen currently and it worked perfectly, now if the tolerance worked im sure this would be just amazing

thanks a lot,
prince


edit: after testing for a bit i realized that the mouse moves in a very detectable way? while its trying to look and stuff it shakes after each click…correct me if im wrong, i love how this works, but isnt this detectable? thanks

tarajunky

2008-02-23 12:00:19

As Rasta said, you use multiple findcolorstolerance searches within a loop because you want to search for exact colors with no tolerance to increase your search specificity. Adding tolerance or searching for similar colors defeats the purpose of collecting the exact colors in the first place.

After running for a while, the array should arrange itself so that the best color is first in the array, the next best color is second, etc. At this point you should only be doing 1 FindColorsTolerance search most of the time because it will succeed the first time. And the times you do more than one search, it's so efficient that you would never notice it anyway.

As for the mouse 'shaking' that would be from the Mouse(x, y, 3, 3, True); part. Change 3,3 to whatever amount of variability you feel comfortable with. Also, Rasta I suggest you add a GetMousePos(x,y) before the actual mouse click movement. The way it is now you could have the first and second mouse movement up to 6 pixels apart, which may look weird.

Prince

2008-02-23 12:07:34

So basically let it run in that loop until it arranges itself? I'm not fully understanding what you are saying to me. Sorry i am really braindead right now

thanks,
prince

tarajunky

2008-02-23 12:49:03

You put generic colors into the function and it will search using tolerance, just like you do with FindObj and other similar functions. When it finds the object, it records the exact color that it actually found. The next time it searches, it looks for the exact color first. If it doesn't find it, it reverts back to the tolerance based search to try to find another color for the object.

Each time you use the tolerance based search and find a new exact color for the object, it gets saved to the color array. So, the script 'learns' the exact object colors as it runs.

As the array gets large, some of the colors will be better at detecting the object than others will. So, each time you search using the color array and actually find the object, that color gets moved forward in the array, and will get a higher search priority next time you look for the object.

So to summarize it does two things. It takes generic colors that you put in and finds exact colors. And it will sort the color array to prioritize the exact colors that most consistently find the object. So, over time as the script learns, you end up with a prioritized color array that you can use to find objects.

Sir R. M8gic1an

2008-02-23 13:43:25



color x
adding tol: {blank}
color y
adding tol: {blank}
color z
adding tol: {blank}


the fact that it says adding col means that it's looking with tolerance, the " : " souldn't actually be there, but i forgot to remove it :p it'll always look with the same amount of tol.

tara, i'll add that in in a moment :) thank you.

~RM

king vash

2008-02-23 16:20:24

very interesting idea, I'm definetly going to use this in my current script. do you think it will be added with the next revision or not?

Will this have to move the mouse more or less than running a couple findcolorspirals and comparing overlaps and moving mouse to those point?


Function CheckAndClick(var x, y:integer; text:TStringArray): boolean;
var
m:integer;
FoundIt:boolean;
begin
MMouse(x, y, 3, 3);
wait(100);
for m:=0 to high(text) do
begin
if IsUpText(text[m]) then
begin
writeln('text is up, '+text[m]);
FoundIt:=True;
break;
end;
end;

if FoundIt then
begin
GetMousePos(x, y);
Mouse(x, y, 3, 3, True);
Result := True;
end else
Result :=False;

end;
isn't the GetMousePos(x ,y); then Mouse(x ,y) redundant? won't it simply move the mouse alittle then click? what's the point of that?

Sir R. M8gic1an

2008-02-23 17:04:21

i doubt this will be in the next revision. there are already many object finding procedures in srl.

GetMousePos and Mouse will do exactly what you said it would do. the thing is that if GetMousePos wasn't there the x and y would still be referring to the position before you did MMouse with randomness. so it would make the mouse sort of shake. hard to explain, but you see a real difference.

it'll move the mouse less. When i pick the colors before running it i only move the mouse about once each time, if the colors were pre-picked it sometimes takes 3 moves and about after half an hour it always hits right on the spot everytime.

~RM

king vash

2008-02-23 19:11:11

I think I understand let me draw a picture and try to explain it.

It thinks the object is at 0,0 (using some colorfinding)
It Moves the MOUSE to a within a box defined by (-3,-3, 3, 3)
If it's matches a possible uptext it gets the coordinates
Now it clicks the MOUSE with 3 pixels random x,y meaning inside the box (-6,-6, 6, 6)


If you remove the GetMouse you would

It thinks the object is at 0,0 (using some colorfinding)
It Moves the MOUSE to a within a box defined by (-3,-3, 3, 3)
it has the correct uptext
Now it clicks the MOUSE with 3 pixels random off of old x,y meaning inside the box (-3,-3, 3, 3)


on the right side the rust colored square is the location the color is found, the black is the MMOUSE and the Blue is MOUSE

on the left the ruse is the location the color is found and the black is both MMOUSE and MOUSE

did i miss something? isn't the removed getmouse better?

tarajunky

2008-02-23 22:49:20

SCAR knows where the original object coordinates are. But you don't, and Jagex doesn't.

Instead of thinking about where the second click may be in relation to the original object position, you should think about where it will be in relation to the first mouse movement. That's what you see on the screen, and that's what Jagex is able to detect.

With GetMousePos added, the maximum distance you can move away from the first point is 3 pixels. And since Mouse uses a normal distribution, you are most likely to click near the first position.

Without GetMousePos, you can click up to 6 pixels away from the first mouse position. And if your first mouse position happens to be far from the original object x,y you are more likely to get a large second mouse movement, which makes it look erratic.

Personally, I think 3,3 for the second mouse movement is too large. I would personally use 1,1 or 1,2 or 2,2 (with GetMousePos so the second movement is small) but it's personal preference.

Sir R. M8gic1an

2008-02-24 02:25:43

actually ou missed it a lil bit.
this should help you see it better:

No GetMousePos -> GetMousePos


the red square is MMouse, the yellow squares are where mouse could be.

the dark red is the spot where we found it.

if we don't have GetMousePos the mouse could move 6 pixels away from where MMouse got it. with GetMousePos it'll max move 3 pixels away.

~RM