User:Trinity Coulter/Handy Follow Seat

From Second Life Wiki
Jump to navigation Jump to search

I just used a default cube prim for this. Its simple but effective, hope it works well for you, feel free to mod and post your improvements if you like :)

Thx, Trin

<lsl> integer finding_target = FALSE; integer follow_range = 1; string targetname; key targetkey; string help_text = "Say \'follow Avie Name\' to follow, \'stop follow\' to stop, and range 1 (or other number) to set the follow range.";

default {

   state_entry()
   {
       llApplyImpulse(-llGetMass()*llGetVel(),FALSE);
       llSay(0,help_text);
       llSitTarget(<.3,0,.5>, ZERO_ROTATION);
       llSetStatus(STATUS_ROTATE_X,FALSE);
       llSetStatus(STATUS_ROTATE_Y,FALSE);
       llSetStatus(STATUS_ROTATE_Z,TRUE);
       llListen(0,"",llGetOwner(),"");
   }
   
   on_rez(integer start_param)
   {
       llResetScript();
   }
   
   listen(integer channel, string name, key id, string message)
   {
       string command = "follow";
       if (llGetSubString(message,0,llStringLength(command)-1) == command)
       {
           //do a sensor
           finding_target = TRUE;
           targetname = llStringTrim(llGetSubString(message,llStringLength(command),-1),STRING_TRIM);
           llSay(0,"Finding " + targetname);
           llSensor(targetname,NULL_KEY,AGENT,65,PI);
       }
       
       command = "stop follow";
       if (llGetSubString(message,0,llStringLength(command)-1) == command)
       {
           //stop sensing
           finding_target = FALSE;
           llSensorRemove();
           llStopLookAt();
           llSay(0,"No Longer Following");
           llSetStatus(STATUS_PHYSICS, FALSE);
       }
       
       command = "range";
       if (llGetSubString(message,0,llStringLength(command)-1) == command)
       {
           //set range
           integer temp_follow_range = (integer)llStringTrim(llGetSubString(message,llStringLength(command),-1),STRING_TRIM);
           if (temp_follow_range == 0)
           {
               llSay(0,"Invalid range, range remains at " + (string)follow_range);
           }
           else
           {
               follow_range = temp_follow_range;
               llSay(0,"Range reset to " + (string)follow_range + " meters");
           }
       }
       
   }
   
   sensor(integer num_detected)
   {
       if(finding_target == TRUE)
       {
       integer x;
       for (x = 0; x < num_detected; x++)
       {
           if (llToLower(llDetectedName(x)) == llToLower(targetname))
           {
               targetkey = llDetectedKey(x);
               llSay(0, "Found " + targetname + ", following at range of " + (string)follow_range + "meters.");
               llSetStatus(STATUS_PHYSICS, TRUE);
               finding_target = FALSE;
               
               float mass = llGetMass(); // mass of this object
               float gravity = 9.8; // gravity constant
               llSetForce(mass * <0,0,gravity>, FALSE); // in global orientation
               llSensorRepeat("",targetkey, AGENT,65,PI,1.0);
           }
       }
       }
       else
       {
           vector targetpos = llDetectedPos(0);
           targetpos.z = targetpos.z + 1;
           
           llLookAt(targetpos, 1.0, 5.0);
           if(llVecDist(targetpos,llGetPos()) > follow_range)
           {
               llTarget(targetpos, follow_range);
               llMoveToTarget(targetpos,2.0);
           }
       }
   }
   
   no_sensor()
   {
       if(finding_target == TRUE)
       {
           llSay(0,"Target not found, please check spelling and try again.");
           finding_target = FALSE;
       }
   }
   
   at_target(integer tnum, vector targetpos, vector ourpos)
   {
       llStopMoveToTarget();
       llStopLookAt();
       llTargetRemove(tnum);
       llApplyImpulse(-llGetMass()*llGetVel(),FALSE);
   }
   
   changed(integer change)
   {
       if (change & CHANGED_LINK)
       {
           float mass = llGetMass(); // mass of this object
           float gravity = 9.8; // gravity constant
           llSetForce(mass * <0,0,gravity>, FALSE); // in global orientation
           llApplyImpulse(-llGetMass()*llGetVel(),FALSE);
           llSetRot(llGetRot());
       }
   }

} </lsl>