SRL Archive - MSI Suggestions

MSI_TrackObject


marpis

2010-08-09 07:03:56

In Objects.simba.
I hope it works well, couldn't really test it because my computer is killing me :-\


{******************************************************************************}
{ procedure MSI_TrackObject(var ObjInfo: TMSObject); }
{ By: marpis }
{ Date: 9th August 2010 }
{ Description: Follows object while moving (ObjInfo.X, ObjInfo.Y) }
{******************************************************************************}
procedure MSI_TrackObject(var ObjInfo: TMSObject);
var
TPA: TPointArray;
CTS, HalfWidth, HalfHeight: integer;
B: TBox;
begin
CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(ObjInfo.Hue, ObjInfo.Sat);

HalfWidth := ObjInfo.W div 2;
HalfHeight := ObjInfo.H div 2;

while IsMoving do
begin
B := IntToBox(ObjInfo.X - HalfWidth, ObjInfo.Y - HalfHeight, ObjInfo.X + HalfWidth, ObjInfo.Y + HalfHeight);
if MSI_FindObjectsTPA(TPA, ObjInfo, B) then
begin
SortTPAFrom(TPA, Point(ObjInfo.X, ObjInfo.Y));
ObjInfo.X := TPA[0].X;
ObjInfo.Y := TPA[0].Y;
end;
Wait(20);
end;

SetColorSpeed2Modifiers(0.2, 0.2);
ColorToleranceSpeed(2);
end;

I think I'll test this tonight and put it into FindObjectsIn(), so that if you use the ClickLeft-action in FindObjectsIn, it will automatically track the object instead of just waiting for character to stop.
This way both woodcutting and mining will improve without any code changes in /skills/ :) This will make WaitWhileChopping way more reliable, because now if you're not already right next to the tree it will very likely watch some other tree to be chopped.

Coh3n

2010-08-09 09:40:02

Awesome! And hey, you stopped capitalizing bold words!?

lordsaturn

2010-08-09 12:43:06

OK when I saw this here's what I thought of.. Once you find the object and have it stored in the TMSObject, use a SmartColors like algorithm to get the unique colors of the object and use those colors to easily track the object.

marpis

2010-08-09 13:57:51

From: lordsaturn
OK when I saw this here's what I thought of.. Once you find the object and have it stored in the TMSObject, use a SmartColors like algorithm to get the unique colors of the object and use those colors to easily track the object.


if you want to write that then be my guest :p

—
and yea i got bored with capitalizing

NCDS

2010-08-09 14:38:08

From: marpis

and yea i got bored with capitalizing


It's for the best ;)

3Garrett3

2010-08-09 14:47:13

From: NCDS
It's for the best ;)


I capitalize my bolds :)

But @ the actual function,

If this is implemented (and tested/proven to work very well, I noticed you mentioned it wasn't tested) I wont need to write a major part of the fishing.scar part that is missing. I will be able to just write one function rather than two, and it should be ready.

marpis

2010-08-11 04:39:49

I tried making this work properly, but the problem was that IsMoving doesn't immediately recognize when we have started moving :-\ Hmm…

Sir R. M8gic1an

2010-08-11 07:32:00

@LordSaturn: I've attempted a SmartColors tracker. It doesn't work too well. Too few colors to track.

@Marpis: better to use MiddleTPA, as you'll be keeping better track of the object.
And I'd do while(FlagExists)or(IsMoving).

It doesn't matter if you've stopped still, as the object will remain in place ;)

~RM

Coh3n

2010-08-11 12:17:21

From: marpis
I tried making this work properly, but the problem was that IsMoving doesn't immediately recognize when we have started moving :-\ Hmm…

WaitIsMoving?

Coh3n

2010-08-11 12:57:47

Instead of making a new thread, I'll just post here. Marpis, I'm not sure why you made all the Objs in the functions var, but the interpreter didn't like it and it wouldn't compile. I fixed it for now, but I was looking at the functions and now that we have the global arrays, I think all the object functions should take integer parameters instead of TMSObject.

That way you can set whatever you need, where ever you need to.

marpis

2010-08-11 14:56:37

From: Coh3n
Instead of making a new thread, I'll just post here. Marpis, I'm not sure why you made all the Objs in the functions var, but the interpreter didn't like it and it wouldn't compile. I fixed it for now, but I was looking at the functions and now that we have the global arrays, I think all the object functions should take integer parameters instead of TMSObject.

That way you can set whatever you need, where ever you need to.


Yea, I guess we should change it to take an integer. I made them take variables because I wanted all the functions to update the x, y properties of the TMSObject.

Coh3n

2010-08-11 16:05:13

From: marpis
Yea, I guess we should change it to take an integer. I made them take variables because I wanted all the functions to update the x, y properties of the TMSObject.

Okay (I think I remember reading that in the SVN log). And yeah, taking an integer we can reset any attribute at any time. Also, all the other MSI functions take integers for scripts and items, so may as well stay consistent.

marpis

2010-08-13 01:44:54

I kinda gave up with this, because I couldn't make it reliable.
If someone has experience with tracking while moving, please finish this. :rolleyes:
It only needs proper loop system; when to start tracking and when to end it.


Giving it one more shot. Also changing object functions to take integers now.

NCDS

2010-08-15 18:38:33

Question about this:

{******************************************************************************}
{ procedure MSI_TrackObject(var ObjInfo: TMSObject); }
{ By: marpis }
{ Date: 09 August 2010 }
{ Description: Follows object while moving (ObjInfo.X, ObjInfo.Y) }
{******************************************************************************}
procedure MSI_TrackObject(ObjID: integer);
var
TPA: TPointArray;
CTS, T: integer;
B: TBox;
begin
CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(MSI_Objects[ObjID].Hue, MSI_Objects[ObjID].Sat);

T := GetSystemTime + 2000 + Random(200);
while (GetSystemTime < T) do
begin
if (FlagPresent) or (IsMoving) then
Break;
Wait(20);
end;

repeat
B := IntToBox(MSI_Objects[ObjID].X - 25, MSI_Objects[ObjID].Y - 25,
MSI_Objects[ObjID].X + 25, MSI_Objects[ObjID].Y + 25);
if MSI_FindObjectsTPA(TPA, ObjID, B) then
MiddleTPAEx(TPA, MSI_Objects[ObjID].X, MSI_Objects[ObjID].Y);
Wait(5);
until (not FlagPresent) or (not IsMoving);

SetColorSpeed2Modifiers(0.2, 0.2);
ColorToleranceSpeed(2);
end;
Would the repeat..until make more sense as a while..do? Unless I'm missing something right now whether there is a flag present or not the repeat..until will execute as it checks after it goes through once instead of before.

marpis

2010-08-16 02:13:15

From: NCDS
Question about this:

{******************************************************************************}
{ procedure MSI_TrackObject(var ObjInfo: TMSObject); }
{ By: marpis }
{ Date: 09 August 2010 }
{ Description: Follows object while moving (ObjInfo.X, ObjInfo.Y) }
{******************************************************************************}
procedure MSI_TrackObject(ObjID: integer);
var
TPA: TPointArray;
CTS, T: integer;
B: TBox;
begin
CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(MSI_Objects[ObjID].Hue, MSI_Objects[ObjID].Sat);

T := GetSystemTime + 2000 + Random(200);
while (GetSystemTime < T) do
begin
if (FlagPresent) or (IsMoving) then
Break;
Wait(20);
end;

repeat
B := IntToBox(MSI_Objects[ObjID].X - 25, MSI_Objects[ObjID].Y - 25,
MSI_Objects[ObjID].X + 25, MSI_Objects[ObjID].Y + 25);
if MSI_FindObjectsTPA(TPA, ObjID, B) then
MiddleTPAEx(TPA, MSI_Objects[ObjID].X, MSI_Objects[ObjID].Y);
Wait(5);
until (not FlagPresent) or (not IsMoving);

SetColorSpeed2Modifiers(0.2, 0.2);
ColorToleranceSpeed(2);
end;
Would the repeat..until make more sense as a while..do? Unless I'm missing something right now whether there is a flag present or not the repeat..until will execute as it checks after it goes through once instead of before.


Hmm I guess you're right. Yeah.

Blumblebee

2010-08-16 13:24:40

I was thinking about this in it's entirety and I thought of a cool idea and thought I'd run it by everyone.

