SRL Archive - OSR Help

String and bitmap questions


Boreas

2010-12-19 19:11:17

1) How do I convert an integer into a string with leading 0s? ie 5 to '05' 15 to '15'
'CleanChunk'+ Format('%.2d-%.2d',[Chunks.x,Chunks.y])+'.bmp'

2) How do I copy a section of the client to a bitmap, and make that bitmap the client?

    //Is this right?
MainBitmap := CreateBMP(128,128); //Create a bitmap 128x128
//What is the command to do this?
CopyClientToBitmap(MainBitmap, 564, 21, 691, 148, 0, 0, 127, 127)
//What is the command to do this?
SetTargetBitmap(MainBitmap);

3) How do I now copy a TBox out of MainBitmap into ChunkBitmap, but skipping pixels in the MainBitmap that are color 0?
        TmpString := CTWBPath + 'CleanChunk'+ Format('%.2d-%.2d',Chunks[i].x,Chunks[i].y)+'.bmp';
if FileExists(TmpString) then
ChunkBitmap := CreateBitmapFromFile(TmpString);
else then
ChunkBitmap := CreateBitmap(100,100);
end;
//How to do this while skipping pixels in box FragmentPixels in MainBitmap that are 0?
Copy from FragmentsPixels[i].x1, FragmentsPixels[i].y1, FragmentsPixels[i].x2 FragmentsPixels[i].y2 on MainBitmap
to FragmentsPos[i].x1, FragmentsPos[i].y1, FragmentsPos[i].x2, FragmentsPos[i].y2 on ChunkBitmap
SaveBitmapToFile(ChunkBitmap);
FreeBitmap(ChunkBitmap);
4) How do I reset the client back to SMART?

Wizzup?

2010-12-19 20:01:38

This should work for 4:


program new;
var a,b,c:integer;
begin
a:=getimagetarget; // get current image target
writeln(getimagetarget);
b:=createbitmap(100,100); // bitmap
FastDrawClear(b, clred); // paint it.... red?
settargetbitmap(b); // set bitmap as target
writeln(getcolor(10,10));
writeln(getimagetarget); // print current image target
c := getimagetarget; // get current, we need to free it later
setimagetarget(a); // restore old image target
freetarget(c); // free it
freebitmap(b); // free it
writeln(getcolor(10,10));
end.

E: Fixed it. Please re-read.

More info, needs to be documented: http://wizzup.org/simbadoc/scriptref/window.html
REMINDER TO SELF^

Boreas

2010-12-19 21:35:14

From: Wizzup?
This should work for 4:


program new;
var a,b,c:integer;
begin
a:=getimagetarget; // get current image target
writeln(getimagetarget);
b:=createbitmap(100,100); // bitmap
FastDrawClear(b, clred); // paint it.... red?
settargetbitmap(b); // set bitmap as target
writeln(getcolor(10,10));
writeln(getimagetarget); // print current image target
c := getimagetarget; // get current, we need to free it later
setimagetarget(a); // restore old image target
freetarget(c); // free it
freebitmap(b); // free it
writeln(getcolor(10,10));
end.

E: Fixed it. Please re-read.

More info, needs to be documented: http://wizzup.org/simbadoc/scriptref/window.html
REMINDER TO SELF^


Cool, thanks. Now that the bitmap is the target, can I copy a section from the target to a section of a second bitmap? And can I do that while skipping pixels in the firstbitmap/target that are color 0?

mastaraymond

2010-12-20 05:17:01

http://wizzup.org/simbadoc/scriptref/bitmaps.html#bitmapfromclient


http://wizzup.org/simbadoc/scriptref/bitmaps.html#fastdrawtransparent
Draws source bitmap on target bitmap, but does not copy the colours of the sourcebitmap which are the same as the "transparent" colour, which you can set by

http://wizzup.org/simbadoc/scriptref/bitmaps.html#settransparentcolor

As for the zero's:

program new;
begin
Writeln(Padz('5',2));
Writeln(Padz('15',2));
end.

Boreas

2010-12-20 08:28:07

For FastDrawTransparent, will it take all of the source bitmap, and put at x,y on the target bitmap? So I need to make the first bitmap the client, do BitmapFromClient to get a section of the first bitmap to be the second bitmap, then FastDrawTransparent the whole of the second bitmap to a certain position on the third bitmap.

If I make a bitmap the target, and then do FastSetPixel on the bitmap, is the target also updated?

