CamHart
11-13-2006, 03:35 AM
I couldn't figure out how to work the road color thing in SRL (unless i did figure it out and it doesn't work like i liked), so I made this thing. You might need to edit the numbers 4000000 and 8000000 which is what i've found all road colors being with the exception of barbarian village. Even if it finds a bad color it doesn't jack up. Still in a beta form, never been tested limitless.
Edit: If you're looking for enhancement use tarajunky's posted below. Dominates mine...
program New;
{.Include SRL\SRL.Scar}
{.Include SRL\SRL\Extended\xColor.Scar}
var
RememberRoadColors: Boolean;
ABadColor: Array of Integer;
Function InArray(One:Integer; Arrays:Array of Integer):Boolean;
var c:integer;
Begin
For c:=0 to (GetArrayLength(Arrays) - 1) Do
If(One = Arrays[c])Then
Result:= true;
End;
//Start of Read/Write Arrays to Files
Function ArrayToString(Arrays: Array of Integer):String;
var
c, arraylength:integer;
thestring:string;
Begin
Arraylength:= GetArrayLength(Arrays) - 1;
for c:=0 to Arraylength do
thestring:= (thestring + IntToStr(Arrays[c])+',');
Result:= thestring;
End;
Function StringToArray(Source, Split:String):Array of Integer;
Var
Arrays: Array of Integer;
ArrayLength, c, v:integer;
Char: String;
Begin
Source:= Trim(Source);
Split:= Trim(Split);
ArrayLength := 1;
SetArrayLength(Arrays, ArrayLength);
//Writeln('Source: '+Source);
//Writeln('Length: '+ IntToStr(Length(Source)));
For c := 0 to (Length(Source) - 1) do
Begin
//Writeln('C: '+ IntToStr(c));
Char:= Trim(StrGet(Source, c + 1));
//Writeln('Char: '+Char);
//if((Char = Split) or (Char = (' ' + Split))) or (Char = (Split + ' ')))Then
if(Char = Split)Then
Begin
Arrays[ArrayLength - 1]:= V;
V:= 0;
ArrayLength:= ArrayLength + 1;
SetArrayLength(Arrays, ArrayLength + 1);
End else
Begin
V:= StrToInt(Trim(IntToStr(V) + Char));
End;
End;
SetArrayLength(Arrays, ArrayLength - 1);// There's an Extra Slot added so this removes it
Result:= Arrays;
End;
Function ReadArrayFromFile(Path, Split:String):Array of Integer;
Var
Filenum: Integer;
Thestuff: String;
Arrays: Array of Integer;
Begin
Filenum := Openfile(Path, True);//not sure about true/false thing
If(Filenum >= 0)Then
Begin
If(ReadFileString(Filenum, Thestuff, FileSize(Filenum)))Then
Begin
Arrays:= StringToArray(Thestuff, Split);
Writeln('Array Read: '+ArrayToString(Arrays));
Result:= Arrays;
End else
Begin
Writeln('Cannot read array');
Result:= Arrays;
End;
CloseFile(Filenum);
End;
End;
Function WriteArrayToFile(Path: String; Arrays: Array of Integer):Boolean;
Var
Filenum: Integer;
Begin
Filenum:=RewriteFile(Path, True);//not sure about true/false thing
if(Filenum >= 0)Then
Begin
Result:= WriteFileString(Filenum, ArrayToString(ABadColor));
Writeln('Array Wrote: ' + ArrayToString(ABadColor));
CloseFile(filenum);
End;
End;
//End of Read/Write Arrays to File
//Read/Write Array Color Sets
Function ReadBadColors:Array of Integer;
Begin
Result:= ReadArrayFromFile(AppPath+'BadOldRoadColors.txt', ',');
End;
Function WriteBadColors(Addition: Integer):Boolean;//Addition is a number you want to add to the array
Var
OldStuff: Array of Integer;
ALength: integer;
Begin
OldStuff:= ReadBadColors;
ALength:= GetArrayLength(OldStuff);
SetArrayLength(OldStuff, ALength + 1);
OldStuff[ALength]:= Addition;//edit? //GetArrayLenght counts doesn't count 0
Result:= WriteArrayToFile(AppPath+'BadOldRoadColors.txt', OldStuff);
End;
Function ReadGoodColors:Array of Integer;
Begin
Result:= ReadArrayFromFile(AppPath+'GoodOldRoadColors.txt', ',');
End;
Function WriteGoodColors(Addition: Integer):Boolean;//Addition is a number you want to add to the array
Var
OldStuff: Array of Integer;
ALength: Integer;
Begin
OldStuff:= ReadGoodColors;
ALength:= GetArrayLength(OldStuff);
SetArrayLength(OldStuff, ALength + 1);
OldStuff[ALength]:= Addition; //edit
Result:= WriteArrayToFile(AppPath+'GoodOldRoadColors.txt', OldStuff);
End;
Function CheckGoodOldRoadColors:integer;
var
Filenum, c:Integer;
OldColors:Array of Integer;
Begin
Filenum:= OpenFile(AppPath+'GoodOldRoadColors.txt', true);
If(Filenum >= 0)Then
Begin
OldColors:= ReadArrayFromFile(AppPath+'GoodOldRoadColors.txt', ',');
For c:=0 to (GetArrayLength(OldColors) - 1) Do
Begin
If(CountColor(OldColors[c], MMX1, MMY1, MMX2, MMY2) > 0)Then
Begin
Writeln('Old Color Found: '+IntToStr(OldColors[c]));
Result:=OldColors[c];
End;
End;
CloseFile(Filenum);
End;
End;
//End of read/write array color sets
//Start of FindRoadColor Functions
Function CreateCircleBitmap(X1, Y1, X2, Y2: Integer; DebugWindow:Boolean):Integer;//Leeched from masquerader
var
Debug,Temp: TCanvas;
H, W, ScreenBmp, TempBmp: Integer;
begin
W := Max(X1, X2) - Min(X1, X2);
H := Max(Y1, Y2) - Min(Y1, Y2);
TempBmp := BitmapFromString(W, H, '');
Temp := GetBitmapCanvas(TempBmp);
ScreenBmp := BitmapFromString(W, H, '');
FastDrawClear(TempBmp, -1);
CopyClientToBitmap(ScreenBmp, X1, Y1, X2, Y2);
CopyCanvas(GetBitmapCanvas(TempBmp), Temp, 0, 0, W, H, 0, 0, W, H);
Temp.Ellipse(0, 0, W, H);
CopyCanvas(Temp, GetBitmapCanvas(TempBmp), 0, 0, W, H, 0, 0, W, H);
SetTransparentColor(TempBmp, 16777215);
FastDrawTransparent(0, 0, TempBmp, ScreenBmp);
If(DebugWindow)Then
displaydebugimgwindow(w,h);
debug:=getdebugcanvas;
copycanvas(getbitmapcanvas(screenbmp),debug,0,0,w, h,0,0,w,h);
SaveBitmap(ScreenBmp, AppPath+'CircleBitmap.bmp');
Result:= LoadBitmap(AppPath+'CircleBitmap.bmp');
FreeBitmap(TempBmp);
FreeBitmap(ScreenBmp);
end;
Function RoadMaskBitMap:integer;
var
a, q, z, ClientHandle, stuff:integer;
Begin
ClientHandle:= GetClientWindowHandle;
FindWindow('Debug Image');
a := BitmapFromString(4, 3, 'z78DA7373A30E0000CEFE13B1');
If(FindBitMapMaskTolerance(a, q, z, 20, 29, 124, 106, 1, 1))Then
//If(FindBitmapInCircleTol(a, q, z, 73, 67, 67, 0))Then //Doesnt work?
Begin
stuff:= GetColor(q, z);
If(stuff >= 0)Then
Writeln('Coord: ('+IntToStr(q)+', '+IntToStr(z)+') - '+IntToStr(stuff));
Result:=stuff;
End;
FreeBitMap(a);
SetClientWindowHandle(ClientHandle);
End;
Function FindTheRoadColor(CheckOldColors: Boolean):Integer;
Var TheColor, c, OldColor,
a, CameraMoves,
MiniMap, MaxRoadColor, MinRoadColor:integer;
DebugCanvas: TCanvas;
TheKey: Boolean;
begin
If(CheckOldColors)Then
Begin
OldColor:= CheckGoodOldRoadColors;
If((OldColor > 0) and (Not(InArray(OldColor, ABadColor))))Then
Result:= OldColor
End;
MaxRoadColor:= 8000000;//Change the road color limitations here
MinRoadColor:= 4000000;// Default are 4000000 and 8000000
DebugCanvas:= GetDebugCanvas;
CameraMoves:= 0;
a := BitmapFromString(4, 3, 'z78DA7373A30E0000CEFE13B1');
MiniMap:= BitmapFromString(165, 161, '');
TheColor:=0;
If(Random(10) > Random(5))Then
Begin
TheKey:= true;
End
Else
Begin
TheKey:= false;
End;
MiniMap:= CreateCircleBitmap(575, 9, 720, 143, true);
Repeat
Writeln('Searching for road...');
c:= 0;
If((TheColor < MinRoadColor) or (TheColor > MaxRoadColor))Then
Begin
CameraMoves:= CameraMoves + 1;
ActivateClient;
If(TheKey)Then
Begin
KeyDown(VK_Right);
End
Else
Begin
KeyDown(VK_Left);
End;
Wait(400 + Random(1000));
If(TheKey)Then
Begin
KeyUp(VK_Right);
End
Else
Begin
KeyUp(VK_Left);
End;
End;
Repeat
TheColor:= RoadMaskBitMap;
MiniMap:= RotateBitmap(MiniMap, (5*(Pi/180)));
SafeCopyCanvas(GetBitmapCanvas(MiniMap), DebugCanvas, 0, 0, 165, 161, 0, 0, 165, 161);//165,161
c:= c + 1;
Until((c > 72) or ((TheColor > MinRoadColor) and (TheColor < MaxRoadColor) and (Not (InArray(TheColor, ABadColor))) ) );
Until(((TheColor > MinRoadColor) and (TheColor < MaxRoadColor) and (Not (InArray(TheColor, ABadColor)))) or (CameraMoves > 500));
FreeBitMap(a);
FreeBitMap(MiniMap);
If(RememberRoadColors)Then
WriteGoodColors(TheColor);
Result:= TheColor;
end;
//End of RoadColors
begin
SetupSRL;
RememberRoadColors:= true;//True to have it save road colors to files
FindTheRoadColor(true);
end.
[I]Copied this from a script, and made sure
One bug I've found....
[Runtime Error] : Exception: Access violation at address 7C918FEA in module 'ntdll.dll'. Write of address 00000098 in line 263 in script
Not sure how to fix this. Happens rarely, might only happen when i haven't set the client. Any help is appreciated.
Also has bugs with the writing/reading of arrays in it, but that can be edited out (I'll fix it once i find time).
Also, it doesn't have a time limit to when its searching really... Well it does but if you want to edit that feel free.
Edit: If you're looking for enhancement use tarajunky's posted below. Dominates mine...
program New;
{.Include SRL\SRL.Scar}
{.Include SRL\SRL\Extended\xColor.Scar}
var
RememberRoadColors: Boolean;
ABadColor: Array of Integer;
Function InArray(One:Integer; Arrays:Array of Integer):Boolean;
var c:integer;
Begin
For c:=0 to (GetArrayLength(Arrays) - 1) Do
If(One = Arrays[c])Then
Result:= true;
End;
//Start of Read/Write Arrays to Files
Function ArrayToString(Arrays: Array of Integer):String;
var
c, arraylength:integer;
thestring:string;
Begin
Arraylength:= GetArrayLength(Arrays) - 1;
for c:=0 to Arraylength do
thestring:= (thestring + IntToStr(Arrays[c])+',');
Result:= thestring;
End;
Function StringToArray(Source, Split:String):Array of Integer;
Var
Arrays: Array of Integer;
ArrayLength, c, v:integer;
Char: String;
Begin
Source:= Trim(Source);
Split:= Trim(Split);
ArrayLength := 1;
SetArrayLength(Arrays, ArrayLength);
//Writeln('Source: '+Source);
//Writeln('Length: '+ IntToStr(Length(Source)));
For c := 0 to (Length(Source) - 1) do
Begin
//Writeln('C: '+ IntToStr(c));
Char:= Trim(StrGet(Source, c + 1));
//Writeln('Char: '+Char);
//if((Char = Split) or (Char = (' ' + Split))) or (Char = (Split + ' ')))Then
if(Char = Split)Then
Begin
Arrays[ArrayLength - 1]:= V;
V:= 0;
ArrayLength:= ArrayLength + 1;
SetArrayLength(Arrays, ArrayLength + 1);
End else
Begin
V:= StrToInt(Trim(IntToStr(V) + Char));
End;
End;
SetArrayLength(Arrays, ArrayLength - 1);// There's an Extra Slot added so this removes it
Result:= Arrays;
End;
Function ReadArrayFromFile(Path, Split:String):Array of Integer;
Var
Filenum: Integer;
Thestuff: String;
Arrays: Array of Integer;
Begin
Filenum := Openfile(Path, True);//not sure about true/false thing
If(Filenum >= 0)Then
Begin
If(ReadFileString(Filenum, Thestuff, FileSize(Filenum)))Then
Begin
Arrays:= StringToArray(Thestuff, Split);
Writeln('Array Read: '+ArrayToString(Arrays));
Result:= Arrays;
End else
Begin
Writeln('Cannot read array');
Result:= Arrays;
End;
CloseFile(Filenum);
End;
End;
Function WriteArrayToFile(Path: String; Arrays: Array of Integer):Boolean;
Var
Filenum: Integer;
Begin
Filenum:=RewriteFile(Path, True);//not sure about true/false thing
if(Filenum >= 0)Then
Begin
Result:= WriteFileString(Filenum, ArrayToString(ABadColor));
Writeln('Array Wrote: ' + ArrayToString(ABadColor));
CloseFile(filenum);
End;
End;
//End of Read/Write Arrays to File
//Read/Write Array Color Sets
Function ReadBadColors:Array of Integer;
Begin
Result:= ReadArrayFromFile(AppPath+'BadOldRoadColors.txt', ',');
End;
Function WriteBadColors(Addition: Integer):Boolean;//Addition is a number you want to add to the array
Var
OldStuff: Array of Integer;
ALength: integer;
Begin
OldStuff:= ReadBadColors;
ALength:= GetArrayLength(OldStuff);
SetArrayLength(OldStuff, ALength + 1);
OldStuff[ALength]:= Addition;//edit? //GetArrayLenght counts doesn't count 0
Result:= WriteArrayToFile(AppPath+'BadOldRoadColors.txt', OldStuff);
End;
Function ReadGoodColors:Array of Integer;
Begin
Result:= ReadArrayFromFile(AppPath+'GoodOldRoadColors.txt', ',');
End;
Function WriteGoodColors(Addition: Integer):Boolean;//Addition is a number you want to add to the array
Var
OldStuff: Array of Integer;
ALength: Integer;
Begin
OldStuff:= ReadGoodColors;
ALength:= GetArrayLength(OldStuff);
SetArrayLength(OldStuff, ALength + 1);
OldStuff[ALength]:= Addition; //edit
Result:= WriteArrayToFile(AppPath+'GoodOldRoadColors.txt', OldStuff);
End;
Function CheckGoodOldRoadColors:integer;
var
Filenum, c:Integer;
OldColors:Array of Integer;
Begin
Filenum:= OpenFile(AppPath+'GoodOldRoadColors.txt', true);
If(Filenum >= 0)Then
Begin
OldColors:= ReadArrayFromFile(AppPath+'GoodOldRoadColors.txt', ',');
For c:=0 to (GetArrayLength(OldColors) - 1) Do
Begin
If(CountColor(OldColors[c], MMX1, MMY1, MMX2, MMY2) > 0)Then
Begin
Writeln('Old Color Found: '+IntToStr(OldColors[c]));
Result:=OldColors[c];
End;
End;
CloseFile(Filenum);
End;
End;
//End of read/write array color sets
//Start of FindRoadColor Functions
Function CreateCircleBitmap(X1, Y1, X2, Y2: Integer; DebugWindow:Boolean):Integer;//Leeched from masquerader
var
Debug,Temp: TCanvas;
H, W, ScreenBmp, TempBmp: Integer;
begin
W := Max(X1, X2) - Min(X1, X2);
H := Max(Y1, Y2) - Min(Y1, Y2);
TempBmp := BitmapFromString(W, H, '');
Temp := GetBitmapCanvas(TempBmp);
ScreenBmp := BitmapFromString(W, H, '');
FastDrawClear(TempBmp, -1);
CopyClientToBitmap(ScreenBmp, X1, Y1, X2, Y2);
CopyCanvas(GetBitmapCanvas(TempBmp), Temp, 0, 0, W, H, 0, 0, W, H);
Temp.Ellipse(0, 0, W, H);
CopyCanvas(Temp, GetBitmapCanvas(TempBmp), 0, 0, W, H, 0, 0, W, H);
SetTransparentColor(TempBmp, 16777215);
FastDrawTransparent(0, 0, TempBmp, ScreenBmp);
If(DebugWindow)Then
displaydebugimgwindow(w,h);
debug:=getdebugcanvas;
copycanvas(getbitmapcanvas(screenbmp),debug,0,0,w, h,0,0,w,h);
SaveBitmap(ScreenBmp, AppPath+'CircleBitmap.bmp');
Result:= LoadBitmap(AppPath+'CircleBitmap.bmp');
FreeBitmap(TempBmp);
FreeBitmap(ScreenBmp);
end;
Function RoadMaskBitMap:integer;
var
a, q, z, ClientHandle, stuff:integer;
Begin
ClientHandle:= GetClientWindowHandle;
FindWindow('Debug Image');
a := BitmapFromString(4, 3, 'z78DA7373A30E0000CEFE13B1');
If(FindBitMapMaskTolerance(a, q, z, 20, 29, 124, 106, 1, 1))Then
//If(FindBitmapInCircleTol(a, q, z, 73, 67, 67, 0))Then //Doesnt work?
Begin
stuff:= GetColor(q, z);
If(stuff >= 0)Then
Writeln('Coord: ('+IntToStr(q)+', '+IntToStr(z)+') - '+IntToStr(stuff));
Result:=stuff;
End;
FreeBitMap(a);
SetClientWindowHandle(ClientHandle);
End;
Function FindTheRoadColor(CheckOldColors: Boolean):Integer;
Var TheColor, c, OldColor,
a, CameraMoves,
MiniMap, MaxRoadColor, MinRoadColor:integer;
DebugCanvas: TCanvas;
TheKey: Boolean;
begin
If(CheckOldColors)Then
Begin
OldColor:= CheckGoodOldRoadColors;
If((OldColor > 0) and (Not(InArray(OldColor, ABadColor))))Then
Result:= OldColor
End;
MaxRoadColor:= 8000000;//Change the road color limitations here
MinRoadColor:= 4000000;// Default are 4000000 and 8000000
DebugCanvas:= GetDebugCanvas;
CameraMoves:= 0;
a := BitmapFromString(4, 3, 'z78DA7373A30E0000CEFE13B1');
MiniMap:= BitmapFromString(165, 161, '');
TheColor:=0;
If(Random(10) > Random(5))Then
Begin
TheKey:= true;
End
Else
Begin
TheKey:= false;
End;
MiniMap:= CreateCircleBitmap(575, 9, 720, 143, true);
Repeat
Writeln('Searching for road...');
c:= 0;
If((TheColor < MinRoadColor) or (TheColor > MaxRoadColor))Then
Begin
CameraMoves:= CameraMoves + 1;
ActivateClient;
If(TheKey)Then
Begin
KeyDown(VK_Right);
End
Else
Begin
KeyDown(VK_Left);
End;
Wait(400 + Random(1000));
If(TheKey)Then
Begin
KeyUp(VK_Right);
End
Else
Begin
KeyUp(VK_Left);
End;
End;
Repeat
TheColor:= RoadMaskBitMap;
MiniMap:= RotateBitmap(MiniMap, (5*(Pi/180)));
SafeCopyCanvas(GetBitmapCanvas(MiniMap), DebugCanvas, 0, 0, 165, 161, 0, 0, 165, 161);//165,161
c:= c + 1;
Until((c > 72) or ((TheColor > MinRoadColor) and (TheColor < MaxRoadColor) and (Not (InArray(TheColor, ABadColor))) ) );
Until(((TheColor > MinRoadColor) and (TheColor < MaxRoadColor) and (Not (InArray(TheColor, ABadColor)))) or (CameraMoves > 500));
FreeBitMap(a);
FreeBitMap(MiniMap);
If(RememberRoadColors)Then
WriteGoodColors(TheColor);
Result:= TheColor;
end;
//End of RoadColors
begin
SetupSRL;
RememberRoadColors:= true;//True to have it save road colors to files
FindTheRoadColor(true);
end.
[I]Copied this from a script, and made sure
One bug I've found....
[Runtime Error] : Exception: Access violation at address 7C918FEA in module 'ntdll.dll'. Write of address 00000098 in line 263 in script
Not sure how to fix this. Happens rarely, might only happen when i haven't set the client. Any help is appreciated.
Also has bugs with the writing/reading of arrays in it, but that can be edited out (I'll fix it once i find time).
Also, it doesn't have a time limit to when its searching really... Well it does but if you want to edit that feel free.