LlAttachToAvatarTemp
Looking for the current API? Open the llAttachToAvatarTemp reference →
Wiki description
Follows the same convention as llAttachToAvatar, with the exception that the object will not create new inventory for the user, and will disappear on detach or disconnect. Also, this function can be used on avatars other than the owner (if granted permission) in which case the ownership is changed to the new wearer.
Function notes
It should be noted that when an object is attached temporarily, a user cannot 'take' or 'drop' the object that is attached to them.
The user does not have to be the owner of the object in advance; this function transfers ownership automatically (the usual permissions required to transfer objects apply).
If
attach_point is zero, then the object attaches to the attach point it was most recently attached to.Specification
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Caveats
- When object ownership changes, any granted permissions are reset. After a successful attach, you will need a fresh call to llRequestPermissions to allow llDetachFromAvatar and other permission-required functions to work.
- Until successful attachment via this method, previously granted permissions are retained as normal.
- The attach step is not guaranteed to succeed, and this function should not be relied on as a security measure. Use the same permission and script precautions you would use with conventional inventory transfers.
- If you use llAttachToAvatarTemp in an object that you do not have permission to transfer, the function will fail with a script error No permission to transfer, even if you are trying to attach it to yourself.
- Temporary attachments cannot request the permission PERMISSION_TELEPORT, the following error will be returned: "Temporary attachments cannot request runtime permissions to teleport"
- Attach points can be occupied by multiple attachments.Multiple attachments per attach point were added as result of SCR-277
- This was not always the case, previously if
attach_pointwas occupied, the existing object was detached and the new attachment took it's place.
- This was not always the case, previously if
- Objects attached to the head (and any attachment position within the head) will not be visible in First Person view (aka Mouselook) if "show attachments in mouselook" is disabled.
- If
attach_pointis zero but the object was never previously attached, it defaults to the right hand (ATTACH_RHAND). - If the object is already attached the function fails silently, regardless of the
attach_pointbeing a different attach point. - If attached via a Land Scope Experience script, the object will be force-detached by the server if the owner enters a parcel that does not have the Experience allowed.
- If the target agent is already wearing the maximum number of attachments, the object will remain on the ground with the target agent as owner. Scripters may wish to do one or more workarounds:
- check for successful attachment and llDie() after a timeout or if the object is manipulated while unattached
- check llGetObjectDetails(avatarKey, [OBJECT_ATTACHED_SLOTS_AVAILABLE]) beforehand, and avoid attaching if zero slots available
Examples
//-- rez object on ground, drop in this script, it will request permissions to attach,
//-- and then attach to the left hand if permission is granted. if permission is denied,
//-- then the script complains.
default
{
state_entry()
{
llRequestPermissions( llGetOwner(), PERMISSION_ATTACH );
}
run_time_permissions( integer vBitPermissions )
{
if( vBitPermissions & PERMISSION_ATTACH )
{
llAttachToAvatarTemp( ATTACH_LHAND );
}
else
{
llOwnerSay( "Permission to attach denied" );
}
}
on_rez(integer rez)
{
if(!llGetAttached())
{ //reset the script if it's not attached.
llResetScript();
}
}
attach(key AvatarKey)
{
if(AvatarKey)
{//event is called on both attach and detach, but Key is only valid on attach
integer test = llGetAttached();
if (test) {
llOwnerSay( "The object is attached" );
} else {
llOwnerSay( "The object is not attached");
}
}
}
}//-- This example can demonstrate ownership transfer of an object on a temporary basis using llAttachToAvatarTemp()
//-- Whoever touches will be asked for permission to attach, and upon granting permission will have the item attach,
//-- But not appear in Inventory.
default
{
touch_start(integer num_touches)
{
llRequestPermissions( llDetectedKey(0), PERMISSION_ATTACH );
}
run_time_permissions( integer vBitPermissions )
{
if( vBitPermissions & PERMISSION_ATTACH )
{
llAttachToAvatarTemp( ATTACH_LHAND );
}
else
{
llOwnerSay( "Permission to attach denied" );
}
}
on_rez(integer rez)
{
if(!llGetAttached())
{ //reset the script if it's not attached.
llResetScript();
}
}
}// This example illustrates how to handle permissions before and after llAttachToAvatarTemp has been called. Because ownership
// changes when the object is attached, the initial PERMISSION_ATTACH is revoked, and new permissions need to be requested.
integer gAttach = TRUE;
default
{
touch_start(integer num)
{
if (gAttach) // Object has not been attached yet
{
llRequestPermissions(llDetectedKey(0),PERMISSION_ATTACH);
gAttach = FALSE;
}
else // Object has been attached, but you still need PERMISSION_ATTACH in order to detach the object
{
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION | PERMISSION_ATTACH)
{
llDetachFromAvatar(); // Note that the object vanishes when detached, so there is no need to set gAttach = TRUE again
}
}
}
attach(key id)
{
if (id) // Object has been attached, so request permissions again
{
llRequestPermissions(id,PERMISSION_ATTACH | PERMISSION_TRIGGER_ANIMATION);
}
}
run_time_permissions (integer perm)
{
if (!gAttach) //First time
{
if (perm & PERMISSION_ATTACH)
{
gAttach = TRUE;
llAttachToAvatarTemp(ATTACH_HEAD); // Initial PERMISSION_ATTACH is revoked at this point
}
}
else // Second time
{
if (perm & PERMISSION_ATTACH | PERMISSION_TRIGGER_ANIMATION)
{
llStartAnimation(llGetInventoryName(INVENTORY_ANIMATION,0));
}
}
}
}An alternative solution:
// Because ownership changes when the object is attached, the initial PERMISSION_ATTACH is revoked, and new permissions need to be requested.
default
{
touch_start(integer num)
{
if (!llGetAttached()) llRequestPermissions( llDetectedKey(0), PERMISSION_ATTACH);
else if ( llGetPermissions() & PERMISSION_ATTACH) llDetachFromAvatar();
}
attach(key id)
{
if (id) llRequestPermissions( id, PERMISSION_ATTACH | PERMISSION_TRIGGER_ANIMATION);
}
run_time_permissions (integer perm)
{
if (!llGetAttached() && (perm & PERMISSION_ATTACH)) llAttachToAvatarTemp( ATTACH_NOSE);
if (perm & PERMISSION_TRIGGER_ANIMATION) llStartAnimation( llGetInventoryName( INVENTORY_ANIMATION, 0));
}
}See also: functions
History
Date of Release 24/07/2012
Shared wiki helpers
The original page also injects shared parameter notes, caveats or issue information through these helpers. Their conditional MediaWiki logic is not reproduced here; inspect the preserved helper source for additional material.
Original shared helper source (conditional wiki logic is not evaluated)
{{Issues|SCR-395|[[llAttachToAvatarTemp]] worn objects do not keep group name.|type=bug}}Template:LSL Function/permission
Original shared helper source (conditional wiki logic is not evaluated)
{{#if:
{{{{#if:{{#var:DEBUG_CHANNEL}}||:DEBUG_CHANNEL}}|}}
{{#vardefine:header_footnote|{{#var:header_footnote}}{{#if:{{{1|<noinclude>*</noinclude>}}}|To run this function the script must request the [[{{{1}}}]] {{#if:{{{2|}}}|or [[{{{2}}}]]}} permission with [[llRequestPermissions]]{{#ifeq:{{{grant|anyone}}}|anyone|| and it must be granted by {{{grant|anyone}}}}}.}}}}
{{#vardefine:caveats|{{#var:caveats}}{{#if:{{{1|<noinclude>*</noinclude>}}}|{{PBR}}
<div style="border: 1px dotted rgba(0,0,0,0.5);">{{Collapsible_Table/Simple|title=<h5 style="margin:0;">Permissions</h5>|table-style=width:100%;|autocollapse=*|content={{!}}<div>
* Do not depend upon the auto-grant status of permissions. '''Always''' use the [[run_time_permissions]] event.
* If the script lacks {{#if:{{{2|}}}|both the permissions [[{{{1}}}]] and [[{{{2}}}]]|the permission [[{{{1}}}]]}}, the script will shout an error on {{#var:DEBUG_CHANNEL}} and the operation fails (but the script continues to run).{{#ifeq:{{{grant|anyone<noinclude>*</noinclude>}}}|anyone||
* If [[{{{1}}}]] {{#if:{{{2|}}}|or [[{{{2}}}]]}} is granted by anyone other than {{{grant|anyone}}}, then when the function is called an error will be shouted on {{#var:DEBUG_CHANNEL}}.}}
{{{caveats|}}}{{LSL Function/permission/caveat switch|{{{1}}}}}{{#if:{{{2|}}}|{{LSL Function/permission/caveat switch|{{{2}}}}}}}</div>}}</div>}}}}
{{#vardefine:also_events|{{#var:also_events}}
{{LSL DefineRow||[[run_time_permissions]]|Permission receiving event}}}}
{{#vardefine:also_functions|{{#var:also_functions}}
{{LSL DefineRow||[[llGetPermissions]]|Get the permissions granted}}
{{LSL DefineRow||[[llGetPermissionsKey]]|Get the agent who granted permissions}}
{{LSL DefineRow||[[llRequestPermissions]]|Request permissions}}}}
{{#vardefine:also_articles|{{#var:also_articles}}
{{LSL DefineRow||[[:Category:LSL Permissions/Script|Script permissions]]|}}}}
<includeonly>{{#if:{{{nc|}}}||{{#vardefine:hidden-text|{{#var:hidden-text}}
{{#if:{{#pos:{{#var:moded}}|r}}{{#pos:{{#var:moded}}|u}}||[[Category:LSL Requires Permissions]]}}
}}}}</includeonly>
}}<noinclude>
{| {{Prettytable}}
|-{{Hl2}}
! #var
! value
|-
{{VarPair|header_footnote}}
|-
{{VarPair|caveats}}
|-
{{VarPairTable|also_events}}
|-
{{VarPairTable|also_functions}}
|-
{{VarPairTable|also_articles}}
|}
</noinclude>Original wiki source
Some wiki templates and tables need their original context. View this article on the Second Life Wiki. Technical wording and examples are retained from the source; historical guidance may differ from current behavior.