Hi, I am using FindColorTolerance to find a certain colour on the MM. I was wondering if someone could give me a basic idea of what the usual range of tolerance values is, i.e. is 1 useless, 15 really high, etc. Thanks in advance!
Hi, I am using FindColorTolerance to find a certain colour on the MM. I was wondering if someone could give me a basic idea of what the usual range of tolerance values is, i.e. is 1 useless, 15 really high, etc. Thanks in advance!
I think it depends on the color you are trying to find..
For example I think that SymbolColors hardly change on the MM, however the RoadColor changes drammaticly.
You could use a function in SRL (FindColorTolRaiser) that highers the tolerance untill it finds the color..
Autocoloring MM colors is awfully hard, specially using to color system scar has.
I'd suggest going on many different worlds, color pick the color of the item your using, although the colors you get maybe thoasands and maybe even 10 thoasands apart, they will be simalair on RBG.
If using scar, the tolerance for MM colors should be 2000, which may seem ridiculous, but take a look at the AutoColor in SRL, and you'll get an idea of how it's done.
I'll will post an autocolor for ladder on minimap using RGB soon.
Tol 255 will find anything.
Thanks for all the help, everyone. I noticed, as per nielsies' comments, that certain things are less prone to change, for me, it only really mattered for a door on the minimap, so I wrote this, which is specific to my script...
Do you think this would consistently work? Don't go and test it or anything, but just from what you can see. I tried looking at TaraJunky's work in AutoColour.scar, but it just confused the living sh*t out of me.SCAR Code:function GetDoorColor:integer;
begin;
begin;
if FindDTM(DoorMM,x,y,570,100,720,150) then
begin
Result := (GetColor(x,y));
Writeln('Using DTM, Door Colour is ' + IntToStr(Result) + '.')
end else
begin
if FindColorTolerance(x,y,230,570,100,720,150,30) then
begin
Result := (GetColor(x,y))
Writeln('Using FindColorTol, Door Colour is ' + IntToStr(Result) + '.')
end else
begin
WriteLN('Door colour not found.')
Result := 0
end;
end;
end;
end;
You are in luck, a few devs made some leet auto door colors the other day. I will post a couple.
Edit:
Cheesehunk's
SCAR Code:function FindDoorColor: Integer;
var
arRoughDoorColors, arFineDoorColors: TPointArray;
i, bmpRedDot: Integer;
begin
bmpRedDot := BitmapFromString(2, 2, 'FE2020FC0606FC0606F10000');
FindColorsSpiralTolerance(MMCX, MMCY, arRoughDoorColors, 241, MMX1, MMY1, MMX2, MMY2, 20);
for i := 0 to GetArrayLength(arRoughDoorColors) - 1 do
begin
FindColorsSpiralTolerance(arRoughDoorColors[i].x, arRoughDoorColors[i].y, arFineDoorColors, 241, arRoughDoorColors[i].x - 4, arRoughDoorColors[i].y - 4, arRoughDoorColors[i].x + 4, arRoughDoorColors[i].y + 4, 20);
if(GetArrayLength(arFineDoorColors) = 3)and
(not(FindBitmapToleranceIn(bmpRedDot, x, y, arRoughDoorColors[i].x - 4, arRoughDoorColors[i].y - 4, arRoughDoorColors[i].x + 4, arRoughDoorColors[i].y + 4, 20)))then
begin
Result := GetColor(arRoughDoorColors[i].x, arRoughDoorColors[i].y);
Writeln('Found possible door at x = ' + IntToStr(arRoughDoorColors[i].x) + ' y = ' + IntToStr(arRoughDoorColors[i].y));
FreeBitmap(bmpRedDot);
Exit;
end
end;
FreeBitmap(bmpRedDot);
Writeln('Door color not found.');
end;
I think mine is a bit slower, but I'll post it anyways
SCAR Code:function GetDoorColor:integer;
var Color,tmpx,tmpy,MinOfRange:integer;
Length206,Length217,Length233,Length241:integer;
Array206,Array217,Array233,Array241:array of tpoint;
RangeOfOthers206,RangeOfOthers217,RangeOfOthers233,RangeOfOthers241:integer;
tmpbool:boolean;
begin
for Color:=200 to 254 do
begin
if not(((Color=206)or(Color=217)or(Color=233)or(Color=241))) then
begin
if FindColor(tmpx,tmpy,Color,mmx1,mmy1,mmx2,mmy2) then
begin
result:=Color;
tmpbool:=true;
end;
end;
if tmpbool then break;
end;
if not(tmpbool) then
begin
//writeln('its a drop dot color');
FindColorsTolerance(Array206,206,mmx1,mmy1,mmx2,mmy2,0);
Length206:=getarraylength(Array206);
FindColorsTolerance(Array217,217,mmx1,mmy1,mmx2,mmy2,0);
Length217:=getarraylength(Array217);
FindColorsTolerance(Array233,233,mmx1,mmy1,mmx2,mmy2,0);
Length233:=getarraylength(Array233);
FindColorsTolerance(Array241,241,mmx1,mmy1,mmx2,mmy2,0);
Length241:=getarraylength(Array241);
RangeOfOthers206:=max(Length233,max(Length217,Length241))-min(Length233,min(Length217,Length241));
RangeOfOthers217:=max(Length233,max(Length206,Length241))-min(Length233,min(Length206,Length241));
RangeOfOthers233:=max(Length206,max(Length217,Length241))-min(Length206,min(Length217,Length241));
RangeOfOthers241:=max(Length233,max(Length217,Length206))-min(Length233,min(Length217,Length206));
MinOfRange:=min(RangeOfOthers206,min(RangeOfOthers217,min(RangeOfOthers233,RangeOfOthers241)));
case MinOfRange of
RangeOfOthers206: result:=206;
RangeOfOthers217: result:=217;
RangeOfOthers233: result:=233;
RangeOfOthers241: result:=241;
end;
end;
end;
As everyone is happily posting his / her doorcolorfinders, I'll suppose I go and post mine too.
As I'm currently busy with a Draynor WheatPicker / Banker I noticed that there are doors with different colors. I mean that I had 5 doors on my MM and 4 of them had the same color (Fence was included by that 4). Another door was slightly different.. Due the fact that that door was one of the most left doors I wrote this Function:
SCAR Code:Function FindFenceColor(AtWheat:Boolean): Boolean;
var Tol: integer;
begin
repeat
if(not(LoggedIn))then Exit;
if Atwheat then MMScannerTol(xx, yy, 245, 'DownUp', 560, 2, 715, 95, Tol) else
MMScannerTol(xx, yy, 245, 'RightLeft', 650, 37, 675, 90, Tol)
if not (FindColor(x, y, 233, xx -5, yy-5, xx+55, yy+55)) then FenceColor := GetColor(xx, yy)
if ((xx <> 0) and (not (FenceColor = 233)) and (FenceColor > 200) and (FenceColor <300) and (FindColorFromCentre(x, y, xx, yy, RoadColor, 4, 0))) then Break else Tol := Tol + 5
until Tol >= 25
Result := True;
Tol := 0
if ((xx <> 0) and (not (FenceColor = 233)) and (FenceColor > 200) and (FenceColor <300)) then Result := True else
begin
FenceColor := 0;
exit;
end
WriteLn('Color of the fence = ' +inttostr(FenceColor));
end;
MMScannerTol is a function I wrote which scans the MM for the first matched color it finds from a direction. As you may have seen I use the direction DownUp which scans the MM beginning at the bottom..
This way I will probably always find the correct Color..
This ColorFinder is not as good as the above, but you might want to check if you also have different doorcolors in your area..
Now I'm thinking of using the above ColorFinder and change FindColor[Tolerance] with MMScanner[Tol]![]()
The more the merrier, here's mine!
Code:program FindDoorColor; {.include SRL/SRL.scar} var DoorColor:integer; var ColorArray: array of integer; Function CountArray:integer; var TestColor,n:integer; begin TestColor:=GetColor(x,y); For n:= 0 to 32 do begin if ColorArray[n]=TestColor then result:=result+1; end; end; Function FindDoorColor:integer; var a,b,i,j,n:integer; begin a:=MMX1; b:=MMY1; repeat; a:=a+1; repeat; b:=b+1; if FindColorTolerance(x,y,255,a,b,a,MMY2,10) then begin b:=y; SetArrayLength(ColorArray,32); n:=0; for i:= 0 to 3 do begin for j:= 0 to 7 do begin ColorArray[n]:=GetColor(a+i,b-3+j); n:=n+1; end; end; if CountArray=4 then begin Result:=GetColor(x,y); exit; end; end else b:=MMY2; until b>=MMY2; until a>=MMX2; end; begin SetupSRL; ActivateClient; Doorcolor:=FindDoorColor; end.
Could you post a screenshot of the doors being different colors please?
Well OK, heres the screenshot. When I looked closer I saw that it wasn't actually a door, but I think all of the posted DoorColorFinders can't make the difference..
The doors in de green circles are the same color, the blue one is different..
The same thing happens for walls. Walls that run N, S, E, and W are one color and walls that run at an angle (NW,NE,SW,SE) are a different color.
Does that mean that also your DoorColorFinder can get the ''wrong'' color?
If that's true, how can you solve it? Is my way the best(for now)?
Wow...well thanks a lot everyone for your very complicated/I don't understand half of it functions... I feel guilty putting something in my script that I don't even understand though...
Script and position specific procedures are always best. For instance, in my Chickenkiller when I want to cook chickens, I need to walk right up next to the door. I do this by scanning the MM left to right for the RoadColor, since the road goes right up to the door and no further. That procedure wouldn't work for 99% of other people that wanted to walk next to a door, but it works perfectly in that script at that position.
It seems that most of these procedures that were posted are generic. In other words, they are meant to find the door color in any script at any position.
Mine is based on the simple fact that doors almost always take up 4 pixels on the minimap no matter which angle they are facing. So, if you find exactly four pixels in a small chunk of the MM, it is most likely going to be a door.
Mine works fine, even if a lot of stuff is on the ground (red dots). However, it may accidentally pick the color of that angled door in that specific situation. Dunno...
Hmmm....Nice doorfinder procedures...now to test 'em all and see which works the best...
Interested in C# and Electrical Engineering? This might interest you.
Ah mine would have picked the majority in that case, but only because it's lower. You could modify it to keep going after it found the first, and return multiple colors. And then determine which is which.
You may also be interested in this. It spits out one Tpoint for each door on the minimap.
(I will clean it up and release it as one function eventually)
SCAR Code:program New;
{.include SRL/SRL.scar}
var doorcolor:integer;
var skippingarray:tboxarray;
AOTPA:array of TpointArray;
vx,f,vy:integer;
function GetDoorColor:integer;
var Color,tmpx,tmpy,MinOfRange:integer;
Length206,Length217,Length233,Length241:integer;
Array206,Array217,Array233,Array241:array of tpoint;
RangeOfOthers206,RangeOfOthers217,RangeOfOthers233,RangeOfOthers241:integer;
tmpbool:boolean;
begin
for Color:=200 to 254 do
begin
if not(((Color=206)or(Color=217)or(Color=233)or(Color=241))) then
begin
if FindColor(tmpx,tmpy,Color,mmx1,mmy1,mmx2,mmy2) then
begin
result:=Color;
tmpbool:=true;
end;
end;
if tmpbool then break;
end;
if not(tmpbool) then
begin
//writeln('its a drop dot color');
FindColorsTolerance(Array206,206,mmx1,mmy1,mmx2,mmy2,0);
Length206:=getarraylength(Array206);
FindColorsTolerance(Array217,217,mmx1,mmy1,mmx2,mmy2,0);
Length217:=getarraylength(Array217);
FindColorsTolerance(Array233,233,mmx1,mmy1,mmx2,mmy2,0);
Length233:=getarraylength(Array233);
FindColorsTolerance(Array241,241,mmx1,mmy1,mmx2,mmy2,0);
Length241:=getarraylength(Array241);
RangeOfOthers206:=max(Length233,max(Length217,Length241))-min(Length233,min(Length217,Length241));
RangeOfOthers217:=max(Length233,max(Length206,Length241))-min(Length233,min(Length206,Length241));
RangeOfOthers233:=max(Length206,max(Length217,Length241))-min(Length206,min(Length217,Length241));
RangeOfOthers241:=max(Length233,max(Length217,Length206))-min(Length233,min(Length217,Length206));
MinOfRange:=min(RangeOfOthers206,min(RangeOfOthers217,min(RangeOfOthers233,RangeOfOthers241)));
case MinOfRange of
RangeOfOthers206: result:=206;
RangeOfOthers217: result:=217;
RangeOfOthers233: result:=233;
RangeOfOthers241: result:=241;
end;
end;
end;
function tPtArrayToStr(newTPoint: TPointArray): string;
var
i: Integer;
begin
for i:=0 to GetArrayLength(newTPoint)-1 do
begin
Result := Result + IntToStr(newTPoint[i].x) + ',' +
IntToStr(newTPoint[i].y);
if (not (i = (GetArrayLength(newTPoint) - 1))) then
Result := Result + ' ';
end;
end;
function BoxArrayToArrayOfTPA(Color:integer; Boxes:array of TBox): array of TPointArray;
var i:integer;
begin
setarraylength(result,getarraylength(boxes));
for i:=0 to GetArrayLength(Boxes)-1 do
FindColorsTolerance(result[i],Color,Boxes[i].x1,Boxes[i].y1,Boxes[i].x2,Boxes[i].y2,0);
end;
procedure DisplayPicture(TheBox:tbox);
var
DebugCanvas, ClientCanvas: TCanvas;
w, h, bmp: Integer;
begin
w := Thebox.x2 - Thebox.x1;
h := Thebox.y2 - Thebox.y1;
ActivateClient;
DisplayDebugImgWindow(w, h);
DebugCanvas := GetDebugCanvas;
ClientCanvas := GetClientCanvas;
SafeCopyCanvas(ClientCanvas, DebugCanvas, TheBox.x1,TheBox.y1,TheBox.x2,TheBox.y2, 0, 0, w, h);
//bmp := BitmapFromString(w, h, '');
//CopyClientToBitmap(bmp,Thebox.x1, Thebox.y1, Thebox.x1 + w, Thebox.y1 + h);
//DisplayDebugImgWindow(w, h);
//CopyCanvas(GetBitmapCanvas(bmp), GetDebugCanvas, TheBox.x1,TheBox.y1,TheBox.x2,TheBox.y2, 0, 0, w, h);
end;
function SurroundBox(px,py:integer):Tbox;
var Inner,Outer:Tbox;
PointColor,dx,dy:integer;
begin
PointColor:=GetColor(px,py);
Inner.x1:=px;
Inner.y1:=py;
Inner.x2:=px;
Inner.y2:=py;
Outer.x1:=px-5;
Outer.y1:=py-5;
Outer.x2:=px+5;
Outer.y2:=py+5; {
repeat
// Outer.x1:=Outer.x1-1;
Inner.x1:=Inner.x1-1;
//writeln('test3');
until (not(FindColorSkipBox(dx,dy,PointColor,Outer.x1,Outer.y1,Inner.x1,Outer.y2,Inner)));
//writeln('test2');
repeat
// Outer.Y1:=Outer.Y1-1;
Inner.Y1:=Inner.y1-1;
until (not(FindColorSkipBox(dx,dy,PointColor,Outer.x1,Outer.y1,Outer.x2,Outer.y2,Inner)));
//writeln('test1');
repeat
//Outer.x2:=Outer.x2+1;
Inner.x2:=Inner.x2+1;
until (not(FindColorSkipBox(dx,dy,PointColor,Outer.x1,Outer.y1,Outer.x2,Outer.y2,Inner)));
// writeln('test1');
repeat
// Outer.y2:=Outer.y2+1;
Inner.y2:=Inner.y2+1;
until (not(FindColorSkipBox(dx,dy,PointColor,Outer.x1,Outer.y1,Outer.x2,Outer.y2,Inner)));
//writeln('test1');
Result:=inner; }result:=outer;
end;
var arraylength,i,t:integer;
tpa:tpointarray;
function MidPointOfLine(TheArray:array of Tpoint):Tpoint;
//var tmpresult:T:integer;
begin
result:=TheArray[round(getarraylength(TheArray)/2)-1];
end;
function IsTPointInDropDot(TP:Tpoint):boolean;
var color:integer;
begin
color:=getcolor(TP.x,TP.y);
case color of
206:
begin
if (getcolor(TP.x,TP.y-1)=233)
or (getcolor(TP.x-1,TP.y)=241)
or (getcolor(TP.x-2,TP.y+1)=217)then
result:=true;
end;
217:
begin
if (getcolor(TP.x+1,TP.y-1)=241)
or (getcolor(TP.x+2,TP.y-1)=206)
or (getcolor(TP.x+2,TP.y-2)=233)then
result:=true;
end;
233:
begin
if (getcolor(TP.x,TP.y+1)=206)
or (getcolor(TP.x-1,TP.y+1)=241)
or (getcolor(TP.x-2,TP.y+2)=217)then
result:=true;
end;
241:
begin
if (getcolor(TP.x+1,TP.y-1)=233)
or (getcolor(TP.x+1,TP.y)=206)
or (getcolor(TP.x-1,TP.y+1)=217)then
result:=true;
end;
else result:=false;
end;
end;
function IgnoreDropDots(TheList:array of array of tpoint):array of array of tpoint;
var
pTo,pFrom:integer;
pList:integer;
begin
result:=TheList;
for pList :=0 to getarraylength(result)-1 do
begin
pTo:=0-1;
pFrom:=0;
for pFrom:=0 to getarraylength(result[pList])-1 do
begin
if not(IsTPointInDropDot(result[pList][pFrom])) then
begin
pTo:=pTo+1;
result[pList][pTo]:=result[pList][pFrom];
end;
end;
setarraylength(result[pList],pto+1);
end;
pTo:=0-1;
pFrom:=0;
for pFrom:=0 to getarraylength(result)-1 do
begin
if not(getarraylength(result[pFrom])=0) then
begin
pTo:=pTo+1;
result[pTo]:=result[pFrom];
end;
end;
// writeln(inttostr(pto));
setarraylength(result,pto+1);
end;
function FindDoorColor: Integer;
var
arRoughDoorColors, arFineDoorColors: TPointArray;
i, bmpRedDot: Integer;
begin
bmpRedDot := BitmapFromString(2, 2, 'FE2020FC0606FC0606F10000');
FindColorsSpiralTolerance(MMCX, MMCY, arRoughDoorColors, 241, MMX1, MMY1, MMX2, MMY2, 20);
for i := 0 to GetArrayLength(arRoughDoorColors) - 1 do
begin
FindColorsSpiralTolerance(arRoughDoorColors[i].x, arRoughDoorColors[i].y, arFineDoorColors, 241, arRoughDoorColors[i].x - 4, arRoughDoorColors[i].y - 4, arRoughDoorColors[i].x + 4, arRoughDoorColors[i].y + 4, 20);
if(GetArrayLength(arFineDoorColors) = 3)and
(not(FindBitmapToleranceIn(bmpRedDot, x, y, arRoughDoorColors[i].x - 4, arRoughDoorColors[i].y - 4, arRoughDoorColors[i].x + 4, arRoughDoorColors[i].y + 4, 20)))then
begin
Result := GetColor(arRoughDoorColors[i].x, arRoughDoorColors[i].y);
Writeln('Found possible door at x = ' + IntToStr(arRoughDoorColors[i].x) + ' y = ' + IntToStr(arRoughDoorColors[i].y));
FreeBitmap(bmpRedDot);
Exit;
end
end;
FreeBitmap(bmpRedDot);
Writeln('Door color not found.');
end;
begin
SetupSRL;
t:=getsystemtime;
doorcolor:=finddoorcolor;
// DisplayPicture(657,120,671,129);
//mybox:=Surroundbox(myx,myy);
//setarraylength(skippingarray,1);
//skippingarray[0].x1:=0;
//skippingarray[0].y1:=0;
//skippingarray[0].x2:=1;
//skippingarray[0].y2:=1;
//arraylength:=1;
repeat {566,6,730,163}
if FindColorSkipBoxArray(vx,vy,DoorColor,mmx1,mmy1,mmx2,mmy2,skippingarray) then
begin
//writeln('found');
//writeln(inttostr(arraylength));
//arraylength:= getarraylength(skippingarray);
arraylength:=arraylength+1;
setarraylength(skippingarray,arraylength);
skippingarray[arraylength-1]:= Surroundbox(vx,vy);
//writeln('test1');
end;
//writeln(inttostr(arraylength));
wait(1);
until ((isfkeydown(11)) or (not(FindColorSkipBoxArray(vx,vy,DoorColor,mmx1,mmy1,mmx2,mmy2,skippingarray))));
//writeln('done');
{ repeat
repeat
wait(1000);
until isfkeydown(12);
i:=i+1;
DisplayPicture(Skippingarray[i]);
repeat
wait(1000);
until isfkeydown(11);
until i=(arraylength-1); }
AOTPA:=BoxArrayToArrayOfTPA(doorColor,Skippingarray)
AOTPA:=ignoredropdots(aotpa);
setarraylength(TPA,getarraylength(AOTPA));
for f:= 0 to getarraylength(AOTPA)-1 do
TPA[f]:=MidPointOfLine(AOTPA[f]);
//for f:= 0 to getarraylength(AOTPA)-1 do
//writeln(tPtArrayToStr(AOTPA[f]));
for f:= 0 to getarraylength(AOTPA)-1 do
writeln(inttostr(tpa[f].x)+','+inttostr(tpa[f].y));
writeln(inttostr(getsystemtime-t)+' ms');
end.
What can you do with that array of tpoints?? Use this
SCAR Code:function RearrangeTPA(thearray:array of tpoint; startpt, endpt:integer; dox,up:boolean):array of tpoint;
var
temp, pArray : integer;
done : boolean;
ttp:tpoint;
tmpTPA : array of tpoint;
begin
setarraylength(tmpTPA,getarraylength(thearray));
tmpTPA:=thearray;
setarraylength(result,endpt+1-startpt);
if not(up) then
begin
if dox then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].x < tmpTPA[pArray + 1].x) then
begin
//temp := tmpTPA[pArray].x;
//tmpTPA[pArray].x := tmpTPA[pArray + 1].x;
//tmpTPA[pArray + 1].x := temp;
ttp := tmpTPA[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;
done := false;
end;
end;
until(done);
end;
if not(dox) then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].y < tmpTPA[pArray + 1].y) then
begin
//temp := thearray[pArray].y;
//tmpTPA[pArray].y := tmpTPA[pArray + 1].y;
//tmpTPA[pArray + 1].y := temp;
ttp := thearray[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;
done := false;
end;
end;
until(done);
end;
end;
if up then
begin
if dox then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].x > tmpTPA[pArray + 1].x) then
begin
//temp := tmpTPA[pArray].x;
//tmpTPA[pArray].x := tmpTPA[pArray + 1].x;
//tmpTPA[pArray + 1].x := temp;
ttp := tmpTPA[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;
done := false;
end;
end;
until(done);
end;
if not(dox) then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].y > tmpTPA[pArray + 1].y) then
begin
//temp := tmpTPA[pArray].y;
// tmpTPA[pArray].y := tmpTPA[pArray + 1].y;
//tmpTPA[pArray + 1].y := temp;
ttp := tmpTPA[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;
done := false;
end;
end;
until(done);
end;
end;
pArray:=startpt-1;
for temp:=0 to getarraylength(result)-1 do
begin
pArray:=pArray+1;
result[temp]:=tmpTPA[pArray];
end;
end;
It can sort TPoints by x or y, ascending or descending, and return a section of that array as a smaller array. I am using in lumby castle to get the 3 most eastern doors, and then the 2 northern most out of those. Which are the doors connected to the big room, which is where I will auto floor color.
SCAR Code:AOTPA:=BoxArrayToArrayOfTPA(doorColor,Skippingarray)
AOTPA:=ignoredropdots(aotpa);
setarraylength(TPA,getarraylength(AOTPA));
for f:= 0 to getarraylength(AOTPA)-1 do
TPA[f]:=MidPointOfLine(AOTPA[f]);
//for f:= 0 to getarraylength(AOTPA)-1 do
//writeln(tPtArrayToStr(AOTPA[f]));
for f:= 0 to getarraylength(tpa)-1 do
writeln(inttostr(tpa[f].x)+','+inttostr(tpa[f].y));
writeln(' ');
TPA2:=RearrangeTPA(TPA, 0, 2,true,true);
for f:= 0 to getarraylength(tpa2)-1 do
writeln(inttostr(tpa2[f].x)+','+inttostr(tpa2[f].y));
writeln(' ');
TPA3:=RearrangeTPA(TPA2, 0, 1,false,true);
for f:= 0 to getarraylength(tpa3)-1 do
writeln(inttostr(tpa3[f].x)+','+inttostr(tpa3[f].y));
writeln(inttostr(getsystemtime-t)+' ms');
writeln(inttostr(getcolor(tpa3[1].x,tpa3[0].y)));
end.
Boreas, can you explain me the last 2 functions plz?![]()
Take the first thing, add the second thing to it, and change the bottom part to the third thing, and you get this:
SCAR Code:program New;
{.include SRL/SRL.scar}
var doorcolor:integer;
var skippingarray:tboxarray;
AOTPA:array of TpointArray;
vx,f,vy:integer;
function GetDoorColor:integer;
var Color,tmpx,tmpy,MinOfRange:integer;
Length206,Length217,Length233,Length241:integer;
Array206,Array217,Array233,Array241:array of tpoint;
RangeOfOthers206,RangeOfOthers217,RangeOfOthers233,RangeOfOthers241:integer;
tmpbool:boolean;
begin
for Color:=200 to 254 do
begin
if not(((Color=206)or(Color=217)or(Color=233)or(Color=241))) then
begin
if FindColor(tmpx,tmpy,Color,mmx1,mmy1,mmx2,mmy2) then
begin
result:=Color;
tmpbool:=true;
end;
end;
if tmpbool then break;
end;
if not(tmpbool) then
begin
//writeln('its a drop dot color');
FindColorsTolerance(Array206,206,mmx1,mmy1,mmx2,mmy2,0);
Length206:=getarraylength(Array206);
FindColorsTolerance(Array217,217,mmx1,mmy1,mmx2,mmy2,0);
Length217:=getarraylength(Array217);
FindColorsTolerance(Array233,233,mmx1,mmy1,mmx2,mmy2,0);
Length233:=getarraylength(Array233);
FindColorsTolerance(Array241,241,mmx1,mmy1,mmx2,mmy2,0);
Length241:=getarraylength(Array241);
RangeOfOthers206:=max(Length233,max(Length217,Length241))-min(Length233,min(Length217,Length241));
RangeOfOthers217:=max(Length233,max(Length206,Length241))-min(Length233,min(Length206,Length241));
RangeOfOthers233:=max(Length206,max(Length217,Length241))-min(Length206,min(Length217,Length241));
RangeOfOthers241:=max(Length233,max(Length217,Length206))-min(Length233,min(Length217,Length206));
MinOfRange:=min(RangeOfOthers206,min(RangeOfOthers217,min(RangeOfOthers233,RangeOfOthers241)));
case MinOfRange of
RangeOfOthers206: result:=206;
RangeOfOthers217: result:=217;
RangeOfOthers233: result:=233;
RangeOfOthers241: result:=241;
end;
end;
end;
function tPtArrayToStr(newTPoint: TPointArray): string;
var
i: Integer;
begin
for i:=0 to GetArrayLength(newTPoint)-1 do
begin
Result := Result + IntToStr(newTPoint[i].x) + ',' +
IntToStr(newTPoint[i].y);
if (not (i = (GetArrayLength(newTPoint) - 1))) then
Result := Result + ' ';
end;
end;
function BoxArrayToArrayOfTPA(Color:integer; Boxes:array of TBox): array of TPointArray;
var i:integer;
begin
setarraylength(result,getarraylength(boxes));
for i:=0 to GetArrayLength(Boxes)-1 do
FindColorsTolerance(result[i],Color,Boxes[i].x1,Boxes[i].y1,Boxes[i].x2,Boxes[i].y2,0);
end;
procedure DisplayPicture(TheBox:tbox);
var
DebugCanvas, ClientCanvas: TCanvas;
w, h, bmp: Integer;
begin
w := Thebox.x2 - Thebox.x1;
h := Thebox.y2 - Thebox.y1;
ActivateClient;
DisplayDebugImgWindow(w, h);
DebugCanvas := GetDebugCanvas;
ClientCanvas := GetClientCanvas;
SafeCopyCanvas(ClientCanvas, DebugCanvas, TheBox.x1,TheBox.y1,TheBox.x2,TheBox.y2, 0, 0, w, h);
//bmp := BitmapFromString(w, h, '');
//CopyClientToBitmap(bmp,Thebox.x1, Thebox.y1, Thebox.x1 + w, Thebox.y1 + h);
//DisplayDebugImgWindow(w, h);
//CopyCanvas(GetBitmapCanvas(bmp), GetDebugCanvas, TheBox.x1,TheBox.y1,TheBox.x2,TheBox.y2, 0, 0, w, h);
end;
function RearrangeTPA(thearray:array of tpoint; startpt, endpt:integer; dox,up:boolean):array of tpoint;
var
temp, pArray : integer;
done : boolean;
ttp:tpoint;
tmpTPA : array of tpoint;
begin
setarraylength(tmpTPA,getarraylength(thearray));
tmpTPA:=thearray;
setarraylength(result,endpt+1-startpt);
if not(up) then
begin
if dox then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].x < tmpTPA[pArray + 1].x) then
begin
//temp := tmpTPA[pArray].x;
//tmpTPA[pArray].x := tmpTPA[pArray + 1].x;
//tmpTPA[pArray + 1].x := temp;
ttp := tmpTPA[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;
done := false;
end;
end;
until(done);
end;
if not(dox) then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].y < tmpTPA[pArray + 1].y) then
begin
//temp := thearray[pArray].y;
//tmpTPA[pArray].y := tmpTPA[pArray + 1].y;
//tmpTPA[pArray + 1].y := temp;
ttp := thearray[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;
done := false;
end;
end;
until(done);
end;
end;
if up then
begin
if dox then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].x > tmpTPA[pArray + 1].x) then
begin
//temp := tmpTPA[pArray].x;
//tmpTPA[pArray].x := tmpTPA[pArray + 1].x;
//tmpTPA[pArray + 1].x := temp;
ttp := tmpTPA[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;
done := false;
end;
end;
until(done);
end;
if not(dox) then
begin
repeat
done := true;
for pArray := 0 to (getarraylength(thearray) - 2) do
begin
if(tmpTPA[pArray].y > tmpTPA[pArray + 1].y) then
begin
//temp := tmpTPA[pArray].y;
// tmpTPA[pArray].y := tmpTPA[pArray + 1].y;
//tmpTPA[pArray + 1].y := temp;
ttp := tmpTPA[pArray];
tmpTPA[pArray] := tmpTPA[pArray + 1];
tmpTPA[pArray + 1] := ttp;
done := false;
end;
end;
until(done);
end;
end;
pArray:=startpt-1;
for temp:=0 to getarraylength(result)-1 do
begin
pArray:=pArray+1;
result[temp]:=tmpTPA[pArray];
end;
end;
function SurroundBox(px,py:integer):Tbox;
var Inner,Outer:Tbox;
PointColor,dx,dy:integer;
begin
PointColor:=GetColor(px,py);
Inner.x1:=px;
Inner.y1:=py;
Inner.x2:=px;
Inner.y2:=py;
Outer.x1:=px-5;
Outer.y1:=py-5;
Outer.x2:=px+5;
Outer.y2:=py+5; {
repeat
// Outer.x1:=Outer.x1-1;
Inner.x1:=Inner.x1-1;
//writeln('test3');
until (not(FindColorSkipBox(dx,dy,PointColor,Outer.x1,Outer.y1,Inner.x1,Outer.y2,Inner)));
//writeln('test2');
repeat
// Outer.Y1:=Outer.Y1-1;
Inner.Y1:=Inner.y1-1;
until (not(FindColorSkipBox(dx,dy,PointColor,Outer.x1,Outer.y1,Outer.x2,Outer.y2,Inner)));
//writeln('test1');
repeat
//Outer.x2:=Outer.x2+1;
Inner.x2:=Inner.x2+1;
until (not(FindColorSkipBox(dx,dy,PointColor,Outer.x1,Outer.y1,Outer.x2,Outer.y2,Inner)));
// writeln('test1');
repeat
// Outer.y2:=Outer.y2+1;
Inner.y2:=Inner.y2+1;
until (not(FindColorSkipBox(dx,dy,PointColor,Outer.x1,Outer.y1,Outer.x2,Outer.y2,Inner)));
//writeln('test1');
Result:=inner; }result:=outer;
end;
var arraylength,i,t:integer;
tpa:tpointarray;
function MidPointOfLine(TheArray:array of Tpoint):Tpoint;
//var tmpresult:T:integer;
begin
if getarraylength(thearray)>1 then
result:=TheArray[round(getarraylength(TheArray)/2)-1];
if getarraylength(thearray)=1 then result:=thearray[0];
end;
function IsTPointInDropDot(TP:Tpoint):boolean;
var color:integer;
begin
color:=getcolor(TP.x,TP.y);
case color of
206:
begin
if (getcolor(TP.x,TP.y-1)=233)
or (getcolor(TP.x-1,TP.y)=241)
or (getcolor(TP.x-2,TP.y+1)=217)then
result:=true;
end;
217:
begin
if (getcolor(TP.x+1,TP.y-1)=241)
or (getcolor(TP.x+2,TP.y-1)=206)
or (getcolor(TP.x+2,TP.y-2)=233)then
result:=true;
end;
233:
begin
if (getcolor(TP.x,TP.y+1)=206)
or (getcolor(TP.x-1,TP.y+1)=241)
or (getcolor(TP.x-2,TP.y+2)=217)then
result:=true;
end;
241:
begin
if (getcolor(TP.x+1,TP.y-1)=233)
or (getcolor(TP.x+1,TP.y)=206)
or (getcolor(TP.x-1,TP.y+1)=217)then
result:=true;
end;
else result:=false;
end;
end;
function IgnoreDropDots(TheList:array of array of tpoint):array of array of tpoint;
var
pTo,pFrom:integer;
pList:integer;
begin
result:=TheList;
for pList :=0 to getarraylength(result)-1 do
begin
pTo:=0-1;
pFrom:=0;
for pFrom:=0 to getarraylength(result[pList])-1 do
begin
if not(IsTPointInDropDot(result[pList][pFrom])) then
begin
pTo:=pTo+1;
result[pList][pTo]:=result[pList][pFrom];
end;
end;
setarraylength(result[pList],pto+1);
end;
pTo:=0-1;
pFrom:=0;
for pFrom:=0 to getarraylength(result)-1 do
begin
if not(getarraylength(result[pFrom])=0) then
begin
pTo:=pTo+1;
result[pTo]:=result[pFrom];
end;
end;
// writeln(inttostr(pto));
setarraylength(result,pto+1);
end;
function FindDoorColor: Integer;
var
arRoughDoorColors, arFineDoorColors: TPointArray;
i, bmpRedDot: Integer;
begin
bmpRedDot := BitmapFromString(2, 2, 'FE2020FC0606FC0606F10000');
FindColorsSpiralTolerance(MMCX, MMCY, arRoughDoorColors, 241, MMX1, MMY1, MMX2, MMY2, 20);
for i := 0 to GetArrayLength(arRoughDoorColors) - 1 do
begin
FindColorsSpiralTolerance(arRoughDoorColors[i].x, arRoughDoorColors[i].y, arFineDoorColors, 241, arRoughDoorColors[i].x - 4, arRoughDoorColors[i].y - 4, arRoughDoorColors[i].x + 4, arRoughDoorColors[i].y + 4, 20);
if(GetArrayLength(arFineDoorColors) = 3)and
(not(FindBitmapToleranceIn(bmpRedDot, x, y, arRoughDoorColors[i].x - 4, arRoughDoorColors[i].y - 4, arRoughDoorColors[i].x + 4, arRoughDoorColors[i].y + 4, 20)))then
begin
Result := GetColor(arRoughDoorColors[i].x, arRoughDoorColors[i].y);
Writeln('Found possible door at x = ' + IntToStr(arRoughDoorColors[i].x) + ' y = ' + IntToStr(arRoughDoorColors[i].y));
FreeBitmap(bmpRedDot);
Exit;
end
end;
FreeBitmap(bmpRedDot);
Writeln('Door color not found.');
end;
var tpa2,tpa3:array of tpoint;
begin
SetupSRL;
t:=getsystemtime;
doorcolor:=finddoorcolor;
// DisplayPicture(657,120,671,129);
//mybox:=Surroundbox(myx,myy);
//setarraylength(skippingarray,1);
//skippingarray[0].x1:=0;
//skippingarray[0].y1:=0;
//skippingarray[0].x2:=1;
//skippingarray[0].y2:=1;
//arraylength:=1;
repeat {566,6,730,163}
if FindColorSkipBoxArray(vx,vy,DoorColor,mmx1,mmy1,mmx2,mmy2,skippingarray) then
begin
//writeln('found');
//writeln(inttostr(arraylength));
//arraylength:= getarraylength(skippingarray);
arraylength:=arraylength+1;
setarraylength(skippingarray,arraylength);
skippingarray[arraylength-1]:= Surroundbox(vx,vy);
//writeln('test1');
end;
//writeln(inttostr(arraylength));
wait(1);
until ((isfkeydown(11)) or (not(FindColorSkipBoxArray(vx,vy,DoorColor,mmx1,mmy1,mmx2,mmy2,skippingarray))));
//writeln('done');
{ repeat
repeat
wait(1000);
until isfkeydown(12);
i:=i+1;
DisplayPicture(Skippingarray[i]);
repeat
wait(1000);
until isfkeydown(11);
until i=(arraylength-1); }
AOTPA:=BoxArrayToArrayOfTPA(doorColor,Skippingarray)
AOTPA:=ignoredropdots(aotpa);
setarraylength(TPA,getarraylength(AOTPA));
for f:= 0 to getarraylength(AOTPA)-1 do
TPA[f]:=MidPointOfLine(AOTPA[f]);
//for f:= 0 to getarraylength(AOTPA)-1 do
//writeln(tPtArrayToStr(AOTPA[f]));
for f:= 0 to getarraylength(tpa)-1 do
writeln(inttostr(tpa[f].x)+','+inttostr(tpa[f].y));
writeln(' ');
TPA2:=RearrangeTPA(TPA, 0, 2,true,true);
for f:= 0 to getarraylength(tpa2)-1 do
writeln(inttostr(tpa2[f].x)+','+inttostr(tpa2[f].y));
writeln(' ');
TPA3:=RearrangeTPA(TPA2, 0, 1,false,true);
for f:= 0 to getarraylength(tpa3)-1 do
writeln(inttostr(tpa3[f].x)+','+inttostr(tpa3[f].y));
writeln(inttostr(getsystemtime-t)+' ms');
writeln(inttostr(getcolor(tpa3[1].x,tpa3[0].y)));
end.
Run it in lumby castle, and you should get the coords of the doors of the big room.
RearrangeTPA sorts a TPA (tpoint array) by x or y, ascending or descending, and returns part of it as another array
TPA3:=RearrangeTPA(TPA2, 0, 1,false,true);
TPA3 in this example is the destination array of tpoint
TPA2 is the source array of tpoint
The first boolean is false, so it will sort by Y position
The second boolean is true, so it will be ascending
So it will sort the array by Y, with [0] having the lowest Y value. Then it will return an array containing [0] to [1], so the 2 most northern points in the array.
Thank you very much..
After reading the whole thing a few times, I do now pretty much understand it!..
Excellent. You should be proud of yourself considering I didn't comment it (which I should have, but I will get around to when I get time).
There are currently 1 users browsing this thread. (0 members and 1 guests)