Edit: so I finally installed Simba etc, and made my crappy gedit code compile, and it looks like almost everything is working except FastSetPixel. Does FastSetPixel not work when bmp is target?

program new;
{$Define SMART}
{$i srl\srl.scar}
{$i Reflection\reflection.simba}


const
CTWBOn = true; //Make true to help out CTWB
color_Black = 65536;
CTWBPath = AppPath + 'CTWB\';
var
CircleOffsets: TPointArray;

//LordSaturn
{function }procedure CTWBCollectDots(Bitmap: integer);//: TPointArray;
var
SearchColors: TIntegerArray;
OtherColors: T2DIntegerArray;
i, j, Hi, x, y, leftDev, rightDev, L, LTop: Integer;
ATPA: T2DPointArray;
TPA, FoundColorsTPA: TPointArray;
begin //red white yellow
//Freeze;
SearchColors := [217, 188, 14869218, 12961221, 56797, 52428];
SetLength(OtherColors, 3);
OtherColors[0] := [3553023, 789758, 2105598, 395004, 237, 206, 65536, 217, 188]; //red
OtherColors[1] := [16711422, 15527148, 13816530, color_Black, 14869218, 12961221]; //white
OtherColors[2] := [1179390, 195836, 62965, 56797, 60909, 52428, color_Black]; //yellow
LTop := 999;
//SetLength(Result, LTop);
for i := 0 to 5 do
begin
if FindColors(TPA, SearchColors[i], 14, 14, 113, 113) then
FoundColorsTPA := CombineTPA(FoundColorsTPA, TPA); //if one color is covered, we will find the other
if (i mod 2 = 1) then
begin
ATPA := TPAtoATPAEx(FoundColorsTPA, 1, 0);
Hi := High(ATPA);
for j := 0 to Hi do
begin
//if (GetColor(ATPA[j][0].x, ATPA[j][0].y+1) = color_Black) then //it is a dot
begin //begin finding the whole dot
leftDev := 0;
if (GetColor(ATPA[j][0].x-1, ATPA[j][0].y) = color_Black) then //finding the left bound of the dot
leftDev := -1
else
if (GetColor(ATPA[j][0].x-2, ATPA[j][0].y) = color_Black) then
leftDev := -2
else
if (GetColor(ATPA[j][0].x-1, ATPA[j][0].y) = 217) then
leftDev := -1;
rightDev := 0;
if (GetColor(ATPA[j][0].x+1, ATPA[j][0].y) = color_Black) then //finding the right bound of the dot
rightDev := 1
else
if (GetColor(ATPA[j][0].x+2, ATPA[j][0].y) = color_Black) then
rightDev := 2
else
if (GetColor(ATPA[j][0].x+1, ATPA[j][0].y) = 188) then
rightDev := 1;

for x := ATPA[j][0].x + leftDev to ATPA[j][0].x + rightDev do
for y := ATPA[j][0].y - 3 to ATPA[j][0].y + 1 do
begin
if ((x = ATPA[j][0].x + leftDev) and (y = ATPA[j][0].y - 3)) or //ignore 4 corners
((x = ATPA[j][0].x + leftDev) and (y = ATPA[j][0].y + 1)) or
((x = ATPA[j][0].x + rightDev) and (y = ATPA[j][0].y - 3)) or
((x = ATPA[j][0].x + rightDev) and (y = ATPA[j][0].y + 1)) then
Continue;
if InIntArray(OtherColors[i/2], GetColor(x, y)) then
begin
if (L = LTop) then
begin
LTop := LTop*2;
//SetLength(Result, LTop);
end;
FastSetPixel(Bitmap, x, y, 0); //Result[L] := Point(x, y);
Inc(L);
end;
end;
end;
end;
SetLength(FoundColorsTPA, 0);
end;
end;
//SetLength(Result, L);
//Unfreeze;
end;

//Determines whether TPoint has at least Threshold color_BlackPoints in radius 7 around it
function CTWBIsSymbolCenter (ThePoint: TPoint; Threshold: integer): boolean;
var
i, Score: integer;
begin
result := false;
//if point is near the edge of the bitmap, doing a GetColor 7 away will result in out of range
//also, we only care about circle edge points 14 pixels in from the edges, so skip it
if (ThePoint.x < 7) or (ThePoint.x > 121) or (ThePoint.y < 7) or (ThePoint.y > 121) then
exit;
Score := 0;
for i := 0 to 39 do
begin
if GetColor(ThePoint.x + CircleOffsets[i].x, ThePoint.y + CircleOffsets[i].y) = color_Black then
begin
Inc(Score);
if Score > Threshold then
begin
result := true;
exit;
end;
end;
end;
end;


