User:Clarknova Helvetic/Sit TP Positioner

From Second Life Wiki
Jump to navigation Jump to search

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.

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.

<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/w/index.php?title=User:Clarknova_Helvetic/Sit_TP_Positioner&action=submit


// 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;

}



default {

   on_rez(integer p) { llResetScript(); }
   
   state_entry() {
       
       // This ugly part turns our prim into a purple ball.
       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);
       channel = genChannel(llGetOwner() , 2 , 300 );
       
       llListen( channel , "" , NULL_KEY , "Where are you?");
       
   }
   listen(integer chan , string name , key id , string msg )
   {
       
       ////// 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]);


       //// Tell our object where we are
       llRegionSay(channel , (string)llGetRot() + "@" + (string)llGetPos()  ); 
   }
   
   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>

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.


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.

<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/w/index.php?title=User:Clarknova_Helvetic/Sit_TP_Positioner&action=submit


// 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;

}


default { touch_start(integer total_number) {

integer i;

   for (i = 0 ; i < total_number ; ++i )
   {
       if (llDetectedKey(i) == llGetOwner())   
       {
           llOwnerSay("Querying Sit Target Helper...");
           channel = genChannel(llGetOwner() , 2 , 300 );
           llListen( channel , "" , NULL_KEY , "");
           llRegionSay(channel,"Where are you?");
           llSetTimerEvent( 10. );
       }
   }

}

listen(integer chan , string name , key id , string msg ) {


   integer at = llSubStringIndex( msg, "@" );
   
   rotation helper_rot = (rotation)(llGetSubString(msg, 0, at - 1));
   vector helper_pos = (vector)(llGetSubString(msg, at + 1,-1));
   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.  You sure your Helper is in the same sim? \n Anyway, try again.");  }

}</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.


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.

<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/w/index.php?title=User:Clarknova_Helvetic/Sit_TP_Positioner&action=submit


// 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;

}


default { state_entry() { llSitTarget(ZERO_VECTOR,ZERO_ROTATION); llOwnerSay("Querying Sit Target Helper..."); channel = genChannel(llGetOwner() , 2 , 300 ); llListen( channel , "" , NULL_KEY , ""); llRegionSay(channel,"Where are you?"); llSetTimerEvent( 10. ); }

listen(integer chan , string name , key id , string msg ) {


   integer at = llSubStringIndex( msg, "@" );
   
   rotation helper_rot = (rotation)(llGetSubString(msg, 0, at - 1));
   vector helper_pos = (vector)(llGetSubString(msg, at + 1,-1));
   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.  You sure your Helper is in the same sim? \n Anyway, try again."); llRemoveInventory(llGetScriptName()); }

}</lsl>