Follower script - Second Life Wiki

Follower script

From Second Life Wiki

Second Life Wiki > LSL Portal > Library > Follower script
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.

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



Less Laggy Follower

--Zelena DeCuir 01:13, 24 June 2012 (PDT)

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

//FOLLOWER SCRIPT
 
 integer count;
 key followee;
 
 
 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 )//this is to ensure some limitation how far the follower is following. In this case the roaming area is at 900m height. 
//So agents below 800 or above 1000ms are not followed. <0,0,0> means the avatar has teleported to other sim.
                  {
 
                     // llRegionSay(-876543,(string)followee);//as you can see the same channel as tellChannel on the assigner script. This in case some object needs 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();
    }
 
 
}


And here an example of the other script in the prim contents, that will assign followees

// 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();
}
}