osgrid.org
https://forums.osgrid.org/

Need help with efficiency
https://forums.osgrid.org/viewtopic.php?f=5&t=3549
Page 1 of 1

Author:  Haplo Voss [ Thu Sep 22, 2011 7:49 am ]
Post subject:  Need help with efficiency

Hello all. I'm wondering if someone can help me with the following issue...

I've created a script and expanded the variables and comments a bit so you can easily see what is going on and why.

Issue is this: osNpcMoveTo prompt the NPC to move to a specified location. Once the command is given and the NPC begins moving I need to then 'wait' until the NPC reaches its destination before performing the next operation. (In this case - pause for X seconds then move to its next position. Simple pathing)

I would like to find a more efficient way to do this. Currently I am using a while loop to constantly check the current position of the NPC against the destination. Once it gets within 1,1,0 it will stop - then progress on to the next path point.

This is obviously very resource intensive. I have thought about placing colliders at path points however there would still need to be course checking so... I'm sure I am missing something simple.

Basically using a timer combined with a sleep seems redundant lol - but hey I'm asking for help right?

Thanks tons!!
- Hap

{L_CODE}:
key npc;                    // npc's key
vector a;                   // temp path vector
vector nPos;                // npc current pos
integer pathPoint;          // path list counter
integer destX;              // spawn init vector.x
integer destY;              // spawn init vector.y
string noteName = "Path1";  // notecard for path vectors
list pathFollow = "[]";     // list container for path
integer listener;           // listener
float absNposX;             // temp npc pos.x
float absNposY;             // temp npc pos.y
float absAposX;             // temp path pos.x
float absAposY;             // temp path pos.y

default
{
    state_entry()
    {
        listener = llListen(10,"",NULL_KEY,"");
        integer i;
        for(i=0; i<osGetNumberOfNotecardLines(noteName); i++) {
            string getPath = osGetNotecardLine(noteName, i);
            if (getPath != "" && (vector)getPath != ZERO_VECTOR){
                pathFollow += getPath;
                llSay(0, getPath);
            }
        }
        llOwnerSay("Total Path points: "+(string)(llGetListLength(pathFollow)-1));
    }
   
    touch_start(integer num)
    {
        llOwnerSay("\n\n
        NPC Path Follower:\nType /10 (command) to control your NPC.\ncreate --- spawn NPC\nremove - despawn NPC\nreload -- reload NPC appearance\nstart ----- start NPC following path\nstop ----- stop NPC at next path point");
    }   

    listen(integer channel, string name, key id, string msg)
    {
        if (msg != "")
        {
            if (msg == "create"){
                osOwnerSaveAppearance("appearance");
                destX = (integer) llFrand (10)-10;
                destY = (integer) llFrand (10)-10;
                npc = osNpcCreate ("Luke", "Endemirror", llList2Vector(pathFollow,1), "appearance");
               
            }
            else if (msg == "start"){
                pathPoint = 2;
                llOwnerSay("Timer Begin");
                osSetSpeed(npc,0.7);
                llSetTimerEvent(1);
            }   
            else if (msg == "stop"){
                llSetTimerEvent(0.0);
                llOwnerSay("Stop");
                osAvatarStopAnimation(npc,"walk");
                osNpcRemove(npc);
                llResetScript();
            }
            else if (msg == "remove"){
                osNpcRemove(npc);
                llResetScript();
            }
            else if (msg == "reload"){
                osNpcLoadAppearance(npc, "appearance");
            }
            else {
                llOwnerSay("Nope");
            }
        }
   
    }
    timer()
    {
        if (pathPoint < llGetListLength(pathFollow)){
            osAvatarPlayAnimation(npc,"walk");
            nPos = osNpcGetPos(npc);
            a = llList2Vector(pathFollow,pathPoint);
            osNpcMoveToTarget(npc, a, OS_NPC_NO_FLY);
           
            absNposX=llFabs(nPos.x);
            absNposY=llFabs(nPos.y);
            absAposX=llFabs(a.x);
            absAposY=llFabs(a.y);
           
            while (llFabs(absNposX - absAposX) > 1 || llFabs(absNposY - absAposY) > 1)
            {
                nPos = osNpcGetPos(npc);
                absNposX=llFabs(nPos.x);
                absNposY=llFabs(nPos.y);
                absAposX=llFabs(a.x);
                absAposY=llFabs(a.y);
                llSleep(.2);
            }
            osAvatarStopAnimation(npc,"walk");
            llOwnerSay((string)pathPoint + ") " + (string)a); // debug - say current pathpoint
            llSleep(5); // pause before starting towards next path point
            pathPoint++;
        }
        else{
            pathPoint=1; // reset counter - start path over.
        }
    }
}


Here is an example of the "Path1" notecard. Use any coordinates you want. One per line. As many as you'd like.
{L_CODE}:
<92.000000,160.000000,23.000000>
<88.000000,137.000000,23.000000>

Author:  Cosmo Topper [ Fri Mar 16, 2012 4:26 pm ]
Post subject:  Re: Need help with efficiency

Thanks for posting this Haplo!
Along with your other topics it has been a great starting point & guide to my NPC experimentations.

I'm rather new to scripting for os, but have been able to utilize most of the NPC scripts in this forum and somewhat modify them to suite my intentions - don't have anything quite unique yet to contribute here.

The first time I used your above code, the npc would stop completely, usually after the first 2 or 3 targets, at random positions.
Using your "built-in" debugging system I found that every-time it stopped before (but close to) the next target.
Putting this together with Kahn's comment that "sometimes the NPC stops up to 1.5 meters from its destination", I changed the distance checking to 2 and it has been running flawlessly ever since.

{L_CODE}:
while (llFabs(absNposX - absAposX) > 2 || llFabs(absNposY - absAposY) > 2)

does this make sense?

Mostly I was wondering if you have discovered alternatives for the "while loop" approach for checking if target has been reached, or other enhancements on the timer/llsleep combination - which to my (newb) mind makes perfect sense.

The locations notecard approach is a real lifesaver for fixed routines, but what if you needed different actions to be performed at each target? (instead of the llsleep used for all)

Like say, different animations...

I guess a second notecard ("animations") with the same number of lines corresponding to the ones in the "locations" notecard could be used referencing anims in the controllers inventory (with some "null option" too for none), and I was contemplating to undertake the task.
But how would the waiting untill animation completes be achieved? before npc moves to next target, and so on... a crude way I can think of would be another llsleep for an amount equal to the anims duration right after the osAvatarPlayAnimation, but then again that could be different for each animation.

Any feedback and/or suggestions and directions for further investigation (well to the best of my current scripting ability) appreciated.

Page 1 of 1 All times are UTC - 5 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/