procedure CTWBMakeClean(MyTile: TPoint);
var
CAB: TBox; //CurrentAreaBox
Chunks, Corners, Corners2, BlackPixels, CircleCenters, CopiedChunks: TPointArray;
t,i, i2, i3, counter, lengthx, lengthy, Score, MainBitmap, ChunkBitmap, FragmentBitmap, NewTarget, OldTarget: integer;
CircleSliceOffsets, CircleSliceWidths: array of integer;
TmpPoint: TPoint;
TmpString: String;
Skip: Boolean;
ChunksTiles, FragmentsTiles, FragmentsPixels, FragmentsPos: TBoxArray;
begin
t := getsystemtime;
//Get tile bounds of CurrentAreaBox
CAB := IntToBox(MyTile.x - 12, MyTile.y + 12, MyTile.x + 12, MyTile.y - 12);//Make sure this does not normalize

//CurrentAreaBox is spread over 1, 2, or 4 chunks, so these arrays are set to 4
//In these arrays, [0] corresponds to the chunk that the top left corner of CAB is in,
//[1] is top right, [2] is bottom left, [3] is bottom right. This defined in Corners
Corners := [Point(CAB.x1, CAB.y1), Point(CAB.x2, CAB.y1), Point(CAB.x1, CAB.y2), Point(CAB.x2, CAB.y2)];
SetArrayLength(Chunks, 4);
SetArrayLength(ChunksTiles, 4);
SetArrayLength(FragmentsTiles, 4);
SetArrayLength(FragmentsPixels, 4);
SetArrayLength(FragmentsPos, 4);

//Contains offsets between the center and 40 outline points of circle with raidus 7 (ie a symbol)
CircleOffsets := [Point(0, 7), Point(1, 7), Point(2, 7), Point(3, 6), Point(4, 6), Point(5, 5), Point(6, 4),
Point(6, 3), Point(7, 2), Point(7, 1), Point(7, 0), Point(7, -1), Point(7, -2), Point(6, -3), Point(6, -4),
Point(5, -5), Point(4, -6), Point(3, -6), Point(2, -7), Point(1, -7), Point(0, -7), Point(-1, -7), Point(-2, -7),
Point(-3, -6), Point(-4, -6), Point(-5, -5), Point(-6, -4), Point(-6, -3), Point(-7, -2), Point(-7, -1),
Point(-7, 0), Point(-7, 1), Point(-7, 2), Point(-6, 3), Point(-6, 4), Point(-5, 5), Point(-4, 6), Point(-3, 6),
Point(-2, 7), Point(-1, 7)];

CircleSliceOffsets := [-2, -4, -5, -6, -6, -7, -7, -7];
CircleSliceWidths := [5, 9, 11, 13, 13, 15, 15, 15];

//Using these conventions when working with tiles and pixels
//Pixels have 0,0 in the top left
//Tiles have 0,0 in the bottom left
//Chunks have 0,0 in the bottom left (the are 100x100 pixels, but they deliberately start and end on tiles so that no tile
//is spread over multiple chunks (25x25 tiles), therefore, they follow the tile convention)
//X1,Y1 is always top left, X2,Y2 is always bottom right
//For pixels, Y1 is lower than Y2. For tiles and chunks, Y2 is lower than Y1

