Difference between revisions of "User:Clarknova Helvetic/Sit TP Positioner"
m (→Target setter - drag 'n drop: asdf) |
(updated to add sensor fallback) |
||
Line 1: | Line 1: | ||
This set of scripts is for making perfect sit targets. It was first written by Lex Neva and heavily abused by me to adapt it for 300m sit-teleport support. You can use it for a sit target just 2cm away, or for from | This set of scripts is for making perfect sit targets. It was first written by Lex Neva and heavily abused by me to adapt it for 300m sit-teleport support. You can use it for a sit target just 2cm away, or for from region corner to corner. | ||
== Behavior == | |||
The sit target setter comes in two parts: the ''Helper'' object and the ''Setter'' script. | |||
<ul> | |||
<li> First you sit on the ''Helper''. If you have an animation to align, put the anim in the Helper before sitting. </li> | |||
<li> After moving the Helper so your avatar is aligned and rotated properly, Put the ''Setter'' script into your chair or teleport object. </li> | |||
<li> First the Setter broadcasts a region-wide message. When the Helper replies, it sets the target. The Helper also draws a line of particles to the chair. </li> | |||
<li> If the Helper is too far away, the Setter warns you and tells you how many meters too far. </li> | |||
<li> If the Helper doesn't reply, the Setter script tries to find it by sensor instead. This is useful if your teleport offset needs to be over no-script land. </li> | |||
<li> If the Setter can't find the Helper at all, it tells you and gives you a list of possible reasons. </li> | |||
</ul> | |||
An unlimited number of builders can use their own copy simultaneously. They will never interfere. | |||
There are two flavors of Setter script: ''touch_start'' and ''drag 'n drop''. The touch_start sets a new sit target each time the chair is touched. You must remove this script manually. The drag 'n drop Setter sets the sit target and then removes from object inventory. | |||
== Helper script == | == Helper script == | ||
Drop this script into a new box prim. It transforms the prim into the Helper. | |||
<lsl>// Sit target system by Lex Neva. Please distribute willy-nilly. | <lsl>// Sit target system by Lex Neva. Please distribute willy-nilly. | ||
Line 12: | Line 38: | ||
// Support for Teleport-range setting shoehorned in by Clarknova Helvetic | // Support for Teleport-range setting shoehorned in by Clarknova Helvetic | ||
// https://wiki.secondlife.com/ | // https://wiki.secondlife.com/wiki/User:Clarknova_Helvetic/Sit_TP_Positioner | ||
Line 34: | Line 48: | ||
state_entry() { | state_entry() { | ||
// This ugly part turns our prim into a purple ball. | // This ugly part turns our prim into a purple ball with the right name. | ||
llSetPrimitiveParams([PRIM_TYPE,3,0,<0.000000, 1.000000, 0.000000>,0.000000,<0.000000, 0.000000, 0.000000>,<0.000000, 1.000000, 0.000000> , PRIM_POINT_LIGHT,0,<1.000000, 1.000000, 1.000000>,1.000000,10.000000,0.750000 , PRIM_COLOR,0,<0.729412, 0.160784, 0.717647>,1.000000 , PRIM_BUMP_SHINY,0,1,0 ]); | llSetPrimitiveParams([PRIM_TYPE,3,0,<0.000000, 1.000000, 0.000000>,0.000000,<0.000000, 0.000000, 0.000000>,<0.000000, 1.000000, 0.000000> , PRIM_POINT_LIGHT,0,<1.000000, 1.000000, 1.000000>,1.000000,10.000000,0.750000 , PRIM_COLOR,0,<0.729412, 0.160784, 0.717647>,1.000000 , PRIM_BUMP_SHINY,0,1,0 ]); | ||
llSetPrimitiveParams([PRIM_ROTATION,<0.000000, 0.000000, 0.000000, 1.000000> , PRIM_TEXTURE,0,"5748decc-f629-461c-9a36-a35a221fe21f",<1.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,0.000000 , PRIM_SIZE,<0.250000, 0.250000, 0.250000> ]); | llSetPrimitiveParams([PRIM_ROTATION,<0.000000, 0.000000, 0.000000, 1.000000> , PRIM_TEXTURE,0,"5748decc-f629-461c-9a36-a35a221fe21f",<1.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,0.000000 , PRIM_SIZE,<0.250000, 0.250000, 0.250000> ]); | ||
Line 42: | Line 56: | ||
llParticleSystem([]); | llParticleSystem([]); | ||
llSitTarget(<0,0,1>, ZERO_ROTATION); | llSitTarget(<0,0,1>, ZERO_ROTATION); | ||
llListen( -13374138 , "" , NULL_KEY , "Ping?"); | |||
llListen( | |||
} | } | ||
Line 50: | Line 63: | ||
listen(integer chan , string name , key id , string msg ) | listen(integer chan , string name , key id , string msg ) | ||
{ | { | ||
if (llList2Key(llGetObjectDetails(id,[OBJECT_OWNER]),0) == llGetOwner() ) | |||
{ | |||
////// Some neat particles to show the link line :) | ////// Some neat particles to show the link line :) | ||
Line 62: | Line 78: | ||
//// | //// Pong! | ||
llRegionSay( | llRegionSay(-13374137 , "Pong!" ); | ||
} | |||
} | } | ||
Line 85: | Line 102: | ||
}</lsl> | }</lsl> | ||
Make sure you stick your animation in the helper prim before you sit. | |||
== Target Setter (on touch) == | == Target Setter (on touch) == | ||
Next drop this script into your chair or teleport pad or whatever. Then touch | Next drop this script into your chair or teleport pad or whatever. Then touch. | ||
<lsl>// Sit target system by Lex Neva. Please distribute willy-nilly. | <lsl>// Sit target system by Lex Neva. Please distribute willy-nilly. | ||
// http://forums.secondlife.com/showthread.php?t=153278&highlight=target | // http://forums.secondlife.com/showthread.php?t=153278&highlight=target | ||
// Sit target setting script. Sets on touch. | // Sit target setting script. Sets on touch. | ||
// Support for Teleport-range setting shoehorned in by Clarknova Helvetic | // Support for Teleport-range setting shoehorned in by Clarknova Helvetic | ||
// https://wiki.secondlife.com/ | // https://wiki.secondlife.com/wiki/User:Clarknova_Helvetic/Sit_TP_Positioner | ||
key owner; | |||
default | |||
{ | |||
{ | |||
state_entry() { owner = llGetOwner(); } | |||
touch_start(integer total_number) { | touch_start(integer total_number) { | ||
integer i; | integer i; | ||
for (i = 0 ; i < total_number ; ++i ) | for (i = 0 ; i < total_number ; ++i ) | ||
Line 122: | Line 134: | ||
{ | { | ||
llOwnerSay("Querying Sit Target Helper..."); | llOwnerSay("Querying Sit Target Helper..."); | ||
llListen( -13374137 , "" , NULL_KEY , "Pong!"); | |||
llListen( | llRegionSay(-13374138,"Ping?"); | ||
llRegionSay( | |||
llSetTimerEvent( 10. ); | llSetTimerEvent( 10. ); | ||
} | } | ||
} | } | ||
} | } | ||
listen(integer chan , string name , key id , string msg ) | listen(integer chan , string name , key id , string msg ) | ||
{ | { | ||
list details = llGetObjectDetails(id,[OBJECT_OWNER,OBJECT_POS,OBJECT_ROT]); | |||
if ( llList2Key(details,0) == owner ) | |||
vector helper_pos = ( | { | ||
vector helper_pos = llList2Vector(details,1); | |||
rotation helper_rot = llList2Rot(details,2); | |||
vector my_pos = llGetPos(); | vector my_pos = llGetPos(); | ||
rotation my_rot = llGetRot(); | rotation my_rot = llGetRot(); | ||
float distance = llVecDist(my_pos,helper_pos); | float distance = llVecDist(my_pos,helper_pos); | ||
vector target_pos = ZERO_VECTOR; | vector target_pos = ZERO_VECTOR; | ||
if ( distance > 300.) { | if ( distance > 300.) { | ||
llOwnerSay("Sit target is " + (string)(distance - 300.) + "m too far away! \n( if you lost your Helper it's at " + (string)helper_pos +" )"); | llOwnerSay("Sit target is " + (string)(distance - 300.) + "m too far away! \n( if you lost your Helper it's at " + (string)helper_pos +" )"); | ||
} | } | ||
else | |||
{ | |||
// calculate where the avatar actually is | // calculate where the avatar actually is | ||
vector avatar_pos = helper_pos + <0,0,1> * helper_rot; // due to helper's sit target | vector avatar_pos = helper_pos + <0,0,1> * helper_rot; // due to helper's sit target | ||
avatar_pos = avatar_pos - <0,0,0.186> + <0,0,0.4> * helper_rot; // correct for a bug in llSitTarget(), for helper sit target | avatar_pos = avatar_pos - <0,0,0.186> + <0,0,0.4> * helper_rot; // correct for a bug in llSitTarget(), for helper sit target | ||
target_pos = (avatar_pos - my_pos) / my_rot; | target_pos = (avatar_pos - my_pos) / my_rot; | ||
target_pos = target_pos + <0,0,0.186>/my_rot - <0,0,0.4>; // correct for the bug again, this time in my sit target | target_pos = target_pos + <0,0,0.186>/my_rot - <0,0,0.4>; // correct for the bug again, this time in my sit target | ||
rotation target_rot = helper_rot / my_rot; | rotation target_rot = helper_rot / my_rot; | ||
llSitTarget(target_pos, target_rot); | llSitTarget(target_pos, target_rot); | ||
llOwnerSay("llSitTarget(" + (string)target_pos + ", " + (string)target_rot + ");"); | llOwnerSay("llSitTarget(" + (string)target_pos + ", " + (string)target_rot + ");"); | ||
} | } | ||
llSetTimerEvent(0.); | llSetTimerEvent(0.); | ||
} | |||
} | } | ||
changed(integer change) { | changed(integer change) { | ||
if (llAvatarOnSitTarget() != NULL_KEY) | if (llAvatarOnSitTarget() != NULL_KEY) | ||
llRequestPermissions(llAvatarOnSitTarget(), PERMISSION_TRIGGER_ANIMATION); | llRequestPermissions(llAvatarOnSitTarget(), PERMISSION_TRIGGER_ANIMATION); | ||
} | } | ||
run_time_permissions(integer perm) { | run_time_permissions(integer perm) { | ||
string anim = llGetInventoryName(INVENTORY_ANIMATION, 0); | string anim = llGetInventoryName(INVENTORY_ANIMATION, 0); | ||
Line 185: | Line 203: | ||
} | } | ||
} | } | ||
timer() { | |||
llOwnerSay("Query timed out. Now trying by sensor..."); | |||
llSensor("Sit Target/Teleport Helper",NULL_KEY,SCRIPTED,96,PI); | |||
} | |||
sensor(integer num) { | |||
integer i; | |||
for ( i = 0 ; i < num ; ++i) | |||
{ | |||
if ( llList2Key(llGetObjectDetails(llDetectedKey(i),[OBJECT_OWNER]),0) == owner ) | |||
{ | |||
rotation helper_rot = llDetectedRot(i); | |||
vector helper_pos = llDetectedPos(i); | |||
vector my_pos = llGetPos(); | |||
rotation my_rot = llGetRot(); | |||
float distance = llVecDist(my_pos,helper_pos); | |||
vector target_pos = ZERO_VECTOR; | |||
// calculate where the avatar actually is | |||
vector avatar_pos = helper_pos + <0,0,1> * helper_rot; // due to helper's sit target | |||
avatar_pos = avatar_pos - <0,0,0.186> + <0,0,0.4> * helper_rot; // correct for a bug in llSitTarget(), for helper sit target | |||
target_pos = (avatar_pos - my_pos) / my_rot; | |||
target_pos = target_pos + <0,0,0.186>/my_rot - <0,0,0.4>; // correct for the bug again, this time in my sit target | |||
rotation target_rot = helper_rot / my_rot; | |||
llSitTarget(target_pos, target_rot); | |||
llOwnerSay("Sit target set by sensor. Helper's probbaly in a no-script parcel.\nllSitTarget(" + (string)target_pos + ", " + (string)target_rot + ");"); | |||
} | |||
} | |||
llSetTimerEvent(0.); | |||
} | |||
no_sensor() { | |||
llOwnerSay("Can't find helper! Problem could be:\nA) Helper's in no-script parcel and further away than 96m\nB) Helper's in another sim\nC) Laaaaaaaaaaag!\n\tAnyway, try again!"); | |||
llSetTimerEvent(0.); | |||
} | |||
}</lsl> | }</lsl> | ||
Adjust and touch as many times as you need. Remember to remove the script when done. | Adjust and touch as many times as you need. Remember to remove the script when done. | ||
Line 195: | Line 254: | ||
== Target setter (drag 'n drop) == | == Target setter (drag 'n drop) == | ||
This script does the same | This script does the same as the one above. The difference is that once you drag the script in your chair it sets the target and deletes from prim inventory. Fire and forget. | ||
<lsl>// Sit target system by Lex Neva. Please distribute willy-nilly. | <lsl>// Sit target system by Lex Neva. Please distribute willy-nilly. | ||
Line 204: | Line 263: | ||
// Support for Teleport-range setting shoehorned in by Clarknova Helvetic | // Support for Teleport-range setting shoehorned in by Clarknova Helvetic | ||
// Drag 'n drop adaptation also by CH. I like doing things this way :) | // Drag 'n drop adaptation also by CH. I like doing things this way :) | ||
// https://wiki.secondlife.com/ | // https://wiki.secondlife.com/wiki/User:Clarknova_Helvetic/Sit_TP_Positioner | ||
key owner; | |||
default | default | ||
{ | { | ||
state_entry() { | state_entry() { | ||
owner = llGetOwner(); | |||
llOwnerSay("Querying Sit Target Helper..."); | llOwnerSay("Querying Sit Target Helper..."); | ||
llListen( -13374137 , "" , NULL_KEY , "Pong!"); | |||
llListen( | llRegionSay(-13374138,"Ping?"); | ||
llRegionSay( | |||
llSetTimerEvent( 10. ); | llSetTimerEvent( 10. ); | ||
} | } | ||
Line 233: | Line 281: | ||
list details = llGetObjectDetails(id,[OBJECT_OWNER,OBJECT_POS,OBJECT_ROT]); | |||
if ( llList2Key(details,0) == owner ) | |||
vector helper_pos = ( | { | ||
vector helper_pos = llList2Vector(details,1); | |||
rotation helper_rot = llList2Rot(details,2); | |||
vector my_pos = llGetPos(); | vector my_pos = llGetPos(); | ||
rotation my_rot = llGetRot(); | rotation my_rot = llGetRot(); | ||
float distance = llVecDist(my_pos,helper_pos); | float distance = llVecDist(my_pos,helper_pos); | ||
vector target_pos = ZERO_VECTOR; | |||
if ( distance > 300.) { | if ( distance > 300.) { | ||
Line 269: | Line 322: | ||
llRemoveInventory(llGetScriptName()); | llRemoveInventory(llGetScriptName()); | ||
} | |||
} | } | ||
Line 285: | Line 339: | ||
} | } | ||
} | } | ||
timer() { | |||
llOwnerSay("Query timed out. Now trying by sensor..."); | |||
llSensor("Sit Target/Teleport Helper",NULL_KEY,SCRIPTED,96,PI); | |||
} | |||
sensor(integer num) { | |||
integer i; | |||
for ( i = 0 ; i < num ; ++i) | |||
{ | |||
if ( llList2Key(llGetObjectDetails(llDetectedKey(i),[OBJECT_OWNER]),0) == owner ) | |||
{ | |||
rotation helper_rot = llDetectedRot(i); | |||
vector helper_pos = llDetectedPos(i); | |||
vector my_pos = llGetPos(); | |||
rotation my_rot = llGetRot(); | |||
float distance = llVecDist(my_pos,helper_pos); | |||
vector target_pos = ZERO_VECTOR; | |||
// calculate where the avatar actually is | |||
vector avatar_pos = helper_pos + <0,0,1> * helper_rot; // due to helper's sit target | |||
avatar_pos = avatar_pos - <0,0,0.186> + <0,0,0.4> * helper_rot; // correct for a bug in llSitTarget(), for helper sit target | |||
target_pos = (avatar_pos - my_pos) / my_rot; | |||
target_pos = target_pos + <0,0,0.186>/my_rot - <0,0,0.4>; // correct for the bug again, this time in my sit target | |||
rotation target_rot = helper_rot / my_rot; | |||
llSitTarget(target_pos, target_rot); | |||
llOwnerSay("Sit target set by sensor. Helper's probbaly in a no-script parcel.\nllSitTarget(" + (string)target_pos + ", " + (string)target_rot + ");"); | |||
} | |||
} | |||
llRemoveInventory(llGetScriptName()); | |||
} | |||
no_sensor() { | |||
llOwnerSay("Can't find helper! Problem could be:\nA) Helper's in no-script parcel and further away than 96m\nB) Helper's in another sim\nC) Laaaaaaaaaaag!\n\tAnyway, try again!"); | |||
llRemoveInventory(llGetScriptName()); | |||
} | |||
}</lsl> | }</lsl> |
Latest revision as of 20:36, 24 January 2008
This set of scripts is for making perfect sit targets. It was first written by Lex Neva and heavily abused by me to adapt it for 300m sit-teleport support. You can use it for a sit target just 2cm away, or for from region corner to corner.
Behavior
The sit target setter comes in two parts: the Helper object and the Setter script.
- First you sit on the Helper. If you have an animation to align, put the anim in the Helper before sitting.
- After moving the Helper so your avatar is aligned and rotated properly, Put the Setter script into your chair or teleport object.
- First the Setter broadcasts a region-wide message. When the Helper replies, it sets the target. The Helper also draws a line of particles to the chair.
- If the Helper is too far away, the Setter warns you and tells you how many meters too far.
- If the Helper doesn't reply, the Setter script tries to find it by sensor instead. This is useful if your teleport offset needs to be over no-script land.
- If the Setter can't find the Helper at all, it tells you and gives you a list of possible reasons.
An unlimited number of builders can use their own copy simultaneously. They will never interfere.
There are two flavors of Setter script: touch_start and drag 'n drop. The touch_start sets a new sit target each time the chair is touched. You must remove this script manually. The drag 'n drop Setter sets the sit target and then removes from object inventory.
Helper script
Drop this script into a new box prim. It transforms the prim into the Helper.
<lsl>// Sit target system by Lex Neva. Please distribute willy-nilly. // http://forums.secondlife.com/showthread.php?t=153278&highlight=target
// Helper prim script
// Support for Teleport-range setting shoehorned in by Clarknova Helvetic
// https://wiki.secondlife.com/wiki/User:Clarknova_Helvetic/Sit_TP_Positioner
default {
on_rez(integer p) { llResetScript(); } state_entry() { // This ugly part turns our prim into a purple ball with the right name. llSetPrimitiveParams([PRIM_TYPE,3,0,<0.000000, 1.000000, 0.000000>,0.000000,<0.000000, 0.000000, 0.000000>,<0.000000, 1.000000, 0.000000> , PRIM_POINT_LIGHT,0,<1.000000, 1.000000, 1.000000>,1.000000,10.000000,0.750000 , PRIM_COLOR,0,<0.729412, 0.160784, 0.717647>,1.000000 , PRIM_BUMP_SHINY,0,1,0 ]); llSetPrimitiveParams([PRIM_ROTATION,<0.000000, 0.000000, 0.000000, 1.000000> , PRIM_TEXTURE,0,"5748decc-f629-461c-9a36-a35a221fe21f",<1.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,0.000000 , PRIM_SIZE,<0.250000, 0.250000, 0.250000> ]); // Ugly all done :) llParticleSystem([]); llSitTarget(<0,0,1>, ZERO_ROTATION);
llListen( -13374138 , "" , NULL_KEY , "Ping?"); }
listen(integer chan , string name , key id , string msg ) { if (llList2Key(llGetObjectDetails(id,[OBJECT_OWNER]),0) == llGetOwner() ) { ////// Some neat particles to show the link line :) // // Calculate the lifespan of the particles so they don't move to fast vector start_scale = <.2,.4,.0>; vector end_scale = <.25,.45,.0>; float part_age = .3 * (llVecDist(llList2Vector(llGetObjectDetails(id,[OBJECT_POS]),0),llGetPos())); if (part_age > 30.) { vector mod = < 0., (part_age / 30.), 0.>; part_age = 30.; start_scale = start_scale + mod; end_scale = end_scale + mod; } // Generate the particles llParticleSystem([2,1.0,4,1.0,1,<0.847059, 0.301961, 0.835294>,3,<0.729412, 0.160784, 0.717647>,5,start_scale,6,end_scale,19,0.0,7,part_age,13,0.0,15,10,9,2,8,<75.0,0.0,0.0>,0,483,20,id]);
//// Pong! llRegionSay(-13374137 , "Pong!" ); } }
changed(integer change) { if (llAvatarOnSitTarget() != NULL_KEY) llRequestPermissions(llAvatarOnSitTarget(), PERMISSION_TRIGGER_ANIMATION); }
run_time_permissions(integer perm) { string anim = llGetInventoryName(INVENTORY_ANIMATION, 0); if (anim != "") { llStopAnimation("sit"); llStopAnimation("sit_generic"); llStopAnimation("sit_female"); llStartAnimation(anim); } }
}</lsl>
Make sure you stick your animation in the helper prim before you sit.
Target Setter (on touch)
Next drop this script into your chair or teleport pad or whatever. Then touch.
<lsl>// Sit target system by Lex Neva. Please distribute willy-nilly. // http://forums.secondlife.com/showthread.php?t=153278&highlight=target
// Sit target setting script. Sets on touch.
// Support for Teleport-range setting shoehorned in by Clarknova Helvetic // https://wiki.secondlife.com/wiki/User:Clarknova_Helvetic/Sit_TP_Positioner
key owner;
default {
state_entry() { owner = llGetOwner(); }
touch_start(integer total_number) {
integer i;
for (i = 0 ; i < total_number ; ++i ) { if (llDetectedKey(i) == llGetOwner()) { llOwnerSay("Querying Sit Target Helper..."); llListen( -13374137 , "" , NULL_KEY , "Pong!"); llRegionSay(-13374138,"Ping?"); llSetTimerEvent( 10. ); } }
}
listen(integer chan , string name , key id , string msg ) {
list details = llGetObjectDetails(id,[OBJECT_OWNER,OBJECT_POS,OBJECT_ROT]); if ( llList2Key(details,0) == owner ) { vector helper_pos = llList2Vector(details,1); rotation helper_rot = llList2Rot(details,2);
vector my_pos = llGetPos(); rotation my_rot = llGetRot(); float distance = llVecDist(my_pos,helper_pos); vector target_pos = ZERO_VECTOR; if ( distance > 300.) { llOwnerSay("Sit target is " + (string)(distance - 300.) + "m too far away! \n( if you lost your Helper it's at " + (string)helper_pos +" )"); } else { // calculate where the avatar actually is vector avatar_pos = helper_pos + <0,0,1> * helper_rot; // due to helper's sit target avatar_pos = avatar_pos - <0,0,0.186> + <0,0,0.4> * helper_rot; // correct for a bug in llSitTarget(), for helper sit target target_pos = (avatar_pos - my_pos) / my_rot; target_pos = target_pos + <0,0,0.186>/my_rot - <0,0,0.4>; // correct for the bug again, this time in my sit target rotation target_rot = helper_rot / my_rot; llSitTarget(target_pos, target_rot); llOwnerSay("llSitTarget(" + (string)target_pos + ", " + (string)target_rot + ");"); } llSetTimerEvent(0.); }
}
changed(integer change) { if (llAvatarOnSitTarget() != NULL_KEY) llRequestPermissions(llAvatarOnSitTarget(), PERMISSION_TRIGGER_ANIMATION); }
run_time_permissions(integer perm) { string anim = llGetInventoryName(INVENTORY_ANIMATION, 0); if (anim != "") { llStopAnimation("sit"); llStopAnimation("sit_generic"); llStopAnimation("sit_female"); llStartAnimation(anim);
}
} timer() {
llOwnerSay("Query timed out. Now trying by sensor..."); llSensor("Sit Target/Teleport Helper",NULL_KEY,SCRIPTED,96,PI);
} sensor(integer num) {
integer i; for ( i = 0 ; i < num ; ++i) {
if ( llList2Key(llGetObjectDetails(llDetectedKey(i),[OBJECT_OWNER]),0) == owner ) { rotation helper_rot = llDetectedRot(i); vector helper_pos = llDetectedPos(i); vector my_pos = llGetPos(); rotation my_rot = llGetRot(); float distance = llVecDist(my_pos,helper_pos); vector target_pos = ZERO_VECTOR; // calculate where the avatar actually is vector avatar_pos = helper_pos + <0,0,1> * helper_rot; // due to helper's sit target avatar_pos = avatar_pos - <0,0,0.186> + <0,0,0.4> * helper_rot; // correct for a bug in llSitTarget(), for helper sit target target_pos = (avatar_pos - my_pos) / my_rot; target_pos = target_pos + <0,0,0.186>/my_rot - <0,0,0.4>; // correct for the bug again, this time in my sit target rotation target_rot = helper_rot / my_rot; llSitTarget(target_pos, target_rot); llOwnerSay("Sit target set by sensor. Helper's probbaly in a no-script parcel.\nllSitTarget(" + (string)target_pos + ", " + (string)target_rot + ");"); } } llSetTimerEvent(0.);
} no_sensor() {
llOwnerSay("Can't find helper! Problem could be:\nA) Helper's in no-script parcel and further away than 96m\nB) Helper's in another sim\nC) Laaaaaaaaaaag!\n\tAnyway, try again!"); llSetTimerEvent(0.); }
}</lsl>
Adjust and touch as many times as you need. Remember to remove the script when done.
Target setter (drag 'n drop)
This script does the same as the one above. The difference is that once you drag the script in your chair it sets the target and deletes from prim inventory. Fire and forget.
<lsl>// Sit target system by Lex Neva. Please distribute willy-nilly. // http://forums.secondlife.com/showthread.php?t=153278&highlight=target
// Sit target setting script. Drag -n- drop version.
// Support for Teleport-range setting shoehorned in by Clarknova Helvetic // Drag 'n drop adaptation also by CH. I like doing things this way :) // https://wiki.secondlife.com/wiki/User:Clarknova_Helvetic/Sit_TP_Positioner
key owner;
default { state_entry() { owner = llGetOwner(); llOwnerSay("Querying Sit Target Helper..."); llListen( -13374137 , "" , NULL_KEY , "Pong!"); llRegionSay(-13374138,"Ping?"); llSetTimerEvent( 10. ); }
listen(integer chan , string name , key id , string msg ) {
list details = llGetObjectDetails(id,[OBJECT_OWNER,OBJECT_POS,OBJECT_ROT]); if ( llList2Key(details,0) == owner ) { vector helper_pos = llList2Vector(details,1); rotation helper_rot = llList2Rot(details,2);
vector my_pos = llGetPos(); rotation my_rot = llGetRot(); float distance = llVecDist(my_pos,helper_pos); vector target_pos = ZERO_VECTOR; if ( distance > 300.) { llOwnerSay("Sit target is " + (string)(distance - 300.) + "m too far away! \n( if you lost your Helper it's at " + (string)helper_pos +" )"); } else {
// calculate where the avatar actually is vector avatar_pos = helper_pos + <0,0,1> * helper_rot; // due to helper's sit target avatar_pos = avatar_pos - <0,0,0.186> + <0,0,0.4> * helper_rot; // correct for a bug in llSitTarget(), for helper sit target
target_pos = (avatar_pos - my_pos) / my_rot; target_pos = target_pos + <0,0,0.186>/my_rot - <0,0,0.4>; // correct for the bug again, this time in my sit target rotation target_rot = helper_rot / my_rot; llSitTarget(target_pos, target_rot); llOwnerSay("llSitTarget(" + (string)target_pos + ", " + (string)target_rot + ");"); } llRemoveInventory(llGetScriptName()); }
}
changed(integer change) { if (llAvatarOnSitTarget() != NULL_KEY) llRequestPermissions(llAvatarOnSitTarget(), PERMISSION_TRIGGER_ANIMATION); }
run_time_permissions(integer perm) { string anim = llGetInventoryName(INVENTORY_ANIMATION, 0); if (anim != "") { llStopAnimation("sit"); llStopAnimation("sit_generic"); llStopAnimation("sit_female"); llStartAnimation(anim);
}
} timer() {
llOwnerSay("Query timed out. Now trying by sensor..."); llSensor("Sit Target/Teleport Helper",NULL_KEY,SCRIPTED,96,PI);
} sensor(integer num) {
integer i; for ( i = 0 ; i < num ; ++i) {
if ( llList2Key(llGetObjectDetails(llDetectedKey(i),[OBJECT_OWNER]),0) == owner ) { rotation helper_rot = llDetectedRot(i); vector helper_pos = llDetectedPos(i); vector my_pos = llGetPos(); rotation my_rot = llGetRot(); float distance = llVecDist(my_pos,helper_pos); vector target_pos = ZERO_VECTOR; // calculate where the avatar actually is vector avatar_pos = helper_pos + <0,0,1> * helper_rot; // due to helper's sit target avatar_pos = avatar_pos - <0,0,0.186> + <0,0,0.4> * helper_rot; // correct for a bug in llSitTarget(), for helper sit target target_pos = (avatar_pos - my_pos) / my_rot; target_pos = target_pos + <0,0,0.186>/my_rot - <0,0,0.4>; // correct for the bug again, this time in my sit target rotation target_rot = helper_rot / my_rot; llSitTarget(target_pos, target_rot); llOwnerSay("Sit target set by sensor. Helper's probbaly in a no-script parcel.\nllSitTarget(" + (string)target_pos + ", " + (string)target_rot + ");"); } } llRemoveInventory(llGetScriptName());
} no_sensor() {
llOwnerSay("Can't find helper! Problem could be:\nA) Helper's in no-script parcel and further away than 96m\nB) Helper's in another sim\nC) Laaaaaaaaaaag!\n\tAnyway, try again!"); llRemoveInventory(llGetScriptName()); }
}</lsl>