if anyone remembers N1ke's MMtoMS function, he calculated the position on the MM to a fairly accurate area on the MS. Now, I was thinking what if we did a search on the MM and found a unique color (again this might not work if there is no unique colors on screen) and then watched for how many pixels the character moved on the MM via the unique color. Then simply converting this distance in the x and y of the MM to a distance in the x and y of the MS and we should have a pretty accurate area to where the object should be no?

although I'm sure that will prove to be just as difficult to produce (as what we have now), I figured if someone can't prove this inplausible I would give it a shot.

marpis

2010-08-16 14:02:37

From: Blumblebee
I was thinking about this in it's entirety and I thought of a cool idea and thought I'd run it by everyone.

if anyone remembers N1ke's MMtoMS function, he calculated the position on the MM to a fairly accurate area on the MS. Now, I was thinking what if we did a search on the MM and found a unique color (again this might not work if there is no unique colors on screen) and then watched for how many pixels the character moved on the MM via the unique color. Then simply converting this distance in the x and y of the MM to a distance in the x and y of the MS and we should have a pretty accurate area to where the object should be no?

although I'm sure that will prove to be just as difficult to produce (as what we have now), I figured if someone can't prove this inplausible I would give it a shot.


That's a nice idea but incredibly difficult :rolleyes:

3Garrett3

2010-08-16 14:02:38

From: Blumblebee
I was thinking about this in it's entirety and I thought of a cool idea and thought I'd run it by everyone.

if anyone remembers N1ke's MMtoMS function, he calculated the position on the MM to a fairly accurate area on the MS. Now, I was thinking what if we did a search on the MM and found a unique color (again this might not work if there is no unique colors on screen) and then watched for how many pixels the character moved on the MM via the unique color. Then simply converting this distance in the x and y of the MM to a distance in the x and y of the MS and we should have a pretty accurate area to where the object should be no?

although I'm sure that will prove to be just as difficult to produce (as what we have now), I figured if someone can't prove this inplausible I would give it a shot.


I like the idea, I don't know if I'd be able to re-create it though. If you're on msn, we can chat about it :)

Blumblebee

2010-08-16 14:11:01

Well I'll get on it with Garrett and see what we can do. If anyone is willing to try to help with the math conversion of 1 pixel via the MM to 1 tile via the MS that would be cool

CX gamer

2010-08-18 06:44:11

Are you sure that that's even possible?
You'd have a hard time with slopes and such.

3Garrett3

2010-08-18 13:54:30

From: CX gamer
Are you sure that that's even possible?
You'd have a hard time with slopes and such.


I've been looking into it. Progress is very slow so far. My knowledge isn't really enough to fully grasp how to do it all really well or efficiently. Though the initial results are good, I've got a beta that can track the movement in relation to a certain spot on the map, usually a fence or other stationary object. It doesn't auto pick the object though, and it doesn't always work perfect, so I still have a lot to do..

Blumblebee

2010-08-18 13:57:26

From: CX gamer
Are you sure that that's even possible?
You'd have a hard time with slopes and such.


I'm more having a hard time with finding unique MM colors in a fast timeframe. It seems the fastest I can get that gives me accurate results is 3 seconds. However with that said you only need to gather the unique colors once a runtime I would think.

Still I think that this method might be too inefficient.

Edit: I Lied. If I break it down to taking only 5 colors or so I can do it in 78 ms. Which sounds good to me.

Sabzi

2010-08-18 13:59:51

Create a small dtm during runtime(more points, needs to be less unique), or a small tpa or a small bitmap? Just trying to help.

Blumblebee

2010-08-18 14:22:14

okay new issue. isMoving() keeps returning false positives on me. IE I cannot get a proper reading because it randomly sets itself off when the character isn't moving :/

might as well post the code now. Keep in mind it's really messy and there is probably math errors etc. I haven't gotten past getting accurate pixel count movements yet.

program new;
{$i SRL/SRL.scar}
{functions required

- get unique color
- get x and y movements
- calculate distance (MM pixel -> MS tile}

const
AXIS_X = 0;
AXIS_Y = 1;

var
Color_List: tIntegerArray;
Initial_Move, Final_Move: array of tIntegerArray;
Dist_X, Dist_Y: Integer;

function ListUniqueColors(x1, y1, x2, y2: Integer): TIntegerArray;
// based of work from N3ss3s
var
I, L: Integer;
C: TIntegerArray;
begin
SetArrayLength(Result, 1 shl 20);
C := GetColors(TPAFromBox(IntToBox(x1, y1, x2, y2)));
for I := 0 to High(C) do
if CountColor(C[I], x1, y1, x2, y2) = 1 then
begin
Result[l] := C[I];
L := L + 1;
if L > 4 then
Break;
end;
SetArrayLength(Result, L);
end;

procedure findMovement(var Movements: array of tIntegerArray);
var
I: Integer;
x, y, L: Integer;
begin
for I := 0 to high(Color_List) do
begin
if FindColor(x, y, Color_List[i], MMx1, MMy1, MMx2, MMy2) then
begin
L := getArrayLength(Movements);
setArrayLength(Movements, L+1);
Movements[L] := [x, y];
end;
end;

try
for I := 0 to high(Movements) do
writeLn('[ Color: '+IntToStr(Color_List[i])+'; Area: ('+inttostr(movements[I][0])+','+inttostr(movements[I][1])+') ]');
except end;
writeLn('----------------------------------');
end;

procedure returnMovement();
var
I, H: Integer;
Count_X, Count_Y: Integer;
t: LongInt;
tempCount: Integer;
begin
Color_List := ListUniqueColors(MMx1, MMy1, MMx2, MMy2);

findMovement(Initial_Move);

t := getSystemtime();
while not isMoving() do
begin
if getSystemTime-t > 5000 then
Exit;
wait(50);
end;

Flag();

while isMoving do
wait(50);
findMovement(Final_Move);

// deturmine X mean
for I := 0 to high(Initial_Move) do
begin
tempCount := Round( abs(Initial_Move[I][AXIS_X] - Final_Move[I][AXIS_X]) );
Count_X := Count_X + tempCount;
end;

H := high(Initial_Move);

writeLn('Count X = '+IntToStr(Count_X));
writeLn('H[X] = '+IntToStr(H));

Dist_X := Count_X div H;

// deturmine Y mean
for I := 0 to high(Initial_Move) do
begin
tempCount := Round( abs(Initial_Move[I][AXIS_Y] - Final_Move[I][AXIS_Y]) );
Count_Y := Count_Y + tempCount;
end;

H := high(Initial_Move);

writeLn('Count Y = '+IntToStr(Count_Y));
writeLn('H[Y] = '+IntToStr(H));

Dist_Y := Count_Y div H;

end;

begin
setUPSRL();

returnMovement();
writeLn('X = '+IntToStr(Dist_X)+' Y = '+IntToStr(Dist_Y));
end.

marpis

2010-08-19 14:00:14

This should be quite fast for getting all unique colors..

function ListUniqueColors2(x1, y1, x2, y2: integer): tintegerarray;
var
bmp,x, y, w, h: integer;
color, index, resultLength: integer;
begin
CopyClientToBitmap(bmp, x1, y1, x2, y2);
w := x2 - x1;
h := y2 - y1;

for x := 0 to w do
for y := 0 to h do
begin
color := fastgetpixel(bmp, x, y);
if InIntArrayEx(result, index, color) then
begin
swap(result[index], result[resultLength - 1]);
setLength(result, resultLength - 1);
end else
begin
Inc(resultLength);
SetLength(result, resultLength);
result[resultLength - 1] := color;
end;
end;

freebitmap(bmp);
end;

Coh3n

2010-08-19 14:11:44

You guys keep talking about going from the MM to MS, but is there something wrong with this function?

{******************************************************************************}
{ procedure MSI_TrackObject(var ObjInfo: TMSObject); }
{ By: marpis }
{ Date: 09 August 2010 }
{ Description: Follows object while moving (ObjInfo.X, ObjInfo.Y) }
{******************************************************************************}
procedure MSI_TrackObject(ObjID: integer);
var
TPA: TPointArray;
CTS, T: integer;
B: TBox;
begin
CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(MSI_Objects[ObjID].Hue, MSI_Objects[ObjID].Sat);

T := GetSystemTime + 2000 + Random(200);
while (GetSystemTime < T) do
begin
if (FlagPresent) or (IsMoving) then
Break;
Wait(20);
end;

repeat
B := IntToBox(MSI_Objects[ObjID].X - 25, MSI_Objects[ObjID].Y - 25,
MSI_Objects[ObjID].X + 25, MSI_Objects[ObjID].Y + 25);
if MSI_FindObjectsTPA(TPA, ObjID, B) then
MiddleTPAEx(TPA, MSI_Objects[ObjID].X, MSI_Objects[ObjID].Y);
Wait(5);
until (not FlagPresent) or (not IsMoving);

SetColorSpeed2Modifiers(0.2, 0.2);
ColorToleranceSpeed(2);
end;
NCDS mentioned the while..do thing, which I agree with, but this seems like it should work pretty well, no?

3Garrett3

2010-08-19 14:15:49

From: Coh3n
You guys keep talking about going from the MM to MS, but is there something wrong with this function?

{******************************************************************************}
{ procedure MSI_TrackObject(var ObjInfo: TMSObject); }
{ By: marpis }
{ Date: 09 August 2010 }
{ Description: Follows object while moving (ObjInfo.X, ObjInfo.Y) }
{******************************************************************************}
procedure MSI_TrackObject(ObjID: integer);
var
TPA: TPointArray;
CTS, T: integer;
B: TBox;
begin
CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(MSI_Objects[ObjID].Hue, MSI_Objects[ObjID].Sat);

T := GetSystemTime + 2000 + Random(200);
while (GetSystemTime < T) do
begin
if (FlagPresent) or (IsMoving) then
Break;
Wait(20);
end;

repeat
B := IntToBox(MSI_Objects[ObjID].X - 25, MSI_Objects[ObjID].Y - 25,
MSI_Objects[ObjID].X + 25, MSI_Objects[ObjID].Y + 25);
if MSI_FindObjectsTPA(TPA, ObjID, B) then
MiddleTPAEx(TPA, MSI_Objects[ObjID].X, MSI_Objects[ObjID].Y);
Wait(5);
until (not FlagPresent) or (not IsMoving);

SetColorSpeed2Modifiers(0.2, 0.2);
ColorToleranceSpeed(2);
end;
NCDS mentioned the while..do thing, which I agree with, but this seems like it should work pretty well, no?


We should kinda make that return a Tpoint shouldn't we? Otherwise it's useless because it doesn't return anything :P

Blumblebee

2010-08-19 14:16:54

From: Coh3n
You guys keep talking about going from the MM to MS, but is there something wrong with this function?

{******************************************************************************}
{ procedure MSI_TrackObject(var ObjInfo: TMSObject); }
{ By: marpis }
{ Date: 09 August 2010 }
{ Description: Follows object while moving (ObjInfo.X, ObjInfo.Y) }
{******************************************************************************}
procedure MSI_TrackObject(ObjID: integer);
var
TPA: TPointArray;
CTS, T: integer;
B: TBox;
begin
CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(MSI_Objects[ObjID].Hue, MSI_Objects[ObjID].Sat);

T := GetSystemTime + 2000 + Random(200);
while (GetSystemTime < T) do
begin
if (FlagPresent) or (IsMoving) then
Break;
Wait(20);
end;

repeat
B := IntToBox(MSI_Objects[ObjID].X - 25, MSI_Objects[ObjID].Y - 25,
MSI_Objects[ObjID].X + 25, MSI_Objects[ObjID].Y + 25);
if MSI_FindObjectsTPA(TPA, ObjID, B) then
MiddleTPAEx(TPA, MSI_Objects[ObjID].X, MSI_Objects[ObjID].Y);
Wait(5);
until (not FlagPresent) or (not IsMoving);

SetColorSpeed2Modifiers(0.2, 0.2);
ColorToleranceSpeed(2);
end;
NCDS mentioned the while..do thing, which I agree with, but this seems like it should work pretty well, no?


I thought the issue was that it was not working so I was looking for a way around it. If the function is working then what is the whole issue?

Coh3n

2010-08-19 14:19:06

From: 3Garrett3
We should kinda make that return a Tpoint shouldn't we? Otherwise it's useless because it doesn't return anything :P

MSI_Objects[Obj].X and .Y are set, so they can be used in FindObjectsIn function.

From: Blumblebee
I thought the issue was that it was not working so I was looking for a way around it. If the function is working then what is the whole issue?

I may have missed it, but I didn't see where anyone said it wasn't working. :p

I think it can be adjusted to work, the right idea is there.

3Garrett3

2010-08-19 14:21:54

From: Coh3n
MSI_Objects[Obj].X and .Y are set, so they can be used in FindObjectsIn function.


I may have missed it, but I didn't see where anyone said it wasn't working. :p

I think it can be adjusted to work, the right idea is there.


It's not returning anything. If you look in the actual procedure it's not a var in the parenthesis, but in the heading it's a var. If it was a var it would return, if not, it wouldn't. Right?

Blumblebee

2010-08-19 14:24:52

From: Coh3n

I may have missed it, but I didn't see where anyone said it wasn't working. :p

I think it can be adjusted to work, the right idea is there.


I thought Marpis had come to the conclusion that he could not get it working due to a timing issue or something along those lines, I won't go dig it up but that was my impression.

3Garrett3

2010-08-19 14:29:21

From: Blumblebee
I thought Marpis had come to the conclusion that he could not get it working due to a timing issue or something along those lines, I won't go dig it up but that was my impression.


Me too ^^ The quote is in this thread somewhere

Coh3n

2010-08-19 14:36:39

From: 3Garrett3
It's not returning anything. If you look in the actual procedure it's not a var in the parenthesis, but in the heading it's a var. If it was a var it would return, if not, it wouldn't. Right?

Yes, but the MSI_Objects array is global, so the coordinates are saved as the X, Y attributes in the object's record. The X, Y attributes are set in this line:

if MSI_FindObjectsTPA(TPA, ObjID, B) then

From: Blumblebee
I thought Marpis had come to the conclusion that he could not get it working due to a timing issue or something along those lines, I won't go dig it up but that was my impression.

I think that's where I posted "WaitIsMoving?", then marpis said he was going to give it another shot, then you posted your idea.

Either way, if we can make this one work then that would better than trying to do a surplus of calculations and finding correlations between the minimap and main screen.

NCDS

2010-08-19 15:41:38

When I was messing with the mining the other day I noticed that when you had to walk to a rock this function made the script click the rock multiple times on the way. When I commented this procedure out, the problem stopped.

That's why I posted about the repeat..until being made a while..do. Unfortunately this week has been rather hectic and I haven't had much time at all to do much.

Just figured I would post the problems I was having with it.

Sir R. M8gic1an

2010-08-19 21:58:30

There's a simple way to do it ;) You guys should try looking at code that has been developed before for this very same purpose, when you are out of ideas. If someone's done it before, why would you not be able to? - I was referring to something I thought I had in my GM but seems like I changed it.



OldPoint := MSI_Objects[OBJ_ID].Point;
OldDist := Distance(OldPoint, MSCenter);

//to detect if we stopped moving
if abs(ThisDistance - OldDist) < 5 then
StoppedMoving := true;

This, wrapped up in some other failsafes, such as flag distances and so on, should work more than fine.

~RM

marpis

2010-08-20 02:49:25

From: Rasta Magician
There's a simple way to do it ;) You guys should try looking at code that has been developed before for this very same purpose, when you are out of ideas. If someone's done it before, why would you not be able to? - I was referring to something I thought I had in my GM but seems like I changed it.



OldPoint := MSI_Objects[OBJ_ID].Point;
OldDist := Distance(OldPoint, MSCenter);

//to detect if we stopped moving
if abs(ThisDistance - OldDist) < 5 then
StoppedMoving := true;

This, wrapped up in some other failsafes, such as flag distances and so on, should work more than fine.

~RM


Currently checking flag existence, if it's not there, will check IsMoving.
Still aint working good enough :(

Sir R. M8gic1an

2010-08-20 07:55:56

From: marpis
Currently checking flag existence, if it's not there, will check IsMoving.
Still aint working good enough :(


Check for actual changes in the Object distance.

~RM

Coh3n

2010-08-20 11:26:08

From: Rasta Magician
Check for actual changes in the Object distance.

~RM

Yeah, like in your function you repeatedly search in a small box around the point that was clicked. If the middle point (MiddleTPA) changes (5+ pixels or something) then we're still moving.