User:Dz/NPC Scripts

From OpenSimulator

< User:Dz(Difference between revisions)
Jump to: navigation, search
(NPC Utility Scripts)
(NPC Utility Scripts)
Line 8: Line 8:
  
 
Remember,  you will need to enable NPC functions,  and may need to set the severity level of allowed osNPC function calls for these scripts to work.
 
Remember,  you will need to enable NPC functions,  and may need to set the severity level of allowed osNPC function calls for these scripts to work.
 +
 +
If you have feedback on script errors,  please post it to the page discussion [[User_talk:Dz/NPC_Scripts]]
  
 
=== NPC BotKiller ===
 
=== NPC BotKiller ===

Revision as of 22:47, 6 May 2013

NPC Utility Scripts

These are useful utilites I have developed over time to help me use NPCs in OpenSimulator. Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired. Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments. The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.

Remember, you will need to enable NPC functions, and may need to set the severity level of allowed osNPC function calls for these scripts to work.

If you have feedback on script errors, please post it to the page discussion User_talk:Dz/NPC_Scripts

NPC BotKiller

Sometimes..things go wrong...and you have a region full of wandering NPC's. Drop this code in a prim and touch it... It can take a while to remove them all.

PLEASE DON'T NUKE other peoples NPC's.

// OpenSimian BotKiller
// Kills all the NPC's in the region.. Please use with discretion.
// Iterate over a list of avatar keys, using them as an arguments to osNpcRemove
// Add a delay to the timer if sim performance starts to drag during logouts
// Feel free to use/distribute/modify to suit your needs
// Prepared for transfer to MOSES grid -  D Osborn  5.3.2013
 
integer who2kill = 0;
integer howmany = 0;
list avatars = [];
 
default
{
    state_entry()
    {
       llSetText("waiting ", <1.0, 0.0, 0.0>, 1.0);
    }
 
    touch_end(integer total_number)  // should not change state in touch_start events....
    {
       avatars = osGetAvatarList();
       howmany = llGetListLength(avatars)/3;
       state KillThem;
    }
 
    changed(integer change)    //  Reset on region restart
    {
       if (change & CHANGED_REGION_RESTART)
       {
           llResetScript();
       }
    }
}
 
state KillThem
 
{
    state_entry()
    {
       llSetText("Processing ", <1.0, 0.0, 0.0>, 1.0);
       llSetTimerEvent(3.0);                            // remove 1 every 3 seconds to minimize performance impact
    }
 
    timer()
    {
       osNpcRemove(llList2Key(avatars,who2kill*3));  
       llSetText("Removed so far : " + (string) (who2kill + 1), <1.0, 0.0, 0.0>, 1.0);
 
       who2kill++;       
       if(who2kill>=howmany)
           state default;          
 
       llSetTimerEvent(3.0/ llGetRegionTimeDilation());   // Use timedilation to add to the delay if lagging
    }
 
 
    touch_end(integer interrupt)   // abort by touching the object while it is processing
    {
       llResetScript();
    }
 
    changed(integer change)
    {
       if (change & CHANGED_REGION_RESTART)
       {
           llResetScript();
       }
    }
}

NPC Router

This script re-directs any NPC that collides with the object to a random destination selected from an internal list.

Once the routers are placed, a text label display can be toggled by touching it. This makes it easy to collect locations

Routers should be placed to facilitate collisions with the avatar capsules.

The real trick of this router design is the rotate calculations. These prevents the NPCs from walking backwards when assigned new targets "behind" them.

// OpenSimian NPC router
//  Douglas Osborn  MOSES version 2013May06
 
// Assign random destination to a NPC that collides with volume detect object
// Drop the script in a prim, resize and position the prim to facilitate collision with NPC av capsules
 
// Modify the list of destination vectors to reflect your layout. 
// Router position text labels can be toggled by touching the prim.  This also triggers the setpos()
 
// This design imlements rotation calculations to prevent NPC avatars from walking backwards
//  Permissions and information about the rotation functions was here..
//     http://wiki.secondlife.com/wiki/User:Pedro_Oval/Calculate_rotation_for_pointing_in_a_direction
//  Due credit is here ...    Written by Pedro Oval, 2011-01-11
 
rotation PointAtHoriz2Rot(vector target)
{
    return llRotBetween(<1., 0., 0.>, <target.x, target.y, 0.>);
}
 
rotation PointAt2Rot(vector target)
{
    rotation r = PointAtHoriz2Rot(target);
    return llRotBetween(<1., 0., 0.>, target/r) * r;
}
//   end of Pedros' rotation magic
 
list DestinationList = [<70.0,70.0,30.0>,<97.0,100.0,37.0>,<70.0,190.0,33.0>];
 
//  Modify DestinationList..  Keep the list of vectors small to minimize processing
//  Be VERY careful about assigning destinations outside of the region.
//  NPC's will move in a direct line, design your "paths" to be as free of obstacles as possible
 
integer numDests = 0;
integer showPos = 0;
 
default
{
    state_entry()
    {
       llVolumeDetect(TRUE); // Starts llVolumeDetect
        numDests = llGetListLength(DestinationList);
 
    }
 
    touch_start (integer numtouches)
    {
        while (numtouches)
        {
            if(showPos)
            {
                llSetText("", ZERO_VECTOR, 0.0);
                showPos=0;
 
                // Comment out the following 2 lines if you do NOT want your targets to "snap" to integer value locations
                vector newpos = llGetPos();
                llSetPos(<llFloor(newpos.x),llFloor(newpos.y), llFloor(newpos.z)>);
            }
            else
            {
                showPos = 1;
                llSetText((string) llGetPos(), ZERO_VECTOR, 1.0);
                llSay(0,(string) llGetPos());
            }
            numtouches--;
        }
    }                
 
    collision_start(integer num)
    {
       integer i = 0;
       do
       {
           integer DestOffset = llFloor(llFrand(numDests));
           vector NewDest = llList2Vector(DestinationList,DestOffset) ;
           osNpcSetRot(llDetectedKey(i), PointAt2Rot(NewDest - llGetPos()));
           osNpcMoveToTarget(llDetectedKey(i), NewDest, OS_NPC_NO_FLY);
       }
       while(num > ++i);
    }
 
    changed(integer change)
    {
       if (change & CHANGED_REGION_RESTART)
       {
           llResetScript();
       }
    }
}
Personal tools
General
About This Wiki