Difference between revisions of "LlSensorRepeat"

From Second Life Wiki
Jump to navigation Jump to search
(Added a note about calling llSensorRepeat twice)
(32 intermediate revisions by 10 users not shown)
Line 1: Line 1:
{{Issues/SVC-2409}}{{Issues/SVC-4301}}{{LSL_Function/uuid|id|object=*}}{{LSL Constants/Sensing|type}}{{LSL_Function
{{LSL_Function
|inject-2={{LSL_Function/uuid|id|object=*}}{{LSL Constants/Sensing|type}}
|inject-3={{Issues/SVC-2409}}{{Issues/SVC-4301}}{{Issues/SVC-6662}}{{Issues/BUG-2366}}
|func=llSensorRepeat|sort=SensorRepeat
|func=llSensorRepeat|sort=SensorRepeat
|func_id=29|func_sleep=0.0|func_energy=10.0
|func_id=29|func_sleep=0.0|func_energy=10.0
|p1_type=string|p1_name=name|p1_desc=Object or avatar name
|p1_type=string|p1_name=name|p1_hover=Object or avatar name|p1_desc=Object or avatar name[[#NameFormat|<span style="color:red;">!</span>]]
|p2_type=key|p2_name=id
|p2_type=key|p2_name=id
|p3_type=integer|p3_name=type|p3_desc=mask ({{#var:AGENT}}, {{#var:ACTIVE}}, {{#var:PASSIVE}}, and/or {{#var:SCRIPTED}})|p3_hover=mask (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED)
|p3_type=integer|p3_name=type|p3_desc=mask ({{#var:AGENT_BY_LEGACY_NAME}}, {{#var:AGENT_BY_USERNAME}}, {{#var:ACTIVE}}, {{#var:PASSIVE}}, and/or {{#var:SCRIPTED}})|p3_hover=mask (AGENT_BY_LEGACY_NAME, AGENT_BY_USERNAME, ACTIVE, PASSIVE, and/or SCRIPTED)
|p4_type=float|p4_name=range|p4_desc=range 0.0 to 96.0m
|p4_type=float|p4_name=range|p4_desc=range in meters, {{Interval|gte=0.0|lte=96.0|center=range}}|p4_hover=range in meters, {{Interval/Hover|gte=0.0|lte=96.0|center=range}}
|p5_type=float|p5_name=arc|p5_desc=the max angle between the local x-axis of the prim and detectable objects, range 0.0 to {{#var:PI}}|p5_hover=the max angle between the local x-axis of the prim and detectable objects, range 0.0 to PI
|p5_type=float|p5_name=arc|p5_desc=the max angle between the local x-axis of the prim and detectable objects, range {{Interval|gte=0.0|lteh=PI|lte={{#var:PI}}|center=arc}}|p5_hover=the max angle between the local x-axis of the prim and detectable objects, range {{Interval/Hover|gte=0.0|lte=PI|center=arc}}
|p6_type=float|p6_name=rate|p6_desc=How often a [[sensor]]/[[no_sensor]] will be queued.
|p6_type=float|p6_name=rate|p6_desc=How often a [[sensor]]/[[no_sensor]] will be queued.
|func_footnote=If '''name''', '''id''', and/or '''type''' are empty or 0, they are ignored.<br/>If '''id''' is an invalid key or [[NULL_KEY]] it is treated as empty.
|func_footnote=If {{LSLP|name}}, {{LSLP|id}}, and/or {{LSLP|type}} are empty or 0, they are ignored.<br/>If {{LSLP|id}} is an invalid key or [[NULL_KEY]] it is treated as empty.<br id="NameFormat"/>Depending upon which AGENT* flag is used determines the format requirements for {{LSLP|name}}


See: [http://www.lslwiki.net/lslwiki/wakka.php?wakka=llSensor llSensor] for an excellent explanation of '''arc'''.
See: [http://www.lslwiki.net/lslwiki/wakka.php?wakka=llSensor llSensor] for an excellent explanation of {{LSLP|arc}}.
|func_desc=Performs a single scan for '''name''' and '''id''' with '''type''' within '''range''' meters and '''arc''' radians of forward vector and repeats every '''rate''' seconds. It does not perform the first scan until '''rate''' seconds have passed.
|func_desc=Performs a single scan for {{LSLP|name}} and {{LSLP|id}} with {{LSLP|type}} within {{LSLP|range}} meters and {{LSLP|arc}} radians of forward vector and repeats every {{LSLP|rate}} seconds. It does not perform the first scan until {{LSLP|rate}} seconds have passed.
|return_text
|return_text
|spec
|spec
|caveats=*The repeat of the sensor event is adversely affected by [[llGetRegionTimeDilation|time dilation]] (lag).
|caveats=*The repeat of the sensor event is adversely affected by [[llGetRegionTimeDilation|time dilation]] (lag).
*Sensors placed in attachments will use the direction the avatar is facing as their forward vector. In mouselook, this means that it will be wherever the avatar is looking, while out of mouselook, this means whichever way the avatar is pointing. This does not include where the avatar's head is pointing, or what animation the avatar is doing, just the direction the avatar would move in if you walked forward. This is the case, regardless of where the object is attached.  
*Sensors placed in the root prim of attachments will use the direction the avatar is facing as their forward vector. In mouselook, this means that it will be wherever the avatar is looking, while out of mouselook, this means whichever way the avatar is pointing. This does not include where the avatar's head is pointing, or what animation the avatar is doing, just the direction the avatar would move in if you walked forward. This is the case, regardless of where the object is attached.
*When a [[sensor]] event is queued, it dequeues all other sensor events in the queue.
*Sensors placed in prims other than the root prim of an attachment will have their forward direction offset relative to the root prim's forward direction, e.g. a sensor in a prim whose +X direction is the reverse of the root +X will look backward.
* Only the most recent [[sensor]] event is queued. Previous sensor events are replaced.
* A repeating sensor does not persist across a state change.
* [[llSensorRepeat]] can occasionally detect outside of it's specified range every few cycles when used near sim borders. [[llSensor]] in a [[timer]] does not.
* Only one or zero llSensorRepeats can be active per script. If llSensorRepeat is called a second time without calling [[llSensorRemove]], the first llSensorRepeat is deactivated and the second one replaces it
|examples=
|examples=
<lsl>// Written by Steamy Latte.
<source lang="lsl2">// Written by Steamy Latte.
// Scans every 30 seconds for visitors within 10 meters.
// Scans every 30 seconds for visitors within 10 meters.
// Reports new visitors to object owner when she is in range.
// Reports new visitors to object owner when she is in range.


string AllAgents;
string AllAgents;
string OwnerName;


default
default
Line 32: Line 36:
         // arc=PI is a sphere, you could look more narrowly in the direction object is facing with PI/2, PI/4 etc.
         // arc=PI is a sphere, you could look more narrowly in the direction object is facing with PI/2, PI/4 etc.
         // don't repeat this too often to avoid lag.
         // don't repeat this too often to avoid lag.
         llSensorRepeat("", "", AGENT, 10.0, PI, 30.0);
         llSensorRepeat("", "", AGENT_BY_LEGACY_NAME, 10.0, PI, 30.0);
     }
     }
     sensor(integer num_detected)
     sensor(integer num_detected)
     {
     {
         string thisAgent = "";
         string thisAgent;
         integer agentNum;
         integer agentNum;
         for (agentNum=0; agentNum<num_detected; agentNum++)
         for (agentNum=0; agentNum<num_detected; agentNum++)
         {
         {
             key thisKey = llDetectedKey(agentNum);
             thisAgent = llDetectedName(agentNum);
            string thisAgent = llDetectedName(agentNum);
             if (llDetectedKey(agentNum) == llGetOwner())
             if (thisKey == llGetOwner())
             {
             {
                 if (AllAgents != "")
                 if (AllAgents != "")
Line 56: Line 59:
         }
         }
     }
     }
}</lsl>
}</source>
 
<source lang="lsl2">
// Written by Evans Love.
// (Limited to most recent 200 names by Void Singer to prevent eventual Stack/Heap Collision + clean up)
// Continuously scans for visitors within 10 meters and reports new visitors to object owner.
//-------------------------------------------------------------------------------------
 
integer RESPONSE_CHANNEL = -100;
float  SCAN_RANGE      = 10.0;
float  SCAN_INTERVAL    = 20.0;
list    VISITOR_LIST;
 
default
{
    state_entry()
    {
        llSensorRepeat("", NULL_KEY, AGENT_BY_LEGACY_NAME, SCAN_RANGE, PI, SCAN_INTERVAL);
    }
 
    sensor(integer number_detected)
    {
        integer agent_number;
 
//      iterate through all detected agents
        for (; agent_number < number_detected; agent_number++)
        {
            string  this_agent_name = llDetectedName(agent_number);
            key    this_agent_key  = llDetectedKey(agent_number);
 
//          if the agent is not found on the list
            if (llListFindList(VISITOR_LIST, [this_agent_name]) == -1)
            {
//              add her/him and make the list hold the last 200 visitors
                VISITOR_LIST = [this_agent_name] + llList2List(VISITOR_LIST, 0, 198);
 
                llDialog(this_agent_key, "Welcome!", ["Ok"], RESPONSE_CHANNEL);
 
                llOwnerSay(this_agent_name);
            }
//          else agent is already on the list
        }
 
    }
}
</source>
|helpers
|helpers
|also_functions=
|also_functions=
{{LSL DefineRow||[[llSensor]]| Runs a sensor once}}
{{LSL DefineRow||[[llSensor]]| Runs a sensor once}}
{{LSL DefineRow||[[llSensorRemove]]| Stops the llSensorRepeat timer}}
{{LSL DefineRow||[[llSensorRemove]]| Stops the llSensorRepeat timer}}
{{LSL DefineRow||[[llOverMyLand]]| What happens over owners land}}
|also_events=
|also_events=
{{LSL DefineRow||[[sensor]]|Triggered when a sensor detects something}}
{{LSL DefineRow||[[sensor]]|Triggered when a sensor detects something}}
{{LSL DefineRow||[[no_sensor]]|Triggered when a sensor detects nothing}}
{{LSL DefineRow||[[no_sensor]]|Triggered when a sensor detects nothing}}
|also_articles
|also_articles
|notes=[http://rpgstats.com/wiki/index.php?title=Lag Lag tip]: Consider [[llVolumeDetect]] as a less resource intensive alternative to llSensorRepeat in many cases.
|notes=
{{LSL Tip|You might want to use [[llGetAgentList]] instead of using sensors to get a list of all avatars within the same parcel or region.}}
|cat1=Sensor
|cat1=Sensor
|cat2=Detected
|cat2=Detected
|cat3
|cat3=Username/As A Parameter
|cat4
|cat4=Legacy Name/As A Parameter
|haiku={{Haiku|Binoculars raised,|All eyes scan the horizon.|Ever vigilant.}}
}}
}}

Revision as of 09:21, 3 May 2017

Summary

Function: llSensorRepeat( string name, key id, integer type, float range, float arc, float rate );
0.0 Forced Delay
10.0 Energy

Performs a single scan for name and id with type within range meters and arc radians of forward vector and repeats every rate seconds. It does not perform the first scan until rate seconds have passed.

• string name Object or avatar name!
• key id group, avatar or object UUID
• integer type mask (AGENT_BY_LEGACY_NAME, AGENT_BY_USERNAME, ACTIVE, PASSIVE, and/or SCRIPTED)
• float range range in meters, [0.0, 96.0]
• float arc the max angle between the local x-axis of the prim and detectable objects, range [0.0, PI]
• float rate How often a sensor/no_sensor will be queued.

If name, id, and/or type are empty or 0, they are ignored.
If id is an invalid key or NULL_KEY it is treated as empty.
Depending upon which AGENT* flag is used determines the format requirements for name

See: llSensor for an excellent explanation of arc.

type Flag Mask Description (llDetectedType()) Description (llSensor() and llSensorRepeat() mask)
AGENT_BY_LEGACY_NAME 0x1 Agents This is used to find agents by legacy name.
AGENT 0x1 Agents This is also used to find agents by legacy name, and is functionally identical to AGENT_BY_LEGACY_NAME
AGENT_BY_USERNAME 0x10 Reserved This is used to find agents by username.
ACTIVE 0x2 Physical tasks. (Physical objects & agents) Physical objects that are moving or objects containing an active script. Thus, it is using SL server resources now.
PASSIVE 0x4 Non-physical objects. Non-scripted or script is inactive and non-physical or, if physical, not moving. Thus, it is not using SL server resources now.
SCRIPTED 0x8 Objects containing any active script. Objects that has any script, which is doing anything in simulator just now.
DAMAGEABLE 0x20 Objects & agents that are able to process damage. Filter for objects in world that have a script with on_damage or a final_damage event (able to process damage)
llDetectedType() Scripted Not Scripted Agent Standing Agent Sitting
Physical Movement 10 (ACTIVE|SCRIPTED) 2 (ACTIVE) 3 (ACTIVE|AGENT) 3 (ACTIVE|AGENT)
Non-Physical 12 (PASSIVE|SCRIPTED) 4 (PASSIVE) 1 (AGENT) 5 (PASSIVE|AGENT)
Float Constants Arc
PI_BY_TWO A hemisphere scan
PI A full sphere scan

Caveats

  • When searching for an avatar but not by name, it doesn't matter which AGENT flag is used.
  • The repeat of the sensor event is adversely affected by time dilation (lag).
  • Sensors placed in the root prim of attachments will use the direction the avatar is facing as their forward vector. In mouselook, this means that it will be wherever the avatar is looking, while out of mouselook, this means whichever way the avatar is pointing. This does not include where the avatar's head is pointing, or what animation the avatar is doing, just the direction the avatar would move in if you walked forward. This is the case, regardless of where the object is attached.
  • Sensors placed in prims other than the root prim of an attachment will have their forward direction offset relative to the root prim's forward direction, e.g. a sensor in a prim whose +X direction is the reverse of the root +X will look backward.
  • Only the most recent sensor event is queued. Previous sensor events are replaced.
  • A repeating sensor does not persist across a state change.
  • llSensorRepeat can occasionally detect outside of it's specified range every few cycles when used near sim borders. llSensor in a timer does not.
  • Only one or zero llSensorRepeats can be active per script. If llSensorRepeat is called a second time without calling llSensorRemove, the first llSensorRepeat is deactivated and the second one replaces it

Examples

// Written by Steamy Latte.
// Scans every 30 seconds for visitors within 10 meters.
// Reports new visitors to object owner when she is in range.

string AllAgents;

default
{
    state_entry()
    {
        // arc=PI is a sphere, you could look more narrowly in the direction object is facing with PI/2, PI/4 etc.
        // don't repeat this too often to avoid lag.
        llSensorRepeat("", "", AGENT_BY_LEGACY_NAME, 10.0, PI, 30.0);
    }
    sensor(integer num_detected)
    {
        string thisAgent;
        integer agentNum;
        for (agentNum=0; agentNum<num_detected; agentNum++)
        {
            thisAgent = llDetectedName(agentNum);
            if (llDetectedKey(agentNum) == llGetOwner())
            {
                if (AllAgents != "")
                {
                    llOwnerSay("We've had the following visitors:" + AllAgents);
                    AllAgents = "";
                }
            }
            else if (llSubStringIndex(AllAgents+"\n", "\n"+thisAgent+"\n") < 0)
            {
                AllAgents = AllAgents + "\n" + thisAgent;
            }
        }
    }
}
// Written by Evans Love.
// (Limited to most recent 200 names by Void Singer to prevent eventual Stack/Heap Collision + clean up)
// Continuously scans for visitors within 10 meters and reports new visitors to object owner.
//-------------------------------------------------------------------------------------

integer RESPONSE_CHANNEL = -100;
float   SCAN_RANGE       = 10.0;
float   SCAN_INTERVAL    = 20.0;
list    VISITOR_LIST;

default
{
    state_entry()
    {
        llSensorRepeat("", NULL_KEY, AGENT_BY_LEGACY_NAME, SCAN_RANGE, PI, SCAN_INTERVAL);
    }

    sensor(integer number_detected)
    {
        integer agent_number;

//      iterate through all detected agents
        for (; agent_number < number_detected; agent_number++)
        {
            string  this_agent_name = llDetectedName(agent_number);
            key     this_agent_key  = llDetectedKey(agent_number);

//          if the agent is not found on the list
            if (llListFindList(VISITOR_LIST, [this_agent_name]) == -1)
            {
//              add her/him and make the list hold the last 200 visitors
                VISITOR_LIST = [this_agent_name] + llList2List(VISITOR_LIST, 0, 198);

                llDialog(this_agent_key, "Welcome!", ["Ok"], RESPONSE_CHANNEL);

                llOwnerSay(this_agent_name);
            }
//          else agent is already on the list
        }

    }
}

Notes

KBcaution.png Important: You might want to use llGetAgentList instead of using sensors to get a list of all avatars within the same parcel or region.

See Also

Events

•  sensor Triggered when a sensor detects something
•  no_sensor Triggered when a sensor detects nothing

Functions

•  llSensor Runs a sensor once
•  llSensorRemove Stops the llSensorRepeat timer
•  llOverMyLand What happens over owners land

Deep Notes

Footnotes

  1. ^ The ranges in this article are written in Interval Notation.

Signature

function void llSensorRepeat( string name, key id, integer type, float range, float arc, float rate );

Haiku

Binoculars raised,
All eyes scan the horizon.
Ever vigilant.