for i:= 0 to 3 do
begin
//Find the Chunk that the corresponding corner of CAB is in
Chunks[i] := Point(((Corners[i].x-2044) div 25),((Corners[i].y-861) div 25));
//Find the tile bounds of that chunk
ChunksTiles[i] := IntToBox(2044+Chunks[i].x*25, 885+Chunks[i].y*25, 2068+Chunks[i].x*25, 861+Chunks[i].y*25);//No normalize
//These are the opposite corners of Corners
Corners2 := [Point(ChunksTiles[i].x2, ChunksTiles[i].y2), Point(ChunksTiles[i].x1, ChunksTiles[i].y2), Point(ChunksTiles
[i].x2, ChunksTiles[i].y1), Point(ChunksTiles[i].x1, ChunksTiles[i].y1)]; //yes normalize
//Find the intersection of the corresponding Corner of CAB and the opposite corner of the Chunk
//that contains the Corner of CAB. Also make X1 lower than X2, and Y1 higher than Y2 (tiles start from the bottom left)
FragmentsTiles[i] := IntToBox(Min(Corners[i].x,Corners2[i].x), Max(Corners[i].y,Corners2[i].y), Max(Corners[i].x,Corners2
[i].x), Min(Corners[i].y, Corners2[i].y));
//Find the pixel bounds (on MainBitmap) of thoses tiles
FragmentsPixels[i] := IntToBox(14+(FragmentsTiles[i].x1-(MyTile.x-12))*4, 14+((MyTile.y+12)-FragmentsTiles[i].y1)*4, 112-
((MyTile.x+12)-FragmentsTiles[i].x2)*4, 112-(FragmentsTiles[i].y2-(MyTile.y-12))*4);
//Find the pixel box in Chunk that fragment will be copied to
FragmentsPos[i] := IntToBox((FragmentsTiles[i].x1-ChunksTiles[i].x1)*4, (ChunksTiles[i].y1-FragmentsTiles[i].y1)*4,
(FragmentsTiles[i].x1-ChunksTiles[i].x1)*4 + (FragmentsPixels[i].x2 - FragmentsPixels[i].x1),
(ChunksTiles[i].y1-FragmentsTiles[i].y1)*4 + (FragmentsPixels[i].y2 - FragmentsPixels[i].y1));
end;
writeln('set arrays '+inttostr(getsystemtime-t));
t:=getsystemtime;
MainBitmap := BitmapFromClient(564, 21, 691, 148);
OldTarget := GetImageTarget;
SetTargetBitmap(MainBitmap);
NewTarget := GetImageTarget;

writeln('set target '+inttostr(getsystemtime-t));
t:=getsystemtime;

//0 out the dots
CTWBCollectDots(MainBitmap);

writeln('set dots '+inttostr(getsystemtime-t));
t:=getsystemtime;

//0 out the symbols
FindColors(BlackPixels, color_Black, 0, 0, 113, 113);

for i := 0 to High(BlackPixels) do
begin

//Start-Checking if this pixel is a part of a circle we already know about
Skip := false;
for i2 := 0 to High(CircleCenters) do
begin
lengthx := (BlackPixels[i].x-CircleCenters[i2].x);
lengthy := (BlackPixels[i].y-CircleCenters[i2].y);
counter := lengthx*lengthx + lengthy*lengthy;
if (counter < 54) and (counter >44) then
begin
Skip := true;
break;
end;
end;
//End-Checking if this pixel is a part of a circle we already know about

if not Skip then
begin
//Start- Hope the top 5 pixels of the symbol are uncovered
Score := 0;
if GetColor(BlackPixels[i].x+1, BlackPixels[i].y) = color_Black then
if GetColor(BlackPixels[i].x+2, BlackPixels[i].y) = color_Black then
if GetColor(BlackPixels[i].x+3, BlackPixels[i].y) = color_Black then
if GetColor(BlackPixels[i].x+4, BlackPixels[i].y) = color_Black then //pixel is top left of group horizontal 5
begin
TmpPoint := Point(BlackPixels[i].x+2, BlackPixels[i].y+7); //Center of possible circle;
if CTWBIsSymbolCenter(TmpPoint, 20) then //TmpPoint is probably the center of a symbol
begin
CircleCenters := CombineTPA(CircleCenters, [TmpPoint]);
Skip := true;
break;
end;
end;
//End- Hope the top 5 pixels of the symbol are uncovered
//Start- Bruteforce
if not Skip then
begin
for i2 := 0 to 39 do
begin
TmpPoint := Point(BlackPixels[i].x+CircleOffsets[i2].x, BlackPixels[i].y+CircleOffsets[i2].y);
if CTWBIsSymbolCenter(TmpPoint, 20) then
begin
CircleCenters := CombineTPA(CircleCenters, [TmpPoint]);
Skip := true;
break;
end;
end;
end;
//End- Bruteforce
end;
end;

writeln('find circles '+inttostr(getsystemtime-t));
t:=getsystemtime;
//now 0 out the circles (and contents)
for i := 0 to High(CircleCenters) do
begin
for i2:= 0 to 7 do
for i3 := 0 to CircleSliceWidths[i2] do
begin
if (CircleCenters[i].x > 6) and (CircleCenters[i].x < 122) and (CircleCenters[i].y > 6) and (CircleCenters[i].y < 122) then
begin
FastSetPixel(MainBitmap, 0, CircleCenters[i].x + CircleSliceOffsets[i2] + i3, CircleCenters[i].y-7+i2);
if i2 < 7 then
FastSetPixel(MainBitmap, 0, CircleCenters[i].x + CircleSliceOffsets[i2] + i3, CircleCenters[i].y+7-i2);
end;
end;
end;
//end of setting pixels on MainBitmap


