Difference between revisions of "Path update"

From Second Life Wiki
Jump to navigation Jump to search
(Use llRegionSayTo instead of llInstantMessage as to avoid unexpectedly yielding the script.)
 
(17 intermediate revisions by 11 users not shown)
Line 1: Line 1:
{{Pathfinding alpha}}
[[Category:LSL Pathfinding]]{{LSL_Event
{{LSL_Event|
|event=path_update
event=path_update|
|event_desc=Event description goes here.
event_desc=Event description goes here.|
|p1_type=integer|p1_name=type
p1_type=integer|
|p1_desc=A <code>PU_*</code>, it's the path event type
p1_name=type|
|p1_hover=A PU_* flag, it's the path event type
p1_desc=The path event type|
|p2_type=list|p2_name=reserved
p2_type=list|
|p2_desc=Reserved; not currently used.
p2_name=reserved|
|constants={{LSL_Constants/path_update}}
p2_desc=Reserved; not currently used.|
|caveats=
constants={{LSL_Constants/path_update}}|
* Note that if wandering, the "stop" (<code>{{LSL Const|PU_GOAL_REACHED|hex=0x01|ihex=1}}</code>) type may never occur as a new goal may be chosen when near (<code>{{LSL Const|PU_SLOWDOWN_DISTANCE_REACHED|hex=0x00|ihex=0}}</code>) the previous goal.
caveats=
* When the character cannot navigate from the current position (<code>{{LSL Const|PU_FAILURE_INVALID_START|hex=0x02|ihex=2}}</code>) [[llNavigateTo]] with the <code>{{LSL Const|FORCE_DIRECT_PATH|value=1}}</code> option may be helpful.
* Note that if wandering, the "stop" (type 0x01) type may never occur as a new goal may be chosen when near (0x00) the previous goal.
|examples=
* When the character cannot navigate from the current position (type 0x02) [[llNavigateTo]] with the FORCE_DIRECT_PATH option may be helpful.|
<syntaxhighlight lang="lsl2">
examples=
create_wandering_character()
<lsl>
{
//  Clear any previous character behaviors
    llDeleteCharacter();
 
//  MAX_SPEED is @ 20 by default
    llCreateCharacter([
        CHARACTER_MAX_SPEED, 25.0,
        CHARACTER_DESIRED_SPEED, 15.0]);
 
    llWanderWithin(llGetPos(), <10.0, 10.0,  2.0>, []);
}
 
list get_pathupdate_failure_info(integer type)
{
    if (type == PU_SLOWDOWN_DISTANCE_REACHED)
        return ["Near", FALSE];
   
    if (type == PU_GOAL_REACHED)
        return ["Stopping", FALSE];
   
    if (type == PU_FAILURE_INVALID_START)
        return ["Cannot path find from current location! Attempting "
                + "to go to the center of the region.", TRUE];
 
    if (type == PU_FAILURE_INVALID_GOAL)
        return ["Goal not on navmesh!", FALSE];
   
    if (type == PU_FAILURE_UNREACHABLE)
        return ["Goal unreachable!", FALSE];
   
    if (type == PU_FAILURE_TARGET_GONE)
        return ["Target gone!", FALSE];
   
    if (type == PU_FAILURE_NO_VALID_DESTINATION)
        return ["No place to go!", FALSE];
   
    if (type ==  PU_EVADE_HIDDEN)
        return ["Hiding from pursuer...", FALSE];
   
    if (type == PU_EVADE_SPOTTED)
        return ["Switched from hiding to running...", FALSE];
   
    if (type ==  PU_FAILURE_NO_NAVMESH)
        return ["Region has no nav mesh..", FALSE];
   
    if (type == PU_FAILURE_DYNAMIC_PATHFINDING_DISABLED)
        return ["Dynamic pathfinding is disabled in this region.", FALSE];
 
    if (type == PU_FAILURE_PARCEL_UNREACHABLE)
        return ["Parcel entry problem (is the parcel full?).", FALSE];
 
    if (type == PU_FAILURE_OTHER)
        return ["Hit an unspecified failure", FALSE];
 
    return ["Unknown failure", FALSE];
}
 
default
default
{
{
    on_rez(integer start_param)
    {
        llResetScript();
    }
     state_entry()
     state_entry()
     {
     {
         llDeleteCharacter(); // Clear any previous character behaviors
         create_wandering_character();
        llCreateCharacter([CHARACTER_DESIRED_SPEED, 35.0]);
       
        llWanderWithin(llGetPos(), 10.0, []);
     }
     }
   
     path_update(integer type, list reserved)
     path_update(integer type, list reserved)
     {
     {
         if (type == 0)
         list params = get_pathupdate_failure_info(type);
        {
         string info = llList2String(params, 0);
            llOwnerSay("Near");
         integer /* boolean */ hasToMove = llList2Integer(params, 1);
        }
 
        else if (type == 1)
         llRegionSayTo(llGetOwner(), 0, info);
        {
         if (hasToMove)
            llOwnerSay("Stopping");
         }
        else if (type == 2)
        {
            llOwnerSay("Cannot path find from current location! Attempting to go to the center of the region.");
           
            llNavigateTo(<128.0, 128.0, llGround(<128.0, 128.0, 0.0> - llGetPos())>, [FORCE_DIRECT_PATH, TRUE]);
         }
        else if (type == 3)
        {
            llOwnerSay("Goal not on navmesh!");
        }
         else if (type == 4)
        {
            llOwnerSay("Goal unreachable!");
        }
        else if (type == 5)
        {
            llOwnerSay("Target gone!");
        }
        else if (type == 6)
        {
            llOwnerSay("No place to go!");
        }
        else if (type == 7)
        {
            llOwnerSay("Hiding from pursuer...");
        }
        else if (type == 8)
        {
            llOwnerSay("Switched from hiding to running...");
         }
        else if (type == 9)
        {
            llOwnerSay("Region has no nav mesh..");
        }
        else if (type == 1000000)
        {
            llOwnerSay("Hit an unspecified failure");
        }
        else
         {
         {
             llOwnerSay("Unknown failure");
             vector currentPosition = llGetPos();
            llNavigateTo(<128.0, 128.0, llGround(<128.0, 128.0, 0.0> - currentPosition)>, [FORCE_DIRECT_PATH, TRUE]);
         }
         }
     }
     }
}
}
</lsl> |
</syntaxhighlight>  
also_functions=
|also_functions=
* [[llCreateCharacter]]
* [[llCreateCharacter]]
* [[llDeleteCharacter]]
* [[llDeleteCharacter]]
Line 91: Line 109:
* [[llPursue]]
* [[llPursue]]
* [[llUpdateCharacter]]
* [[llUpdateCharacter]]
* [[llWanderWithin]]|
* [[llWanderWithin]]
also_events=
|also_events
* [[path_update]]
|history = Date of Release  [[ Release_Notes/Second_Life_Server/12#12.07.31.262785 | 31/07/2012 ]]
}}
}}

Latest revision as of 07:58, 6 October 2024

Description

Event: path_update( integer type, list reserved ){ ; }

Event description goes here.

• integer type A PU_*, it's the path event type
• list reserved Reserved; not currently used.
Constants Value Description
PU_SLOWDOWN_DISTANCE_REACHED 0x00 Character is near current goal.
PU_GOAL_REACHED 0x01 Character has reached the goal and will stop or choose a new goal (if wandering).
PU_FAILURE_INVALID_START 0x02 Character cannot navigate from the current location - e.g., the character is off the navmesh or too high above it.
PU_FAILURE_INVALID_GOAL 0x03 Goal is not on the navmesh and cannot be reached.
PU_FAILURE_UNREACHABLE 0x04 Goal is no longer reachable for some reason - e.g., an obstacle blocks the path.
PU_FAILURE_TARGET_GONE 0x05 Target (for llPursue or llEvade) can no longer be tracked - e.g., it left the region or is an avatar that is now more than about 30m outside the region.
PU_FAILURE_NO_VALID_DESTINATION 0x06 There's no good place for the character to go - e.g., it is patrolling and all the patrol points are now unreachable.
PU_EVADE_HIDDEN 0x07 Triggered when an llEvade character thinks it has hidden from its pursuer.
PU_EVADE_SPOTTED 0x08 Triggered when an llEvade character switches from hiding to running
PU_FAILURE_NO_NAVMESH 0x09 This is a fatal error reported to a character when there is no navmesh for the region. This usually indicates a server failure and users should file a bug report and include the time and region in which they received this message.
PU_FAILURE_DYNAMIC_PATHFINDING_DISABLED 0x0A Triggered when a character enters a region with dynamic pathfinding disabled. Dynamic pathfinding can be toggled by estate managers via the 'dynamic_pathfinding' option in the Region Debug Console.
PU_FAILURE_PARCEL_UNREACHABLE 0x0B Triggered when a character failed to enter a parcel because it is not allowed to enter, e.g. because the parcel is already full or because object entry was disabled after the navmesh was baked.
PU_FAILURE_OTHER 0xF4240 Other failure.

Caveats


Examples

create_wandering_character()
{
//  Clear any previous character behaviors
    llDeleteCharacter();

//  MAX_SPEED is @ 20 by default
    llCreateCharacter([
        CHARACTER_MAX_SPEED, 25.0,
        CHARACTER_DESIRED_SPEED, 15.0]);

    llWanderWithin(llGetPos(), <10.0, 10.0,  2.0>, []);
}

list get_pathupdate_failure_info(integer type)
{
    if (type == PU_SLOWDOWN_DISTANCE_REACHED)
        return ["Near", FALSE];
    
    if (type == PU_GOAL_REACHED)
        return ["Stopping", FALSE];
    
    if (type == PU_FAILURE_INVALID_START)
        return ["Cannot path find from current location! Attempting "
                + "to go to the center of the region.", TRUE];

    if (type == PU_FAILURE_INVALID_GOAL)
        return ["Goal not on navmesh!", FALSE];
    
    if (type == PU_FAILURE_UNREACHABLE)
        return ["Goal unreachable!", FALSE];
    
    if (type == PU_FAILURE_TARGET_GONE)
        return ["Target gone!", FALSE];
    
    if (type == PU_FAILURE_NO_VALID_DESTINATION)
        return ["No place to go!", FALSE];
    
    if (type ==  PU_EVADE_HIDDEN)
        return ["Hiding from pursuer...", FALSE];
    
    if (type == PU_EVADE_SPOTTED)
        return ["Switched from hiding to running...", FALSE];
    
    if (type ==  PU_FAILURE_NO_NAVMESH)
        return ["Region has no nav mesh..", FALSE];
    
    if (type == PU_FAILURE_DYNAMIC_PATHFINDING_DISABLED)
        return ["Dynamic pathfinding is disabled in this region.", FALSE];

    if (type == PU_FAILURE_PARCEL_UNREACHABLE)
        return ["Parcel entry problem (is the parcel full?).", FALSE];

    if (type == PU_FAILURE_OTHER)
        return ["Hit an unspecified failure", FALSE];

    return ["Unknown failure", FALSE];
}

default
{
    on_rez(integer start_param)
    {
        llResetScript();
    }

    state_entry()
    {
        create_wandering_character();
    }
 
    path_update(integer type, list reserved)
    {
        list params = get_pathupdate_failure_info(type);
        string info = llList2String(params, 0);
        integer /* boolean */ hasToMove = llList2Integer(params, 1);

        llRegionSayTo(llGetOwner(), 0, info);
        if (hasToMove)
        {
            vector currentPosition = llGetPos();
            llNavigateTo(<128.0, 128.0, llGround(<128.0, 128.0, 0.0> - currentPosition)>, [FORCE_DIRECT_PATH, TRUE]);
        }
    }
}

Deep Notes

History

Date of Release 31/07/2012

Signature

event void path_update( integer type, list reserved );