Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

ladder script

Dylan Rickenbacker
Animator
Join date: 11 Oct 2006
Posts: 365
04-03-2008 05:40
I made a poseball for climbing up a vertical ladder a while back - a bad hack, no variables, all the vectors fixed in the code. Now I'm trying to rework that script so I can use the ladder in other places too without having to recode everything.

One thing I did to do that is to link the poseball to the ladder so I can move the poseball in relation to it instead of in region coordinates. Trouble is, if I do that, the poseball moves, but not the av sitting on it, unless I call an additional function to move the av. The relevant bit of code looks like this:

CODE

while(curPos != target) // we're not there yet
{
if(target == up)
{
llSetPos(curPos - <0.0,0.0,0.25>); //move the poseball
curPos = llGetLocalPos(); //get the new position
avPos = curPos - avOffset; //set the new position for the av
llSetLinkPrimitiveParams(avlinknum, [PRIM_POSITION,avPos]); // move av there
}

if(target == down)
{
llSetPos(curPos + <0.0,0.0,0.25>);
curPos = llGetLocalPos();
avPos = curPos - avOffset;
llSetLinkPrimitiveParams(avlinknum, [PRIM_POSITION,avPos]);
}
}



This works, but the motion looks very jerky that way. I wonder is there a more elegant way to do that? Any ideas much appreciated.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
04-03-2008 15:03
I think llSetLinkPrimitiveParams is one of the throttled functions, so even if you call it in a loop like that, it blocks for 0.2 seconds each time you call it. So at best you get 5 of them a second, probably more like 4. Ditto for llSetPos. So that loop is basically moving the av 2 - 2.5 times a second. Try using a smaller step than 0.25m - this will slow down the speed with which the av climbs up or down, but it should also make the jerks smaller. Another option is to throw more scripts at it, all of them moving the av in parallel, but synchronizing them will get tricky.

Here's a question - why do you need to move the poseball at all? Once the av is sitting on the object, it becomes like another linked prim, and you can just calculate its new position and move it there, without actually having to move the poseball prim. Assuming the animation that's playing is moving the arms and legs in a ladder climbing motion, and not actually moving the hips, I think this might work.

That way you only have one blocking function (llSetLinkPrimitiveParams) in the loop, instead of 2, and that doubles the speed at which your code runs. Maybe you need the poseball to end up at the top or bottom of the ladder, and you can do that by moving the poseball in one step at the end of the av-mover loop (assuming the ladder isn't >10m, if it is, then you'll need a separate loop to move the poseball).

So, instead of:

llSetPos(curPos - <0.0,0.0,0.25>;); //move the poseball
curPos = llGetLocalPos(); //get the new position

You have:

curPos = curPos - <0.0,0.0,0.25>;

I think that might work... I'm not sure where avOffset is coming from in your script, but unless I'm totally missing something, I don't think the loop needs to move the poseball prim.
Dylan Rickenbacker
Animator
Join date: 11 Oct 2006
Posts: 365
04-03-2008 23:29
Hi Ziggy, thanks for the reply. The idea appeals to me greatly, the only trouble is I haven't found any way to get the current position of the avatar, or indeed of any prim in the linkset other than the one the script resides in. If I found a way to do that, I wouldn't use a poseball at all but put the script inside the ladder itself.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
04-04-2008 11:52
OK, so avOffset is the sit target offset? Which is only known in the 'poseball' prim. Even then, do you really need to move the poseball? Or can you link the poseball to the ladder, and then have the poseball script move only the av?

I have no idea if this will work, but it's an idea. And to simplify things, for now I'm assuming that 'up' and 'down' are < 10m apart, using more variables than necessary to illustrate what I'm doing, etc...

CODE

while(curPos != target) // we're not there yet
{
if(target == up)
{
// Only move the av here, don't move the poseball
curPos = curPos - <0.0,0.0,0.25>; //calculate the new position, without actually moving anything
avPos = curPos - avOffset; //set the new position for the av
llSetLinkPrimitiveParams(avlinknum, [PRIM_POSITION,avPos]); // move av there
}

if(target == down)
{
// Only move the av here, don't move the poseball
curPos = curPos + <0.0,0.0,0.25>; //calculate the new position, without actually moving anything
avPos = curPos - avOffset;
llSetLinkPrimitiveParams(avlinknum, [PRIM_POSITION,avPos]);
}
}

// Done moving the av, now move the poseball
llSetPos(target);



Try that and see what happens. The idea is that you don't need to continuously get the av's current position. If you know the av's starting position, and you know how much you've moved him so far, then you know his new position. So you move the av in small steps, then once that's done, move the poseball in one step.

Or maybe I'm completely missing what you're trying to tell me, and there's some obvious reason why that won't work.

Some other options - don't link the poseball to the ladder. Have the ladder talk to the poseball, and tell it its position, rotation, size. This will require a lot more math, but from that you could have the poseball correctly position itself in relation to the ladder, and also know how far to move. But that's probably best left for 'phase 2' :)
Dylan Rickenbacker
Animator
Join date: 11 Oct 2006
Posts: 365
04-04-2008 12:20
Thanks Ziggy! Your idea works perfectly, I was just being dense!
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
04-04-2008 13:49
Note that if you move the avatar away from the prim's sit target, another avatar can then sit on the sit target, and llAvatarOnSitTarget() will return the NEW avatar, even though the original avatar is still sitting on the object. You might want to think about what to do in this circumstance; whether to ignore the original sitter (they'll just stop moving and have to stand up manually), unsit the new or old sitter, manage a list of sitters, etc. Note also that you may have to test whether an avatar is still sitting in your 'changed' event handlers by iterating through the link set and testing llGetLinkKey(). You MIGHT instead be able to get away with moving the avatar and the SIT TARGET (as opposed to the whole prim) together to avoid this complication.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
04-04-2008 14:59
Is that how avatar-on-sit-target works? I've never played with this "treat the avatar as a linked prim" thing, so all of this is new to me :)
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
04-04-2008 15:26
Yeah. llAvatarOnSitTarget() literally just tests whether there is a (linked) avatar at the place where the sit target is defined. Otherwise the avatar acts in most regards like a child prim box. Note that the system prevents--in some manner--avatars from sitting such that they overlap, or overlap and both intersect a sit target, or something like that.
Blaze Nielsen
Registered User
Join date: 24 May 2005
Posts: 276
Tried Ziggy's script, hmmm
05-05-2008 12:53
I know I can be pretty dense, but I put ziggys script in a ball, connected it to a rope and couldnt get it to work, what am I missing here?
Dylan Rickenbacker
Animator
Join date: 11 Oct 2006
Posts: 365
05-05-2008 22:26
Blaze: It wouldn't work just like that, it's only part of the script.