writeln('set circles '+inttostr(getsystemtime-t));
t:=getsystemtime;

SetImageTarget(OldTarget);
FreeTarget(NewTarget);
OldTarget := GetImageTarget;
SetTargetBitmap(MainBitmap);
NewTarget := GetImageTarget;


writeln('set target '+inttostr(getsystemtime-t));
t:=getsystemtime;

SetLength(CopiedChunks,1);
Counter := 0;
CopiedChunks[0] := Point(-1,-1);
for i:= 0 to 3 do
begin
Skip := false;
TmpString := 'CleanChunk'+ Padz(IntToStr(Chunks[i].x),2)+'-'+Padz(IntToStr(Chunks[i].y),2);
//bug in here making it skip when i is 2 and 3
{ for i2 := 0 to High(CopiedChunks) do
begin
if ReadINI('CleanChunksDone', TmpString, CTWBPath + 'CTWBSVN\SVNCleanChunks.INI')='DONE' then
begin
Skip := true;
break;
end;
if ReadINI('CleanChunksDone', TmpString, CTWBPath + 'UserCleanChunks.INI')='DONE' then
begin
Skip := true;
break;
end;
if (Chunks[i].x = CopiedChunks[i2].x) and (Chunks[i].x = CopiedChunks[i2].x) then
begin
Skip := true;
break;
end;
end; }
if not Skip then
begin
SetArrayLength(CopiedChunks, counter+1);
CopiedChunks[Counter] := Chunks[i];
Inc(Counter);
TmpString := CTWBPath + TmpString +'.bmp';
if FileExists(TmpString) then
ChunkBitmap := LoadBitmap(TmpString)
else
ChunkBitmap := CreateBitmap(100,100);
FragmentBitmap := BitmapFromClient(FragmentsPixels[i].x1, FragmentsPixels[i].y1,
FragmentsPixels[i].x2, FragmentsPixels[i].y2);
SetTransparentColor(FragmentBitmap, 0);
FastDrawTransparent(FragmentsPos[i].x1, FragmentsPos[i].y1, FragmentBitmap, ChunkBitmap);
FreeBitmap(FragmentBitmap);
SaveBitmap(ChunkBitmap, TmpString);

FreeBitmap(ChunkBitmap);
end;
end;

writeln('make bmps '+inttostr(getsystemtime-t));
t:=getsystemtime;
SetImageTarget(OldTarget);
FreeTarget(NewTarget);
SaveBitmap(MainBitmap, AppPath+'poop.bmp');
FreeBitmap(MainBitmap);
end;




{*******************************************************************************
function CTWBGetMyPos: TTile;
By: BenLand100
Description: Returns the global tile position of your player.
*******************************************************************************}
function CTWBGetMyPos: TPoint;
var
me: Integer;
begin
me := SmartGetFieldObject(0, hook_static_MyPlayer);
Result.x := SmartGetFieldInt(0, hook_static_BaseX) + SmartGetFieldInt(me, hook_animable_PixelX) / 512;
Result.y := SmartGetFieldInt(0, hook_static_BaseY) + SmartGetFieldInt(me, hook_animable_PixelY) / 512;
SmartFreeObject(me);
if CTWBOn then
CTWBMakeClean(Result);
end;



var mypoint:tpoint;
t:integer;
begin
Smart_Server := 152;
Smart_Members := false;
Smart_signed := true;
Smart_SuperDetail := false;

SetUpSRL;
SetUpReflection;
HowManyPlayers := 1;
CurrentPlayer := 0;
NumberOfPlayers(HowmanyPlayers);
with Players[0] do
begin
Name := '';
Pass := '';
Active := true;
end;
LoginPlayer;


writeln('go');
t:=getsystemtime;
mypoint:= CTWBGetMyPos;
writeln(inttostr(getsystemtime-t));
writeln(mypoint);
end.

Wizzup?

2010-12-25 18:25:02

Did you figure this out?

Boreas

2010-12-25 19:23:10

I think so, unless you or Ray see a more efficient way than this:

program new;
{$Define SMART}
{$i srl\srl.scar}
{$i Reflection\reflection.simba}


