SRL Archive - Help and Support

GetMiniMapDotsIn subtract a color by another color?!


riwu

2012-11-14 04:50:42

GetMiniMapDotsIn gets the shadows of the dots, then i would expect it to search for the desired color (red, yellow etc) within a box above the shadows of the dots.

Instead, it takes a color found at some point near the shadows of the dots and subtract it by another point near it?!

if (GetColor(TPA[I].X-1, TPA[I].Y-1) - GetColor(TPA[I].X, TPA[I].Y-1) = Dif) then
What do you achieve by subtracting a color by another color? Do you get a unique resultant color that matches the color of yellow, white etc? But why not search for that color directly then?

The reason for this investigation is that it sometimes fails to retrieve dots that are close together.

The function for quick reference:

function GetMiniMapDotsIn(WhatDot: String; x1, y1, x2, y2: Integer): TPointArray;
var
I, Dif, Radius, Hi, C: Integer;
TPA: TPointArray;
begin
case LowerCase(WhatDot) of
'npc', 'n', 'yellow', 'y': Dif := 4369;
'item', 'i', 'red', 'r': Dif := 23;
'player', 'p', 'white', 'w': Dif := 1907997;
'friend', 'f', 'green', 'g': Dif := 5376;
'team', 't', 'blue', 'b', 'cape': Dif := 2171941;
{'clan', 'c', 'orange', 'o': Dif := -1;}
else
srl_Warn('GetMiniMapDotsIn', '"' + WhatDot + '" is not a valid dot type', warn_AllVersions);
end;
Freeze;
Radius := Max((x2-x1)div 2, (y2-y1)div 2);
FindColorsPie(TPA, 65536, 0, 0, 360, 0, radius, x1, y1, x2, y2, (x1+x2)div 2, (y1+y2)div 2);
Hi := High(TPA);
SetLength(Result, Hi + 1);
if (Hi < 0) then
begin
UnFreeze;
Exit;
end;
C := 0;
for I := 0 to Hi do
begin
if (GetColor(TPA[I].X-1, TPA[I].Y-1) - GetColor(TPA[I].X, TPA[I].Y-1) = Dif) then //?!?
begin
Result[C] := Point(TPA[I].x, TPA[i].y - 2);
Inc(C);
end;
end;
Unfreeze;
SetLength(Result, C);
end;

NKN

2012-11-14 06:44:56

Seems to be, they check 1 pixel to the X, and each dot has it's own special integer.

Look at the Dif at the top. Each one is different, so it just does that, and checks if equal to?

All in all, it's a unique color that only portrays to said color dot.

weequ

2012-11-14 16:30:32

So there is cases where only 1 pixel of a dot colour is visible where as the current method requires 2? The point of the current method is that there is no need for tolerance since the subtraction value remains constant even when the dot color changes. It is an old autocoloring method that works for many mm objects such as trees, rocks, etc.

mormonman

2012-11-14 17:50:39

I use this function to find dots, it just takes longer.
function mMiniMapDots(Which: String; B: TBox): TPointArray;
var
I, Dif, Radius, Hi, C, X, Y: Integer;
TPA: TPointArray;
begin
case LowerCase(Which) of
'npc', 'n', 'yellow', 'y': Dif := 4369;
'item', 'i', 'red', 'r': Dif := 23;
'player', 'p', 'white', 'w': Dif := 1907997;
end;
Freeze;
X := (b.x2-b.x1)/2;
Y := (b.y2-b.y1)/2;
Radius := Max(X, Y);
FindColorsPie(TPA, 65536, 0, 0, 360, 0, Radius,
B.X1, B.Y1, B.X2, B.Y2, (B.X1 + B.X2)/2, (B.Y1 + B.Y2)/2);
Hi := High(TPA);
SetLength(Result, Hi + 1);
if (Hi < 0) then
begin
UnFreeze;
Exit;
end;
C := 0;
for I := 0 to Hi do
begin
if (GetColor(TPA[I].X - 1, TPA[I].Y - 1) - GetColor(TPA[I].X, TPA[I].Y - 1) = Dif) then
begin
Result[C] := Point(TPA[I].x, TPA[i].y - 2);
Inc(C);
end else
if (GetColor(TPA[I].X + 1, TPA[I].Y) - GetColor(TPA[I].X + 2, TPA[I].Y) = Dif) then
begin
Result[C] := Point(TPA[I].x + 2, TPA[i].y - 1);
Inc(C);
end else
if (GetColor(TPA[I].X - 2, TPA[I].Y) - GetColor(TPA[I].X - 1, TPA[I].Y) = Dif) then
begin
Result[C] := Point(TPA[I].x - 1, TPA[i].y - 1);
Inc(C);
end;
end;
Unfreeze;
SetLength(Result, C);
RAaSTPA(Result, 1);
end;

NCDS

2012-11-14 18:48:40

IIRC it was done a year or two ago after an RS update left mmDots without any static colors. The catch, however, is that even though the colors were dynamic, the colors on those two pixels have a static relationship, and therefor make for a sensible comparison.

riwu

2012-11-14 23:14:19

From: NCDS
IIRC it was done a year or two ago after an RS update left mmDots without any static colors. The catch, however, is that even though the colors were dynamic, the colors on those two pixels have a static relationship, and therefor make for a sensible comparison.

Wow that's quite amazingly.
What's the theory behind this that the relationship between 2 dynamic colors is static? And how did the dev thought of/discover that? I'd personally never thought of that unless there's some known theory on subtraction of colors.
Is it something related to the way colors are labeled as decimals?

From: mormonman
I use this function to find dots, it just takes longer.

Thanks for the function! Rep+! Seems much more accurate:


I scatter 11 items close together, GetMiniMapDots only retrieved 9 points
[(634, 79), (625, 81), (621, 82), (635, 83), (631, 84), (636, 88), (632, 89), (628, 90), (623, 91)]
while yours detected all 11!
[(634, 79), (630, 80), (625, 81), (621, 82), (635, 83), (631, 84), (622, 87), (636, 88), (632, 89), (628, 90), (623, 91)]


One main constraint of item MM dots is that it may get covered up by npc dots.
My current idea is to locate the mm dot of the npc that i'm engaged in by finding out the direction through MS hp bar, then wait for the red dot that should replace the npc dot, which would be the loot dropped by the slain npc. Does that make sense or is there a better way?

Home

2012-11-15 15:11:36

@Riwu, the idea I think came from Flag (Same method is used to detect Flag)

Look into FindFlag2.

~Home

mormonman

2012-11-15 16:07:34

From: Home
@Riwu, the idea I think came from Flag (Same method is used to detect Flag)

Look into FindFlag2.

~Home


No that's backwards. I'm pretty sure flag was made afterwards.

riwu

2012-11-16 06:21:40

I still don't understand how i could utilize this technique in the future. So basically when i'm dealing with an object of dynamic colors, i should just trial and error around to see if the relationship between 2 colors on/near the obj is static? Still don't quite understand how i would go about doing this :confused:

Also @Home, in your FindFlag2, instead of going through the hassle of doing BitmapFrom..Client (;)) and setting it as target, why not just Freeze and directly search the color from rs client?
And how did you discover the static relationship of 2 dynamic colors near the flag? I just can't understand the thought process..

Something like this?

function FindFlag2(var X, Y: Integer): Boolean;
var
I, Hi: Integer;
TPA: TPointArray;
begin
Result := False;
Freeze;

FindColors(TPA, 65536, MMX1, MMY1, MMX2, MMY2);
FilterPointsDist(TPA, 0, 75.5, MMCX, MMCY);
Hi := High(TPA);
for I := 0 to Hi do
if ((GetColor(TPA[I].X - 1, TPA[I].Y - 1) - GetColor(TPA[I].X, TPA[I].Y - 1)) = 6381921) then
begin
Result := True;
X := TPA[I].X;
Y := TPA[I].Y;
Break;
end;

Unfreeze;
end;

Home

2012-11-17 13:03:51

From: riwu
I still don't understand how i could utilize this technique in the future. So basically when i'm dealing with an object of dynamic colors, i should just trial and error around to see if the relationship between 2 colors on/near the obj is static? Still don't quite understand how i would go about doing this :confused:

Also @Home, in your FindFlag2, instead of going through the hassle of doing BitmapFrom..Client (;)) and setting it as target, why not just Freeze and directly search the color from rs client?
And how did you discover the static relationship of 2 dynamic colors near the flag? I just can't understand the thought process..

Something like this?

function FindFlag2(var X, Y: Integer): Boolean;
var
I, Hi: Integer;
TPA: TPointArray;
begin
Result := False;
Freeze;

FindColors(TPA, 65536, MMX1, MMY1, MMX2, MMY2);
FilterPointsDist(TPA, 0, 75.5, MMCX, MMCY);
Hi := High(TPA);
for I := 0 to Hi do
if ((GetColor(TPA[I].X - 1, TPA[I].Y - 1) - GetColor(TPA[I].X, TPA[I].Y - 1)) = 6381921) then
begin
Result := True;
X := TPA[I].X;
Y := TPA[I].Y;
Break;
end;

Unfreeze;
end;


By back then I think that we had an discussion about it and I found it better by scanning it via bitmap :P
I can't really remember how did we discover it. Sorry :)

@Mor. Maybe you are right :)


~Home

weequ

2012-11-17 13:33:33

The point of using bitmap was that it only freezes the minimap while freeze freezes the whole client window. I think using bitmap is faster or uses less memory or both. Can't remember.

riwu

2012-11-17 20:10:15

I just tested the 2 methods:

program new;
{$DEFINE SMART}
{$I SRL/SRL.simba}

function FindFlag3(var X, Y: Integer): Boolean;
var
I, Hi: Integer;
TPA: TPointArray;
begin
Result := False;
Freeze;

FindColors(TPA, 65536, MMX1, MMY1, MMX2, MMY2);
FilterPointsDist(TPA, 0, 75.5, MMCX, MMCY);
Hi := High(TPA);
for I := 0 to Hi do
if ((GetColor(TPA[I].X - 1, TPA[I].Y - 1) - GetColor(TPA[I].X, TPA[I].Y - 1)) = 6381921) then
begin
Result := True;
X := TPA[I].X;
Y := TPA[I].Y;
Break;
end;

Unfreeze;
end;

var
t,i,x,y:integer;

begin
SetupSRL;

marktime(t);
for i:=1 to 1000 do
FindFlag3(x,y);

writeln('Freezing takes: ' + ToStr(timefrommark(t)));



marktime(t);
for i:=1 to 1000 do
FindFlag2(x,y);

writeln('Bitmap creation takes: ' + ToStr(timefrommark(t)));

end.
Ran it a few times, freezing is always faster:

Freezing takes: 6099
Bitmap creation takes: 6740

Freezing takes: 5741
Bitmap creation takes: 6615


I don't think freezing the client use any memory at all, you simply pause the canvas transfer which would mean even less resources needed? Creating a whole ~500x300 bitmap certainly takes more memory ;). The difference is pretty negligible though.



Anyway back to the topic, i just tried playing around with this concept, and gotcha!
The map icon for the onion has 2 distinct dynamic colors, of which left half of the icon occupy 1 and right half occupy another. Using the same concept, i subtract them and does indeed ended with a static result!
Does this work with mainscreen obj too? I tried some but doesn't seem to be the case.
Any idea why Jagex makes it so convenient for us? :whistling: