Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Need help with attaching an avatar to a door

Luci Koenkamp
Registered User
Join date: 8 Aug 2007
Posts: 23
10-29-2007 23:51
Hi,

I´m a complete scripting newbie but I recently made a device that needs to link an avatar to a sliding door, so that by touch the avatar will move with it. I can´t use a pose ball because I can only move 1 prim with the script, so I added a pose ball script to the door together with the pose and it seems to work fine but when I touch the door, the door moves but the avatar stays in place and the door becomes invisible. Can some one help me with this? I used the following script for the door:


// USAGE INSTRUCTIONS FOR BUILDERS:
//------------------------------------------------------
// 1. Copy and paste this script into the door prim and
// change the settings (see further down).
// 2. The door prim must be linked to at least one other
// prim (could be linked to the house for example).
// 3. The door prim MUST NOT be the root prim.
// 4. Use Edit Linked Parts to move, rotate and size the
// door prim for the closed state.
// 5. When ready, stand close to the door and say
// '/door closed' (this records the closed door
// position, rotation and size to the object's
// name and description).
// 6. Use the Edit Linked parts to move, rotate and size
// the door prim for the opened state.
// 7. When ready, stand close to the door and say
// '/door opened' (this records the opened door
// position, rotation and size).
// 8. Once recorded it will not accept these commands
// again. If you do need to redo the settings then
// delete the Name and Description of the door prim
// (these are where the position information is
// stored), and then follow the steps above again.
// Note: deleting the object name won't save, so set
// the object name to 'Object' to reset the object
// name.

//------------------------------------------------------
// Change these settings to suit your needs.
//------------------------------------------------------
// To mute any/all of the sounds set the sound string(s)
// to "" (empty string).
// To get the UUID of a sound, right click on the sound
// in your inventory and choose "Copy Asset UUID", then
// paste the UUID in here.
string doorOpenSound = "cb340647-9680-dd5e-49c0-86edfa01b3ac";
string doorCloseSound = "e7ff1054-003d-d134-66be-207573f2b535";
string confirmedSound = "69743cb2-e509-ed4d-4e52-e697dc13d7ac";
string accessDeniedSound = "58da0f9f-42e5-8a8f-ee51-4fac6c247c98";
string doorBellSound = "ee871042-e272-d8ec-3d40-0b0cb3371346"; // Setting to empty stops door announcements too.
float autoCloseTime = 0; // 0 seconds to disable auto close.
integer allowGroupToo = TRUE; // Set to FALSE to disallow same group access to door.
list allowedAgentUUIDs = ["8efecbac-35de-4f40-89c1-2c772b83cafa"]; // Comma-separated, quoted list of avatar UUIDs who are allowed access to this door.
integer listenChannel = 0;


//------------------------------------------------------
// Leave the rest of the settings alone, these are
// handled by the script itself.
//------------------------------------------------------
integer isLocked = FALSE; // Only when the door is locked do the permissions apply.
integer isOpen = TRUE;
vector openPos = ZERO_VECTOR;
rotation openRot = ZERO_ROTATION;
vector openScale = ZERO_VECTOR;
vector closedPos = ZERO_VECTOR;
rotation closedRot = ZERO_ROTATION;
vector closedScale = ZERO_VECTOR;
key openerKey = NULL_KEY;
key closerKey = NULL_KEY;
integer isSetup = FALSE;
integer listenHandle = 0;
string avatarName = "";

mySayName(integer channel, string objectName, string message)
{
string name = llGetObjectName();
llSetObjectName(objectName);
llSay(0, "/me " + message);
llSetObjectName(name);
}

mySay(integer channel, string message)
{
string name = llGetObjectName();
llSetObjectName("Door";);
llSay(0, message);
llSetObjectName(name);
}

myOwnerSay(string message)
{
string name = llGetObjectName();
llSetObjectName("Door";);
llOwnerSay(message);
llSetObjectName(name);
}

mySoundConfirmed()
{
if (confirmedSound != "";)
{
llTriggerSound(confirmedSound, 1.0);
}
}

mySoundAccessDenied()
{
if (accessDeniedSound != "";)
{
llTriggerSound(accessDeniedSound, 1.0);
}
}

myGetDoorParams()
{
isSetup = FALSE;
if (llSubStringIndex(llGetObjectDesc(), "door;";) == 0 && llSubStringIndex(llGetObjectName(), "door;";) == 0)
{
list nameWords = llParseString2List(llGetObjectName(), [";"], []);
list descWords = llParseString2List(llGetObjectDesc(), [";"], []);
if (llGetListLength(nameWords) != 4 || llGetListLength(descWords) != 4)
{
myOwnerSay("The door prim's name and/or description has invalid syntax and/or number of parameters. Delete the door prim's name and description and setup the door prim again.";);
}
else
{
openPos = (vector)llList2String(nameWords, 1);
openRot = (rotation)llList2String(nameWords, 2);
openScale = (vector)llList2String(nameWords, 3);
closedPos = (vector)llList2String(descWords, 1);
closedRot = (rotation)llList2String(descWords, 2);
closedScale = (vector)llList2String(descWords, 3);
isSetup = TRUE;
}
}
}

mySetDoorParams(vector openPos, rotation openRot, vector openScale, vector closedPos, rotation closedRot, vector closedScale)
{
llSetObjectName("door;" +
(string)openPos + ";" +
(string)openRot + ";" +
(string)openScale);
llSetObjectDesc("door;" +
(string)closedPos + ";" +
(string)closedRot + ";" +
(string)closedScale);
isSetup = TRUE;
}

integer myPermissionCheck(key id)
{
integer hasPermission = FALSE;
if (isLocked == FALSE)
{
hasPermission = TRUE;
}
else if (llGetOwnerKey(id) == llGetOwner())
{
hasPermission = TRUE;
}
else if (allowGroupToo == TRUE && llSameGroup(id))
{
hasPermission = TRUE;
}
else if (llListFindList(allowedAgentUUIDs, [(string)id]) != -1)
{
hasPermission = TRUE;
}
return hasPermission;
}

myOpenDoor()
{
isOpen = FALSE;
myToggleDoor();
}

myCloseDoor()
{
isOpen = TRUE;
myToggleDoor();
}

myToggleDoor()
{
if (isSetup == FALSE)
{
myOwnerSay("The door prim has not been configured yet. Please read the usage instructions in the door script.";);
}
else if (llGetLinkNumber() == 0 || llGetLinkNumber() == 1)
{
myOwnerSay("The door prim must be linked to at least one other prim and the door prim must not be the root prim";);
}
else
{
isOpen = !isOpen;
if (isOpen)
{
if (doorBellSound != "";)
{
//llTriggerSound(doorBellSound, 1.0);
if (avatarName != "";)
{
// mySayName(0, avatarName, "is at the door.";);
avatarName = "";
}
}
if (doorOpenSound != "";)
{
llTriggerSound(doorOpenSound, 1.0);
}
llSetPrimitiveParams([ PRIM_POSITION, openPos, PRIM_ROTATION, ZERO_ROTATION * openRot / llGetRootRotation(), PRIM_SIZE, openScale ]);
// Door API.
llMessageLinked(LINK_SET, 255, "cmd|door|opened", NULL_KEY);
}
else
{
if (doorCloseSound != "";)
{
llTriggerSound(doorCloseSound, 1.0);
}
llSetPrimitiveParams([ PRIM_POSITION, closedPos, PRIM_ROTATION, ZERO_ROTATION * closedRot / llGetRootRotation(), PRIM_SIZE, closedScale ]);
// Door API.
llMessageLinked(LINK_SET, 255, "cmd|door|closed", NULL_KEY);
}

llSetTimerEvent(0.0);
if (isOpen == TRUE && autoCloseTime != 0.0)
{
llSetTimerEvent(autoCloseTime);
}
}
}

default
{
state_entry()
{
listenHandle = llListen(listenChannel, "", NULL_KEY, "";);
myGetDoorParams();
}

touch_start(integer total_number)
{
if (myPermissionCheck(llDetectedKey(0)) == TRUE)
{
avatarName = llDetectedName(0);
myToggleDoor();
}
else
{
mySoundAccessDenied();
}
}

timer()
{
myCloseDoor();
}

link_message(integer sender_num, integer num, string str, key id)
{
// Door API. The API is here in case you want to create PIN entry keypads or whatever.
if (num == llGetLinkNumber())
{
if (str == "cmd|door|doOpen";)
{
myOpenDoor();
}
else if (str == "cmd|door|doClose";)
{
myCloseDoor();
}
}
if (str == "cmd|door|discover";)
{
llMessageLinked(LINK_SET, 255, "cmd|door|discovered|" + (string)llGetKey(), id);
}
}

listen(integer channel, string name, key id, string message)
{
// Performance note: it's quicker to compare the strings than to compare permissions each time anyone says anything on this channel.
if (message == "open";)
{
if (myPermissionCheck(id) == TRUE)
{
// Only open the door if the person is quite close to this door.
openerKey = id;
closerKey = NULL_KEY;
avatarName = name;
llSensor(name, id, AGENT, 5.0, TWO_PI);
}
else
{
mySoundAccessDenied();
}
}
else if (message == "close";)
{
if (myPermissionCheck(id) == TRUE)
{
openerKey = NULL_KEY;
closerKey = id;
avatarName = name;
// Only close the door if the person is quite close to this door.
llSensor(name, id, AGENT, 5.0, TWO_PI);
}
else
{
mySoundAccessDenied();
}
}
else if (message == "lock";)
{
if (myPermissionCheck(id) == TRUE)
{
isLocked = TRUE;
mySoundConfirmed();
}
else
{
mySoundAccessDenied();
}
}
else if (message == "unlock";)
{
if (myPermissionCheck(id) == TRUE)
{
isLocked = FALSE;
mySoundConfirmed();
}
else
{
mySoundAccessDenied();
}
}
else if (message == "/door opened" && llSubStringIndex(llGetObjectName(), "door;";) == -1)
{
if (llGetOwnerKey(id) == llGetOwner())
{
mySoundConfirmed();
openPos = llGetLocalPos();
openRot = llGetLocalRot();
openScale = llGetScale();
isOpen = TRUE;
if (! (closedPos == ZERO_VECTOR && closedRot == ZERO_ROTATION && closedScale == ZERO_VECTOR))
{
mySetDoorParams(openPos, openRot, openScale, closedPos, closedRot, closedScale);
}
}
else
{
mySoundAccessDenied();
}
}
else if (message == "/door closed" && llSubStringIndex(llGetObjectDesc(), "door;";) == -1)
{
if (llGetOwnerKey(id) == llGetOwner())
{
mySoundConfirmed();
closedPos = llGetLocalPos();
closedRot = llGetLocalRot();
closedScale = llGetScale();
isOpen = FALSE;
if (! (openPos == ZERO_VECTOR && openRot == ZERO_ROTATION && openScale == ZERO_VECTOR))
{
mySetDoorParams(openPos, openRot, openScale, closedPos, closedRot, closedScale);
}
}
else
{
mySoundAccessDenied();
}
}
}

sensor(integer num_detected)
{
if (openerKey != NULL_KEY)
{
integer i;
for (i = 0; i < num_detected; i++)
{
if (llDetectedKey(i) == openerKey && myPermissionCheck(llDetectedKey(i)) == TRUE)
{
myOpenDoor();
}
}
openerKey = NULL_KEY;
}
else
{
integer i;
for (i = 0; i < num_detected; i++)
{
if (llDetectedKey(i) == closerKey && myPermissionCheck(llDetectedKey(i)) == TRUE)
{
myCloseDoor();
}
}
closerKey = NULL_KEY;
}
}

//------------------------------------------------------
// Uncomment the following code if you particularly want
// collisions to affect the door state.
//------------------------------------------------------

// collision_start(integer num_detected)
// {
// integer i;
// for (i = 0; i < num_detected; i++)
// {
// if (myPermissionCheck(llDetectedKey(i)) == TRUE)
// {
// avatarName = llDetectedName(i);
// myOpenDoor();
// }
// else if (llDetectedType(i) & AGENT)
// {
// mySoundAccessDenied();
// }
// }
// }

} // End of default state and end of script.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
10-30-2007 05:33
wow, that's alot of code.....

uhm, this may help


I had someone test real quick and it moves the sitting avatar WITH the door... even multi-prim doors, at any angle
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Luci Koenkamp
Registered User
Join date: 8 Aug 2007
Posts: 23
10-30-2007 23:02
sorry, I should have explained that it´s a sliding door not a rotating and the "door" needs to be linked to the structure.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
10-31-2007 08:14
ah ok, jumping around in the code I finally see it....

you are setting a move AND a scale..... the scale is what's giving you trouble... if it's only a move, the av should move with it (unless it's linked to the larger structure)

what you need to do, is move the av to .5 of the change in scale, then move the door. -eg startSize - endSize * 0.5

if it's linked to a larger structure, you'll need to also move the av when you move the door, and will require 2 scripts to get simultaneous movement for the av and the door

-eg in one script
llMessageLinked ( LINK_THIS, how-far-to-move, "open", "" );
llSetPrimitiveParams( [your move / size change] );

and in another
link_message( standard crap ){
if (message = "open" ){
llSetLinkPrimitiveParams( llGetNumberOfLinks() -1, [the calculated (only)move for the av] );
}
}

if you can place the door so that it slides into the structure wall, you won't have to do as much calculation

if you unlink the door, you may not have to do ANY, the trouble comes that sit position is relative to the root IIRC, if you move the root, av goes with, if you move a child, the av stays put
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
revochen Mayne
...says
Join date: 14 Nov 2006
Posts: 198
10-31-2007 10:20
Hi Void

Yes you're on the right way, if i get it right Luci wants to have the door as a child prim
and the avatar is sitting on it.
So why not just jusing 2 llSetLinkPrimitiveParams instead the llMessageLinked call for a second script?
And what for a new function is llGetNumberOfLinks? ;P
Sure best would be if the door is a single unlinked prim.
Luci Koenkamp
Registered User
Join date: 8 Aug 2007
Posts: 23
Hi guys
10-31-2007 11:25
I still have no idea what to do to make it work. The door is a single prim with a pose script but it has to stay linked to the structure. By the way the door script is the best script I can get because it lets me move the prim in any direction I want while keeping it linked to the main structure.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
10-31-2007 12:47
I don't think you can sit on a child prim, move the prim, and have the avatar move with it. Once you're sitting on an object, the avatar becomes like another linked prim in the object. It doesn't matter which child prim you sat on. Moving one child prim doesn't move other child prims, and by extension, won't move a sitting avatar.

I think. I vaguely remember testing this, but I'm not positive.
revochen Mayne
...says
Join date: 14 Nov 2006
Posts: 198
10-31-2007 15:05
I've tested several ideas already.
The only one working is to handle the avatar sitting on the prim door as an additional prim like Void already did with his post above.

llSetLinkPrimitiveParams(link_nr_of_avatar,[PRIM_POSITION,move_to]);

link_nr_of_avatar is like an additional linked prim representing the sitting avatar.
move_to is the vector representing the avatars target but couldnt figure out yet
if this vector is a global coordinates or relativ to the root prims position.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
10-31-2007 16:00
So you tried this and it works? Send in a link number that represents the avatar will move the avatar?
revochen Mayne
...says
Join date: 14 Nov 2006
Posts: 198
10-31-2007 22:20
yes Ziggy it does. The only strange thing i cant get is:
whatever i used for 'move_to' it only moves into one direction.
i tried <1,0,0>,<0,1,0> and <0,0,1> but the only result of this was
that the avatar moved to the north while sitting.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
11-01-2007 09:40
From: revochen Mayne
Hi Void

Yes you're on the right way, if i get it right Luci wants to have the door as a child prim
and the avatar is sitting on it.
So why not just jusing 2 llSetLinkPrimitiveParams instead the llMessageLinked call for a second script?

for simultaneous movement, because SetPrimitiveParams has a delay, if the delay isn't an issue, sure one script is fine

From: someone
And what for a new function is llGetNumberOfLinks? ;P
Sure best would be if the door is a single unlinked prim.

heh, the avatar should be the last link in the set when sitting on the set... you could also use the KNOWN number of links in the set + 1, but I try to avoid hard coding anything that might change if used elswhere

From: someone
I still have no idea what to do to make it work. The door is a single prim with a pose script but it has to stay linked to the structure. By the way the door script is the best script I can get because it lets me move the prim in any direction I want while keeping it linked to the main structure.

I'd pay(beg?) a scripter to redo that door for you, there are much simpler ways to go about it, that will still move the door relative to the house, regardless of placement angle.
SHAMELESS PUG: Send me an IM if you want, and I'll give you a referral to my sister. reasonable rates =)

@Ziggy:
yeah, treating a sitting av as a child prim works for movement (again... it was 'fixed' for a while, broke alot of furniture)

@revochen:
weird on the movement thing, IIRC Postion only takes globals, so your vector should be added to the doors global position.
stupid question, but what's the call you're using? PS it's "her" =)
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
revochen Mayne
...says
Join date: 14 Nov 2006
Posts: 198
11-02-2007 00:09
Hi Void

From: someone

Its "her" =)

ups...i'm sorry óò

From: someone

And what for a new function is llGetNumberOfLinks? ;P

Well i guess you mean llGetNumberOfPrims();
That was all i want to point at :)

From: someone

what's the call you're using?

i used llSetLinkPrimitiveParams(4,[PRIM_POSITION,vec_pos]);
and used local and global setting for vec_pos
here some results:
vec_pos=<1,0,0> // moving
vec_pos=<0,1,0> // moving into same direction like <1,0,0>
vec_pos=<0,0,1> // same result like above
vec_pos= llGetLocalPos()+<1,0,0> // moving like above
vec_pos=llGetPos()+<1,0,0> // not moving oô

The more and more i try i think its just a bug... dont know what else to do
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
11-02-2007 09:45
From: revochen Mayne
ups...i'm sorry óò

don't sweat it, I don't ;)
From: someone
Well i guess you mean llGetNumberOfPrims();
That was all i want to point at :)

serves me right for writing code all day.... yeah that's what I MEANT lol
From: someone
i used llSetLinkPrimitiveParams(4,[PRIM_POSITION,vec_pos]);
and used local and global setting for vec_pos
here some results:
vec_pos=<1,0,0> // moving
vec_pos=<0,1,0> // moving into same direction like <1,0,0>
vec_pos=<0,0,1> // same result like above
vec_pos= llGetLocalPos()+<1,0,0> // moving like above
vec_pos=llGetPos()+<1,0,0> // not moving oô

The more and more i try i think its just a bug... dont know what else to do

the last 2 should work, but then someone mentioned some ugly math involved, and I never used it myself so.... damn now I gotta look this up?... Strife KNOWS this (because that's who made the comment about the ugly math, on jira)... tempted to AR my post here to get Strife's attention

getlocal seems a better logical function to use on a script residing in the linked door.... although come to think of it it sould be

llGetLinkPrimitiveParams( av-link-#, [PRIM_POSITION] ) + offset * llGetLocalRot();

EDIT: except there is no such function as llGetLinkPrimitiveParams ::eyeroll::
I think if you set and store the sit target you could use

llGetLocalPos() + <sit-target-vector> + offset * llGetLocalRot()

maybe that's the ugly math Strife mentioned?
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -