Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

llTarget, and llTargetRemove

Talan Mackenzie
The Rocketeer
Join date: 15 Aug 2004
Posts: 14
06-06-2005 23:59
Its the intrepid Talan again, plumbing the obscure depths of LSL to bring you more things I don't understand.

The short of the situation is that I have an object that travels to a vector with llMoveToTarget. Everything works fine. I would like to add a feature so that when it reaches the target, it executes some code (like sending me a message).

The obvious solution would be to llTarget the position, so that at_target gets raised when it arrives. To keep it from happening over and over, I'll just llTargetRemove at the end of the at_target block. Easy? I thought so too.

Apperantly llTarget wants some kind of integer before it, a handle. So..

CODE
targetnum = llTarget(targetvec, 0.5);


And then...

CODE
at_target(integer tnum, vector targetpos, vector ourpos)
{
llInstantMessage(llGetOwner(), "I'm here.");
llTargetRemove(targetnum);
}


The target is not being removed. The at_target block fires over and over again. I'm fairly certain this is arising from my not understanding the way handles work for targets. If you know better, I'd appreciate some help.
Escort DeFarge
Together
Join date: 18 Nov 2004
Posts: 681
06-07-2005 09:39
Facing much the same issue, I ended up with a snip along these lines...
CODE
vector target = <x, y, z>;
while (llVecDist(llGetPos(), target) > 0.001) {
llSetPos(target);
}
llOwnerSay("OK, I'm there");

...I think I found it in the wikki somewhere.

/esc
_____________________
http://slurl.com/secondlife/Together
Talan Mackenzie
The Rocketeer
Join date: 15 Aug 2004
Posts: 14
Yes and no..
06-07-2005 10:06
Yeah, that'd do for while-based non-physical setpos movement. Unfortunately this situation requires a physical, llMoveToTarget based movement. Thanks for your interest, though.
Escort DeFarge
Together
Join date: 18 Nov 2004
Posts: 681
06-07-2005 10:23
Then why not just...
CODE
  at_target(integer tnum, vector targetpos, vector ourpos) {
if (tnum == handle && llVectorDist(targetpos, ourpos) < some_float) {
state do_me;
}
}

state do_me {
state_entry() {
...do my code...
}
....
}

...I think you missed the wikki wisdom "...within a defined range...".

Have a pleasant day.

/esc
_____________________
http://slurl.com/secondlife/Together
Talan Mackenzie
The Rocketeer
Join date: 15 Aug 2004
Posts: 14
Here's why not...
06-07-2005 13:35
Because now it's going to a whole new state when it reaches the target, meaning I have to repeat all the code from default in the do_me state. The object doesn't sit dormant once it hits the target, it needs to do other things. The state solution is a possible kludge fix which I hadn't thought of, and I'll use it if I have to, but I have got to believe that someone out there knows how to llRemoveTarget. Someone. Anyone.
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
06-07-2005 14:44
Are you positive that the target is not being removed? llInstantMessage causes a built-in delay in the script's execution. When I was experimenting with the not_at_target and at_target functions, the functions would execute multiple times, rapidly. If many at_target responces are queued while the llInstantMessage from the first fire of at_target is executing, then you'll get some erronious repeats.

Try putting the call to llInstantMessage after the call to llTargetRemove. llOwnerSay is also a valid alternative to llInstantMessage and it doesn't delay your script.
==Chris
_____________________
October 3rd is the Day Against DRM (Digital Restrictions Management), learn more at http://www.defectivebydesign.org/what_is_drm
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
06-07-2005 14:47
Also, it would help if you could post the context (events, functions, loops, etc) where llTarget is being called. This way, we could diagnose any logic errors that may cause multiple targets to be set up with the same data.
==Chris
_____________________
October 3rd is the Day Against DRM (Digital Restrictions Management), learn more at http://www.defectivebydesign.org/what_is_drm
Talan Mackenzie
The Rocketeer
Join date: 15 Aug 2004
Posts: 14
06-07-2005 17:34
Tried llOwnerSay and let it run for 10 seconds, it kept spamming and spamming. There's no backlog here, the target is really not being removed. I'll post the script up here when I get a chance.
Talan Mackenzie
The Rocketeer
Join date: 15 Aug 2004
Posts: 14
06-07-2005 17:57
Several debug lines later...

The target was being established during the sensor calls, of which two generally snuck by before it actually reached the target (and terminated target). Long story short, two targets were being defined. What I'm still curious about is how
CODE
targetnum = llTarget(targetvec, 0.5);

managed to define two targets. They both had the same handle, so the second should have overwritten the first.. no?

Working solution was actually to put llTarget within an IF(toggle) statement, inside which toggle was set to FALSE, to make damn sure it only happened once.
Escort DeFarge
Together
Join date: 18 Nov 2004
Posts: 681
06-08-2005 03:27
From: Talan Mackenzie
The state solution is a possible kludge fix which I hadn't thought of, and I'll use it if I have to.

I find it rather odd that you chose to use the word "kludge" to describe the use of a script state change to define a change of state!?!
_____________________
http://slurl.com/secondlife/Together
Zindorf Yossarian
Master of Disaster
Join date: 9 Mar 2004
Posts: 160
06-08-2005 06:16
Escort's solution of checking the distance between the current position and the destination position is usable with physical objects, and it most often used for elevators. You simply need to put the check into a timer event which runs ever second or so. I also find that the timer event works well for scaling the llMoveToTarget, in order to have steady speed for the moving object.
_____________________
Badass Ninja Penguin: Killing stuff it doesn't like since sometime in May 2004.
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
06-08-2005 12:56
From: Talan Mackenzie
They both had the same handle, so the second should have overwritten the first.. no?


Nope. You can define as many targets as you like in a script, but if you dont keep track of their handle integers, then you have no way to remove them.

For example:
CODE

integer myTarget;
integer i;
for (i = 0; i < 2; ++i) {
myTarget = llTarget(...);
}
llTargetRemove(myTarget);


That code only removes the second target that was defined. The first target's return value is lost once the second target's return value is assigned to the myTarget variable. The not_at_target and at_target events for the first target will continue to fire.

This brings up an interesting question... is there *any* way to clear all targets, even those that you no longer have the identifyer for? A state change might do it, since all listens are cleaned up there, but Im not 100% sure.

EDIT:
Oops, the answer to my question is obvious.
Code your at_targer event like this:
CODE

at_target(integer target, vector targPos, vector curPos) {
if (target == myTarget) {
// Do stuff...
}
llTargetRemove(target);
}

That way, all the handles that trigger an at_target event, even those that are erronious, are cleaned up (except for those that never trigger an at_target event...)
==Chris