const
CTWBOn = true; //Make true to help out CTWB
color_Black = 65536;
CTWBPath = AppPath + 'CTWB\';
//lordsaturn
function CollectDots: TPointArray;
var
SearchColors: T2DIntegerArray;
TPA, TotalTPA: TPointArray;
i, j: Integer;
begin
SetLength(SearchColors, 3);
SearchColors[0] := [3553023, 789758, 2105598, 395004, 237, 206, 65536, 217, 188]; //red
SearchColors[1] := [16711422, 15527148, 13816530, 14869218, 12961221]; //white
SearchColors[2] := [1179390, 195836, 62965, 56797, 60909, 52428]; //yellow
for i := 0 to 2 do
begin
for j := 0 to High(SearchColors[i]) do
if FindColors(TPA, SearchColors[i][j], MMX1, MMY1, MMX2, MMY2) then
TotalTPA := CombineTPA(TotalTPA, TPA);
end;

Result := TotalTPA;
end;

//lordsaturn
function CollectSymbols: TPointArray;
var
SearchTPA, InsideTPA, OutlineTPA: TPointArray;
ATPA, SymbolATPA, PossiblesATPA, SearchATPA: T2DPointArray;
i, j, k, Hi, Hi2, Hi3, lowX, highX, x, y, L, L2, highCount, counter: Integer;
mid, aPt: TPoint;
SearchBox: TBox;
BadColors: TIntegerArray;
begin
//tpa of symbol outline, length = 40, midpoint = 7,7, bounds 14x14
SearchTPA := [Point(5, 0), Point(6, 0), Point(7, 0), Point(8, 0), Point(9, 0),
{5} Point(3, 1), Point(4, 1), Point(10, 1), Point(11, 1),
{9} Point(2, 2), Point(12, 2),
{11} Point(1, 3), Point(13, 3),
{13} Point(1, 4), Point(13, 4),
{15} Point(0, 5), Point(14, 5),
{17} Point(0, 6), Point(14, 6),
{19} Point(0, 7), Point(14, 7),
{21} Point(0, 8), Point(14, 8),
{23} Point(0, 9), Point(14, 9),
{25} Point(1, 10), Point(13, 10),
{27} Point(1, 11), Point(13, 11),
{29} Point(2, 12), Point(12, 12),
{31} Point(3, 13), Point(4, 13), Point(10, 13), Point(11, 13),
{35} Point(5, 14), Point(6, 14), Point(7, 14), Point(8, 14), Point(9, 14)];
BadColors := [789758, 217, 188, 206, 16711422, 14869218, 12961221, 13816530, 195836, 56797, 52428, 52428];
FindColors(InsideTPA, 12632256, MMX1, MMY1, MMX2, MMY2);
ATPA := TPAtoATPAEx(InsideTPA, 15, 15);
InsideTPA := []; //run faster
Hi := High(ATPA);
Hi3 := 39; //High(SearchTPA);
SetLength(SymbolATPA, Hi+1);
for i := 0 to Hi do
begin
//find top left, bottom right
SearchBox := GetTPABounds(ATPA[i]);
//get symbol outline
FindColors(OutlineTPA, 65536, SearchBox.x1-1, SearchBox.y1-1, SearchBox.x2+1, SearchBox.y2+1);

//build midpoint possibilities
Hi2 := High(OutlineTPA);
L2 := 0;
SetLength(PossiblesATPA, Hi2+1);
for j := 0 to Hi2 do
begin
if not (InIntArray(BadColors, GetColor(OutlineTPA[j].x, OutlineTPA[j].y-1))) then
begin
SetLength(PossiblesATPA[L2], Hi3+1);
for k := 0 to Hi3 do
begin
PossiblesATPA[L2][k].x := SearchTPA[k].x + OutlineTPA[j].x - 7;
PossiblesATPA[L2][k].y := SearchTPA[k].y + OutlineTPA[j].y - 7;
end;
Inc(L2);
end;
end;
OutlineTPA := []; //run faster
SetLength(PossiblesATPA, L2);

//find common midpoint
Hi2 := L2-1; //because it changed
highCount := 0;
for k := 0 to Hi3 do
begin
aPt := PossiblesATPA[0][k];
counter := 0;
for j := 1 to Hi2 do
if PointInTPA(aPt, PossiblesATPA[j]) then
Inc(counter);
if counter > highCount then
begin
mid := aPt;
highCount := counter;
end;
end;
PossiblesATPA := []; //run faster

