marpis
2009-04-14 12:43:58
i got this idea from reflection. My function FindObjects() finds all objects in the mainscreen, and saves them in an array of TObject2. As we all know, names cannot be found with colors so TObject2 has no 'name' property.
What makes it better than FindObj()?
For finding a single object, a door for example, FindObj() is accurate enough. But when you have 5 monsters on your screen, and you need to find the best one to attack (which is the nearest unattacked monster) it is much easier to inspect the monsters as an array. I use this technique in my new universal Multifighter (not ready yet) and it seems to work fine.
Remember: No color-based function is 100% accurate. It sometimes doesnt notice if a monster is in fight, but hasnt been a problem for me.
MAJOR UPDATE TO FindObjects() !!
MAJOR UPDATE TO FindObjects() again !!
- Now you can define the size of the object (width, height)
- You can define the accuracy required (see the description)
* now the accuracy actually works ^^
* removed double check colors, no need for that. now its much faster and still reliable
* colorspeedmodifiers, its now even more accurate
Here are all the functions i made to make this system work:
Example of fnding a giant rat:
Thanks for comments!
:)
What makes it better than FindObj()?
For finding a single object, a door for example, FindObj() is accurate enough. But when you have 5 monsters on your screen, and you need to find the best one to attack (which is the nearest unattacked monster) it is much easier to inspect the monsters as an array. I use this technique in my new universal Multifighter (not ready yet) and it seems to work fine.
Remember: No color-based function is 100% accurate. It sometimes doesnt notice if a monster is in fight, but hasnt been a problem for me.
MAJOR UPDATE TO FindObjects() !!
MAJOR UPDATE TO FindObjects() again !!
- Now you can define the size of the object (width, height)
- You can define the accuracy required (see the description)
* now the accuracy actually works ^^
* removed double check colors, no need for that. now its much faster and still reliable
* colorspeedmodifiers, its now even more accurate
Here are all the functions i made to make this system work:
//type TObject2 by marpis
type TObject2 = record
x: integer;
y: integer;
InFight: boolean;
end;
{*******************************************************************************
function IsInFight(x, y: integer): Boolean;
By: marpis
Description: Checks if there is a fight at (x, y)
*******************************************************************************}
function IsInFight(x, y: integer): Boolean;
var
G, R: TPointArray;
begin
if not loggedin then exit;
FindColorsTolerance(G, 65280, x-35, y-35, x+35, y+35, 0);
FindColorsTolerance(R, 255, x-35, y-35, x+35, y+35, 0);
Result := High(CombineTPA(G, R)) > 10;
end;
{*******************************************************************************
procedure DeleteATPAIndex(i: Integer; var arr: T2DPointArray);
By: Nava2 & marpis
Description: Deletes an ATPA index in array
*******************************************************************************}
//DeleteIndex by Nava2. Thanks! (again)
procedure DeleteATPAIndex(i: Integer; var arr: T2DPointArray);
begin
swap(arr[i], arr[High(arr)]);
SetLength(arr, High(arr));
end;
{*******************************************************************************
procedure DeleteObj2ArrayIndex(i: Integer; var arr: Array of TObject2);
By: Nava2 & marpis
Description: Deletes an Object index in array of TObject2
*******************************************************************************}
procedure DeleteObj2ArrayIndex(i: Integer; var arr: Array of TObject2);
begin
swap(arr[i], arr[High(arr)]);
SetLength(arr, High(arr));
end;
{=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=}
{ function FindObjects
var Objs: Array of TObject2 Here the found objects are stored
width, height: Size of the object
colors: TIntegerArray, object colors
tolerance: Color tolerance
accuracy: Minimum amount of pixels per object
ExcludeSelf: Ignore objects at the same spot than you are
{=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=}
function FindObjects(var Objs: Array of TObject2; width, height: integer; colors: TIntegerArray; accuracy, tolerance: integer; ExcludeSelf: boolean): boolean;
var
TPA, TempTPA: TPointArray;
ATPA: T2DPointArray;
i, hi, CTS: integer;
P: TPoint;
Box: TBox;
begin
if not loggedin then exit;
CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.1, 0.4);
for i:= 0 to high(colors) do
begin
FindColorsSpiralTolerance(MSCX, MSCY, TempTPA, colors[i], MSX1, MSY1, MSX2, MSY2, tolerance);
TPA:= CombineTPA(TPA, TempTPA);
end;
SetColorspeed2Modifiers(0.2, 0.2);
ColorToleranceSpeed(CTS);
if (Length(TPA) < accuracy) then exit;
ATPA:= SplitTPAEx(TPA, width, height);
SetArrayLength(Objs, Length(ATPA));
Result:= Length(ATPA) > 0;
SortATPASize(ATPA, true);
//DebugATPA(ATPA, '');
for i:= 0 to High(ATPA) do
begin
P:= MiddleTPA(ATPA[i]);
Box:= IntToBox(245, 145, 275, 180);
if (PointInBox(P, Box) and ExcludeSelf) or (Length(ATPA[i]) < accuracy) then
DeleteATPAIndex(i, ATPA)
else
begin
Objs[i].x := P.x;
Objs[i].y := P.y;
Objs[i].InFight := IsInFight(P.x, P.y);
end;
end;
end;
{*******************************************************************************
procedure QuickSort(var A: array of Integer; iLo, iHi: Integer);
By: some dude in IRC: #delphi @ Quakenet
Description: Sorts integerarray from min to max
*******************************************************************************}
procedure QuickSort(var A: array of Integer; iLo, iHi: Integer);
var
Lo, Hi, Pivot, T: Integer;
begin
Lo := iLo;
Hi := iHi;
Pivot := A[(Lo + Hi) div 2];
repeat
while A[Lo] < Pivot do Inc(Lo);
while A[Hi] > Pivot do Dec(Hi);
if Lo <= Hi then
begin
T := A[Lo];
A[Lo] := A[Hi];
A[Hi] := T;
Inc(Lo);
Dec(Hi);
end;
until Lo > Hi;
if Hi > iLo then QuickSort(A, iLo, Hi);
if Lo < iHi then QuickSort(A, Lo, iHi);
end;
{*******************************************************************************
function ArrangeObjects(Objs: Array of TObject2): array of TObject2;
By: marpis
Description: Arrange objects in array from closest to furthers
*******************************************************************************}
function ArrangeObjects(Objs: Array of TObject2): array of TObject2;
var
i, w: integer;
Distances, Distances2: TIntegerArray;
begin
SetArrayLength(Distances, GetArrayLength(Objs));
SetArrayLength(Distances2, GetArrayLength(Objs));
for i:= 0 to High(Objs) do
begin
Distances[i] := Distance(MSCX, MSCY, Objs[i].x, Objs[i].y);
Distances2[i] := Distance(MSCX, MSCY, Objs[i].x, Objs[i].y);
end;
QuickSort(distances, Low(distances), High(distances));
for i:= 0 to High(Objs) do
begin
InIntArrayEx(Distances2, w, distances[i]);
Result[i] := Objs[w];
end;
end;
{*******************************************************************************
procedure FilterFightingMonsters(Mobs: Array of TObject2);
By: marpis
Description: Filters objects that are in fight in array
*******************************************************************************}
procedure FilterFightingMonsters(Mobs: Array of TObject2);
var
i: integer;
begin
for i:= 0 to High(Mobs) do
if Mobs[i].InFight then
DeleteObj2ArrayIndex(i, Mobs);
end;
Example of fnding a giant rat:
function KillRat: boolean
var
Rats: array of TObject2;
i, x, y: integer;
begin
if FindObjects(Rats, 50, 30, [1904881, 293719, 945789], 5, 15, true) then
begin
FilterFightingMonsters(Rats);
Rats:= ArrangeObjects(Rats);
for i:= 0 to High(Rats) do
begin
MMouse(Rats[i].x, Rats[i].y, 5, 5);
if IsUpText('iant') then
begin
GetMousePos(x, y);
Mouse(x, y, 0, 0, false);
Result:= ChooseOption('ttack');
end;
end;
end else writeln('No rats found!');
end;Thanks for comments!
:)