Here's the new FindObjectsTPA (renamed to FindObjectTPA).
- Takes a TMSObject as a parameter rather than integer/searchBox.
- More organized and it removes values from the original ATPA rather than exiting the function.
- Accuracy was also being checked twice (the first time didn't work properly, and the second time was in the wrong spot).
- BadColors and Anim have been removed as they're never used and probably never will be.
- SMART debugging is better. It will paint all the dots of the original ATPA (after checking accuracy/findAllColors), then paint boxes around all the valid points (at the end of the function).
- Added a lot of comments.
It's untested of course since it will cause a bunch of compiling errors, so if you look through it let me know if you see something out of the ordinary.
(*
MSI_FindObjectTPA
~~~~~~~~~~~~~~~~~
.. code-block:: pascal
function MSI_FindObjectTPA(Obj: TMSObject; var Points: TPointArray): Boolean;
Returns a TPointArray ('Points') of all the instances of the object 'Obj' that
are found in the object's ('Obj') SearchBox atribute.
.. note::
| Author: marpis
| Last Updated: 01 June 2011 by Coh3n
Example:
.. code-block:: pascal
ms_Points := function MSI_FindObjectTPA(TREE_NORMAL, tmpTPA);
*)
function MSI_FindObjectTPA(Obj: TMSObject; var Points: TPointArray): Boolean;
var
TPA: TPointArray;
ATPA: T2DPointArray;
tpaBoxes: TBoxArray;
i, j, cts: integer;
badPoint: boolean;
begin
if (not loggedIn) then
exit;
cts := GetToleranceSpeed;
setColorToleranceSpeed(2);
setToleranceSpeed2Modifiers(obj.hue, obj.sat);
// search for all the object's colors
setLength(ATPA, length(obj.colors));
for i := 0 to high(ATPA) do
begin
findColorsSpiralTolerance(MSCX, MSCY, ATPA[i], obj.colors[i],
obj.searchArea.x1, obj.searchArea.y1,
obj.searchArea.x2, obj.searchArea.y2, obj.tol);
end;
setColorToleranceSpeed(cts);
setToleranceSpeed2Modifiers(0.2, 0.2);
// check if all the colors were found
if (obj.findAllColors) then
for i := 0 to high(ATPA) do
if (length(ATPA[i]) < 1) then
begin
MSI_SubDebug('FindObjectTPA: not all colors were found');
deleteValueInATPA(ATPA, i);
end;
// split points in to boxes the size of object & check if there's enough points
TPA := MergeATPA(ATPA);
ATPA := TPAtoATPAEx(TPA, obj.w, obj.h);
for i := 0 to high(ATPA) do
if (length(ATPA[i]) < obj.accuracy) then
begin
MSI_SubDebug('FindObjectTPA: Not enough points: ' + intToStr(length(ATPA[i])));
deleteValueInATPA(ATPA, i);
end;
TPA := [];
sortATPAFrom(ATPA, point(MSCX, MSCY));
setLength(TPA, length(ATPA));
// draw points on SMART if setting enabled
if (MSI_SetupVars[SETUP_DEBUG_SMART]) then
drawDotsMulti(true, ATPA);
// get the middle point of each TPA in the ATPA + create a box for each point
setLength(tpaBoxes, length(TPA));
for i := 0 to high(ATPA) do
begin
tpaBoxes[i] := getTPABounds(ATPA[i]);
TPA[i] := middleTPA(ATPA[i]);
end;
// loop through all the points to see which are valid/invalid
for i := 0 to high(TPA) do
begin
badPoint := false;
// checks to see if the point is in the object's search area
if (not badPoint) then
if (not pointInBox(TPA[i], obj.searchArea)) then
begin
MSI_SubDebug('FindObjectTPA: Invalid point - exceeds search area');
badPoint := true;
end;
// check to see if point is in a bad box
if (not badPoint) then
if (length(MSI_NotBoxes) > 0) then
for j := 0 to high(MSI_NotBoxes) do
if (pointInBox(TPA[i], MSI_NotBoxes[j])) then
begin
MSI_SubDebug('FindObjectTPA: Point in bad box');
badPoint := true;
end;
// checks to see if the point is on the player
if (not badPoint) then
if (obj.excludeSelf) then
if (pointInBox(TPA[i], intToBox(PLBX1, PLBY1, PLBX2, PLBY2))) then
begin
MSI_SubDebug('FindObjectTPA: Point is on player');
badPoint := true;
end;
// a valid point as been found
if (not badPoint) then
begin
setLength(Points, length(Points) + 1);
Points[high(Points)] := TPA[i];
// add point's box to MSI_NotBoxes so it can be avoided next search
end else begin
setLength(MSI_NotBoxes, length(MSI_NotBoxes) + 1);
MSI_NotBoxes[high(MSI_NotBoxes)] := tpaBoxes[i];
end;
end;
if (length(points) > 0) then
begin
result := true;
for i := 0 to high(Points) do
if (MSI_SetupVars[SETUP_DEBUG_SMART]) then
SMART_DrawBoxMS((i = 0), MSI_MakeBox(point(Points[i].x, Points[i].y), obj.w, obj.h), clGreen);
MSI_SubDebug('FindObjectTPA: Points found: ' + intToStr(length(points)));
end;
end;
E: Updated and I started testing. This is what I get:

Anyone have an idea of how to "merge" the points that are on the same tree? By the way, the boxes are created around each point that's found.
E2: Updated script, and with some more tweaking I got this:

Much better I'd say. Oh and by the way, the first image is what happened with our current object finding.