//filler up
SetLength(SymbolATPA[i], 177);
if L = 0 then
SearchATPA := TPAtoATPAEx(SearchTPA, 15, 0); //go faster
L := 0;
Hi2 := 14; //High(SearchATPA);
for j := 0 to Hi2 do
begin
lowX := mid.x + SearchATPA[j][0].x - 7;
highX := mid.x + SearchATPA[j][High(SearchATPA[j])].x - 7;
y := mid.y + SearchATPA[j][0].y - 7;
for x := lowX to highX do
begin
SymbolATPA[i][L] := Point(x, y);
Inc(L);
end;
end;

end;
Result := MergeATPA(SymbolATPA);
end;

//lordsaturn
function StuffOnMM: TPointArray;
var
timer: Integer;
begin
timer := GetSystemTime;
Result := CombineTPA(CollectDots, CollectSymbols);
//Writeln('StuffOnMM took '+tostr(GetSystemTime-timer)+' msec.');
end;

procedure CTWBMakeClean(MyTile: TPoint);
var
CAB: TBox; //CurrentAreaBox
Chunks, Corners, Corners2, CopiedChunks, DotsTPA: TPointArray;
t,i, i2, counter, MainBitmap, ChunkBitmap, FragmentBitmap, NewTarget, OldTarget: integer;
TmpPoint: TPoint;
TmpString: String;
Skip: Boolean;
ChunksTiles, FragmentsTiles, FragmentsPixels, FragmentsPos: TBoxArray;
var
SearchColors: T2DIntegerArray;
TPA, TotalTPA: TPointArray;
il, jl: Integer;
begin
t := getsystemtime;
//Get tile bounds of CurrentAreaBox
CAB := IntToBox(MyTile.x - 12, MyTile.y + 12, MyTile.x + 12, MyTile.y - 12);//Make sure this does not normalize

//CurrentAreaBox is spread over 1, 2, or 4 chunks, so these arrays are set to 4
//In these arrays, [0] corresponds to the chunk that the top left corner of CAB is in,
//[1] is top right, [2] is bottom left, [3] is bottom right. This defined in Corners
Corners := [Point(CAB.x1, CAB.y1), Point(CAB.x2, CAB.y1), Point(CAB.x1, CAB.y2), Point(CAB.x2, CAB.y2)];
SetArrayLength(Chunks, 4);
SetArrayLength(ChunksTiles, 4);
SetArrayLength(FragmentsTiles, 4);
SetArrayLength(FragmentsPixels, 4);
SetArrayLength(FragmentsPos, 4);

//Using these conventions when working with tiles and pixels
//Pixels have 0,0 in the top left
//Tiles have 0,0 in the bottom left
//Chunks have 0,0 in the bottom left (the are 100x100 pixels, but they deliberately start and end on tiles so that no tile
//is spread over multiple chunks (25x25 tiles), therefore, they follow the tile convention)
//X1,Y1 is always top left, X2,Y2 is always bottom right
//For pixels, Y1 is lower than Y2. For tiles and chunks, Y2 is lower than Y1

for i:= 0 to 3 do
begin
//Find the Chunk that the corresponding corner of CAB is in
Chunks[i] := Point(((Corners[i].x-2044) div 25),((Corners[i].y-861) div 25));
//Find the tile bounds of that chunk
ChunksTiles[i] := IntToBox(2044+Chunks[i].x*25, 885+Chunks[i].y*25, 2068+Chunks[i].x*25, 861+Chunks[i].y*25);//No normalize
//These are the opposite corners of Corners
Corners2 := [Point(ChunksTiles[i].x2, ChunksTiles[i].y2), Point(ChunksTiles[i].x1, ChunksTiles[i].y2), Point(ChunksTiles
[i].x2, ChunksTiles[i].y1), Point(ChunksTiles[i].x1, ChunksTiles[i].y1)]; //yes normalize
//Find the intersection of the corresponding Corner of CAB and the opposite corner of the Chunk
//that contains the Corner of CAB. Also make X1 lower than X2, and Y1 higher than Y2 (tiles start from the bottom left)
FragmentsTiles[i] := IntToBox(Min(Corners[i].x,Corners2[i].x), Max(Corners[i].y,Corners2[i].y), Max(Corners[i].x,Corners2
[i].x), Min(Corners[i].y, Corners2[i].y));
//Find the pixel bounds (on MainBitmap) of thoses tiles
FragmentsPixels[i] := IntToBox(14+(FragmentsTiles[i].x1-(MyTile.x-12))*4, 14+((MyTile.y+12)-FragmentsTiles[i].y1)*4, 112-
((MyTile.x+12)-FragmentsTiles[i].x2)*4, 112-(FragmentsTiles[i].y2-(MyTile.y-12))*4);
//Find the pixel box in Chunk that fragment will be copied to
FragmentsPos[i] := IntToBox((FragmentsTiles[i].x1-ChunksTiles[i].x1)*4, (ChunksTiles[i].y1-FragmentsTiles[i].y1)*4,
(FragmentsTiles[i].x1-ChunksTiles[i].x1)*4 + (FragmentsPixels[i].x2 - FragmentsPixels[i].x1),
(ChunksTiles[i].y1-FragmentsTiles[i].y1)*4 + (FragmentsPixels[i].y2 - FragmentsPixels[i].y1));
end;

