Difference between revisions of "User:Clarknova Helvetic/Sit TP Positioner"

From Second Life Wiki
Jump to navigation Jump to search
(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 one region corner to the other.
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 ==


To get started drop the following script into a new prim.  It's your Helper prim.  You sit on it and edit it to where you want your av to be.
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/w/index.php?title=User:Clarknova_Helvetic/Sit_TP_Positioner&action=submit
// https://wiki.secondlife.com/wiki/User:Clarknova_Helvetic/Sit_TP_Positioner
 
 
// Generate a private chat channel based on key, JUSSSSSST in case 
// two people are using a sit positioner in the same sim.
integer channel;
integer genChannel(key k , integer mod, integer pin)
{  // NOTE : mod must = 1 or 2  ,  pin must be  >=  || < 500,000
    float a = (float)("0x"+llGetSubString( (string)k, mod,-1));     
    integer b =  llRound( llFabs(a) - a*2 + pin );         
    return b;
}
 




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);
        channel = genChannel(llGetOwner() , 2 , 300 );
 
       
         llListen( -13374138 , "" , NULL_KEY , "Ping?");
         llListen( channel , "" , NULL_KEY , "Where are you?");
          
          
     }
     }
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:




         //// Tell our object where we are
         //// Pong!
         llRegionSay(channel , (string)llGetRot() + "@" + (string)llGetPos() );  
         llRegionSay(-13374137 , "Pong!"  );  
        }
     }
     }
      
      
Line 85: Line 102:
}</lsl>
}</lsl>


If you actually read that you'll see that you can also stick an animation in the helper prim and it'll play it while you sit.   
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.  It sets the sit target of the prim to be exactly where your av is sitting on the helper.   
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/w/index.php?title=User:Clarknova_Helvetic/Sit_TP_Positioner&action=submit
// https://wiki.secondlife.com/wiki/User:Clarknova_Helvetic/Sit_TP_Positioner


key owner;


// Generate a private chat channel based on key, JUSSSSSST in case 
default
// two people are using a sit positioner in the same sim.
{
integer channel;
integer genChannel(key k , integer mod, integer pin)
{ // NOTE : mod must = 1 or 2  ,  pin must be  >= 1  or < 500,000
    float a = (float)("0x"+llGetSubString( (string)k, mod,-1));     
    integer b =  llRound( llFabs(a) - a*2 + pin );         
    return b;
}


state_entry() { owner = llGetOwner(); }


default
{
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...");
            channel = genChannel(llGetOwner() , 2 , 300 );
             llListen( -13374137 , "" , NULL_KEY , "Pong!");
             llListen( channel , "" , NULL_KEY , "");
             llRegionSay(-13374138,"Ping?");
             llRegionSay(channel,"Where are you?");
             llSetTimerEvent( 10. );
             llSetTimerEvent( 10. );
         }
         }
     }
     }
}
}
 
listen(integer chan , string name , key id , string msg )
listen(integer chan , string name , key id , string msg )
{
{
      
      
     integer at = llSubStringIndex( msg, "@" );
     list details = llGetObjectDetails(id,[OBJECT_OWNER,OBJECT_POS,OBJECT_ROT]);
      
      
     rotation helper_rot = (rotation)(llGetSubString(msg, 0, at - 1));
     if ( llList2Key(details,0) == owner )
     vector helper_pos = (vector)(llGetSubString(msg, at + 1,-1));
    {
     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 {
     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.  You sure your Helper is in the same sim? \n Anyway, try again."); }
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>
If successful, particles will flow from your Helper to the chair prim.  If your target is too far away, or not in the same region, you'll be warned instead.


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 thing 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.
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/w/index.php?title=User:Clarknova_Helvetic/Sit_TP_Positioner&action=submit
// https://wiki.secondlife.com/wiki/User:Clarknova_Helvetic/Sit_TP_Positioner
 
 
// Generate a private chat channel based on key, JUSSSSSST in case 
// two people are using a sit positioner in the same sim.
integer channel;
integer genChannel(key k , integer mod, integer pin)
{  // NOTE : mod must = 1 or 2  ,  pin must be  >= 1  or < 500,000
    float a = (float)("0x"+llGetSubString( (string)k, mod,-1));     
    integer b =  llRound( llFabs(a) - a*2 + pin );         
    return b;
}


key owner;


default
default
{
{
state_entry() {
state_entry() {
llSitTarget(ZERO_VECTOR,ZERO_ROTATION);
owner = llGetOwner();
llOwnerSay("Querying Sit Target Helper...");
llOwnerSay("Querying Sit Target Helper...");
channel = genChannel(llGetOwner() , 2 , 300 );
llListen( -13374137 , "" , NULL_KEY , "Pong!");
llListen( channel , "" , NULL_KEY , "");
llRegionSay(-13374138,"Ping?");
llRegionSay(channel,"Where are you?");
llSetTimerEvent( 10. );
llSetTimerEvent( 10. );
}
}
Line 233: Line 281:


      
      
     integer at = llSubStringIndex( msg, "@" );
     list details = llGetObjectDetails(id,[OBJECT_OWNER,OBJECT_POS,OBJECT_ROT]);
      
      
     rotation helper_rot = (rotation)(llGetSubString(msg, 0, at - 1));
     if ( llList2Key(details,0) == owner )
     vector helper_pos = (vector)(llGetSubString(msg, at + 1,-1));
    {
     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.) {
Line 269: Line 322:
      
      
     llRemoveInventory(llGetScriptName());
     llRemoveInventory(llGetScriptName());
    }
}
}


Line 285: Line 339:
     }
     }
}
}
    timer() { llOwnerSay("Query timed out.  You sure your Helper is in the same sim? \n Anyway, try again."); llRemoveInventory(llGetScriptName()); }
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>