Follower script

From Second Life Wiki
Revision as of 01:01, 24 June 2012 by Zelena DeCuir (Talk | contribs)

Jump to: navigation, search

This script is based on an extract from the Batman Follower v1.2. It is very basic. If you put it in an object, that object will keep moving toward a position offset from it's owner.

<lsl>

vector offset = < -1, 0, 1>; //1 meter behind and 1 meter above owner's center.

default {

   state_entry()
   {
       llSetStatus(STATUS_PHYSICS, TRUE);
       // Little pause to allow server to make potentially large linked object physical.
       llSleep(0.1);
       // Look for owner within 20 metres in 360 degree arc every 1 seconds.
       llSensorRepeat("", llGetOwner(), AGENT, 20.0, PI,1.0);
   }
   sensor(integer total_number)
   {   // Owner detected...
       // Get position and rotation
       vector pos   = llDetectedPos(0);
       rotation rot = llDetectedRot(0);
       // Offset back one metre in X and up one metre in Z based on world coordinates.
       // use whatever offset you want.
       vector worldOffset = offset;
       // Offset relative to owner needs a quaternion.
       vector avOffset = offset * rot;
       pos += avOffset;       // use the one you want, world or relative to AV.
       llMoveToTarget(pos,0.4);     
   }

} </lsl> <lsl> //adding this script as a less laggy and more efficient way of doing the same as above //this is for havok4's new functions vector offset = < -1, 0, 1>; //1 meter behind and 1 meter above owner's center.

default {

   state_entry()
   {
       llSetStatus(STATUS_PHYSICS, TRUE);
       // Little pause to allow server to make potentially large linked object physical.
       llSleep(0.1);
       llSetTimerEvent(1.0);
   }
   timer()
   {
       list det = llGetObjectDetails(llGetOwner(),[OBJECT_POS,OBJECT_ROT]);//this will never fail less owner is not in the same sim
       // Owner detected...
       // Get position and rotation
       vector pos   = llList2Vector(det,0);
       rotation rot = (rotation)llList2String(det,1);
       // Offset back one metre in X and up one metre in Z based on world coordinates.
       // use whatever offset you want.
       vector worldOffset = offset;
       // Offset relative to owner needs a quaternion.
       vector avOffset = offset * rot;
       pos += avOffset;       // use the one you want, world or relative to AV.
       llMoveToTarget(pos,0.4);
   }

} </lsl>

=============================================================================================================================

This following is a bit less laggy, as it does not use sensor. This is completelly separate system from previous example.
<lsl>

//FOLLOWER SCRIPT

integer count;
key followee;

vector agent;


position()
{
  vector pos = llList2Vector(llGetObjectDetails(followee, [OBJECT_POS]),0);
                  
                  
                 llSetPos(pos); 
                 
                  count += 1;
                  
                   if (count > 50)
                   {
                       llResetScript();
                      // llSay(0,"resetting");
                   }
   position2();
   }
   
   
   
position2()
{
  vector pos = llList2Vector(llGetObjectDetails(followee, [OBJECT_POS]),0);
                 
              
                 
                   
                  if (pos == <0,0,0> | pos.z > 1000 | pos.z < 800 )
                 {
                     
                    
                     
                   
                   
                    // llRegionSay(-876543,(string)followee);//as you can see the same channel as tellChannel on the assigner script. This in case you need to know we have stopped following and deleted ourselves
                     llSleep(1);
                     llDie();
                   }
                 
                
               
                 llSetPos(pos); 
                  count += 1;
                
   position();// yes this script loops between position(); and position2(); 
   
   }
   
   

default {

 state_entry()
 {

llSetStatus(STATUS_PHYSICS,FALSE); llSetStatus(STATUS_PHANTOM,TRUE);

     llSleep(3);
     llMessageLinked(LINK_THIS,700,"who",""); //asks another script in contents who is wanted to be followed (maybe the other script has a listener, getting the to-be-followed agent from a central server or something)
    // llSay(0,"reseted");
  
 }

 link_message(integer sender_num, integer num, string message, key id)
   {
       if (num == 500)//the other script replies, giving us an agentkey to follow
       {
           // llfolloweeSay("I follow: " + (string) message);
           followee = (key)message;
          // llfolloweeSay("I will follow: " + (string) followee);
          // llSleep(1);
           if (followee != "")
           {
               llMessageLinked(LINK_THIS,600,"got it","");//we tell the other script we got the name and we are ready
            
         
          position();
              
           }
          return;
       }
   }
   on_rez(integer start_param)
   {
       llResetScript();
   }


} </lsl>
And here an example of the other script in the prim contents, that will assign followees
<lsl>


// ASSIGNER SCRIPT

string agentkey; integer deleteChannel = -4567; // the channel your whatever tells this follower to delete itself integer listenID = -97654; // the channel your visitor list send names (to be assigned to be followed) to integer tellChannel = -86443; //in case there is some object, who needs to know who we are following, this is the channel for it to listen


default {

   state_entry()
   {
       agentkey = "";
      llListen(listenID,"",NULL_KEY,"");
     
    
       llSetTimerEvent(5);
   }
link_message(integer sender_num, integer num, string msg, key id)
   {
        if (num == 700 && msg == "who") //the follower script asks us if we know who to follow
       {
             llMessageLinked(LINK_THIS,500,agentkey, "");
           
           }
           
       if (num == 600 && msg == "got it")//the follower script has told us the agent key is received
       {
                llListenRemove(listenID);//we have all the data we need, no point listening anylonger (less laggy this way)
                llSetTimerEvent(0);
               state secondary;
       }
   }//link_message end


on_rez(integer start_param) {

   llResetScript();

}


timer() {

  if (agentkey == "")
  {
      llRegionSay(-8765433,"who"); //we repeat this until we know who to follow
      return;
   }
    if (agentkey != "")
  {
   
      llMessageLinked(LINK_THIS,500,agentkey, "");//we pass our knowledge to the other script
      
       llRegionSay(tellChannel,agentkey);//in case your whatever needs to know who we are following
       
             llSleep(6);
      state secondary;
      return;
   }
   

}

listen( integer channel, string name, key id, string message )
   {
       if (channel == listenID)
       {
            llListenRemove(listenID);
             //   llSay(0,"Listen removed, I´ve heard the command");
          agentkey = message;
           llMessageLinked(LINK_THIS,500, agentkey, "");
            llRegionSay(tellChannel,agentkey);// we've got this one to follow
          llSetTimerEvent(5);
          return;
       }
       
   
   }
   

}


state secondary {

   state_entry()
   {
       llSetTimerEvent(0);
       llListen(deleteChannel,"","","");
   }
   
    listen( integer channel, string name, key id, string message )
   {
       if (channel == deleteChannel && message == agentkey)
       {
            
           llDie();
       }
       
   }
   
   
   
   link_message(integer sender_num, integer num, string msg, key id)
   {
        if (num == 700 && msg == "who")  //the follower script asks us if we know who to follow
       {
             llMessageLinked(LINK_THIS,500,agentkey, "");
            
           }
       if (num == 600 && msg == "got it")
       {
           return;
       }


} on_rez(integer start_param) {

   llResetScript();

} } </lsl>