DotsTPA :=StuffOnMM;

MainBitmap := BitmapFromClient(564, 21, 691, 148);
OldTarget := GetImageTarget;
SetTargetBitmap(MainBitmap);
NewTarget := GetImageTarget;

for i := 0 to High(DotsTPA) do
begin
il:=DotsTPA[i].x-564;
jl:=DotsTPA[i].y-21;
if (il > -1) and (il < 128) and (jl > -1) and (jl < 128) then
FastSetPixel(MainBitmap, il, jl, 0);
end;

for il:= mmcx-1 to mmcx+1 do
for jl:= mmcy-1 to mmcy +1 do
FastSetPixel(MainBitmap, il-564, jl-21, 0);

SetLength(CopiedChunks,1);
Counter := 0;
CopiedChunks[0] := Point(-1,-1);
for i:= 0 to 3 do
begin
Skip := false;
TmpString := 'CleanChunk'+ Padz(IntToStr(Chunks[i].x),2)+'-'+Padz(IntToStr(Chunks[i].y),2);
for i2 := 0 to High(CopiedChunks) do
begin
if ReadINI('CleanChunksDone', TmpString, CTWBPath + 'CTWBSVN\SVNCleanChunks.INI')='DONE' then
begin
Skip := true;
break;
end;
if ReadINI('CleanChunksDone', TmpString, CTWBPath + 'UserCleanChunks.INI')='DONE' then
begin
Skip := true;
break;
end;
if (Chunks[i].x = CopiedChunks[i2].x) and (Chunks[i].y = CopiedChunks[i2].y) then
begin
Skip := true;
break;
end;
end;
if not Skip then
begin
SetArrayLength(CopiedChunks, counter+1);
CopiedChunks[Counter] := Chunks[i];
Inc(Counter);
TmpString := CTWBPath + TmpString +'.bmp';
if FileExists(TmpString) then
ChunkBitmap := LoadBitmap(TmpString)
else
ChunkBitmap := CreateBitmap(100,100);
FragmentBitmap := BitmapFromClient(FragmentsPixels[i].x1, FragmentsPixels[i].y1,
FragmentsPixels[i].x2, FragmentsPixels[i].y2);
SetTransparentColor(FragmentBitmap, 0);
FastDrawTransparent(FragmentsPos[i].x1, FragmentsPos[i].y1, FragmentBitmap, ChunkBitmap);
FreeBitmap(FragmentBitmap);
SaveBitmap(ChunkBitmap, TmpString);

FreeBitmap(ChunkBitmap);
end;
end;

SetImageTarget(OldTarget);
FreeTarget(NewTarget);
FreeBitmap(MainBitmap);
end;




{*******************************************************************************
function CTWBGetMyPos: TTile;
By: BenLand100
Description: Returns the global tile position of your player.
*******************************************************************************}
function CTWBGetMyPos: TPoint;
var
me: Integer;
begin
me := SmartGetFieldObject(0, hook_static_MyPlayer);
Result.x := SmartGetFieldInt(0, hook_static_BaseX) + SmartGetFieldInt(me, hook_animable_PixelX) / 512;
Result.y := SmartGetFieldInt(0, hook_static_BaseY) + SmartGetFieldInt(me, hook_animable_PixelY) / 512;
SmartFreeObject(me);
if CTWBOn then
if R_MakeCompass('n') then
if not R_FlagExists then
CTWBMakeClean(Result);
end;



var mypoint: tpoint;

begin
Smart_Server := 152;
Smart_Members := false;
Smart_signed := true;
Smart_SuperDetail := false;

SetUpSRL;
SetUpReflection;
HowManyPlayers := 1;
CurrentPlayer := 0;
NumberOfPlayers(HowmanyPlayers);
with Players[0] do
begin
Name := '';
Pass := '';
Active := true;
end;
LoginPlayer;

mypoint:= CTWBGetMyPos;

end.