Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0006028opensim[REGION] Script Functionspublic2012-05-22 20:052012-07-05 19:35
Reporterslow putzo 
Assigned Tojustincc 
PriorityhighSeveritymajorReproducibilityalways
StatusclosedResolutionfixed 
PlatformAMD 64 bit 6 coreOSLinux FedoraOS Version15
Product Versionmaster (dev code) 
Target VersionFixed in Version 
Summary0006028: osAvatarStopAnimation fails if a UUID is used for the animation rather than the animation name
DescriptionThe below script uses the llGetAnimationList function to get a list of the playing animations on the avatar. The osAvatarStopAnimation function is used to send the individual UUID's from the list to the avatar to stop each one.

Using the llStopAnimation works perfectly.

The reason for the desire to use the os function is to allow NPC's to use the same pose ball as a regular avatar without having to have the NPC grant permissions, which it is not able to do.
Steps To ReproduceHave the avatar sit on a pose ball and give it an animation.

In my case I am using a dance stand that uses the MLP script. Because the pose ball does not do the animations but rather the dance stand does the animations are done using linkmesage to send information back and forth.

Using the os function eliminates the problem of granting permission to animate.

I am testing this using my normat avatar, not an NPC. It should work the same as with the llStopAnimation function.
Additional Information    // stop all playing animations for avatar
stopAnim(key avi) {
    list anims = llGetAnimationList(avi);
    integer ix;
    for (ix = 0; ix < llGetListLength(anims); ++ix) {
        string anim = llList2String(anims, ix);
        string owner_name = osKey2Name(avi); // debug
        llSay(0,"Stopping animation = "+anim+" for: "+owner_name); // debug
        if (anim != "") llStopAnimation(anim); // <-- this works
  // if (anim != "") osAvatarStopAnimation(avi, anim); // <-- this fails
  // if (anim != "") osAvatarStopAnimation(avi, (string)anim); // <-- this fails
    }
    llSetTimerEvent(0.0); // disable timer
}
TagsNo tags attached.
Git Revision or version numberOSgrid 0.7.4 (Dev) 4186fa1: 2012-05-07 (Unix/Mono)
Run Mode Standalone (Multiple Regions)
Physics EngineBasicPhysics
EnvironmentMono / Linux64
Mono Version2.10
ViewerImprudence 1.4.0 beta 2
Attached Filespatch file icon 0002-Mantis-6028-osAvatarStopAnimation-not-stopping-anima.patch [^] (2,302 bytes) 2012-05-22 23:36 [Show Content]

- Relationships

-  Notes
(0021483)
Talun (manager)
2012-05-22 23:36
edited on: 2012-05-22 23:44

Patch attached to allow stopping of animations by UUID similar to llStopAnimation.
See http://opensimulator.org/wiki/OsAvatarStopAnimation [^]


Using llGetAnimationList may be overkill for stopping dance animations though, the script above will stop ALL animations e.g. holding a drink, tiny avatar compression animations etc. It may be better iterate through the dance animations in inventory and try to stop them one at a time by calling the function with either the dances UUID or name

(0021531)
justincc (administrator)
2012-05-26 00:14

Thanks Talun, applied as git master 120f814.
(0021742)
slow putzo (reporter)
2012-07-03 20:35
edited on: 2012-07-03 21:40

I believe that this patch broke the prior operation of this function.

I did not test this until the 6-30-2012 release of opensim on OSGrid and now this function does not stop animations when using the animation name.

Here is the routine I have been using to create an NPC for a very long time. It always stopped the "greeting" animation and went to the stand animation. Now the npc continues to do the greet animation all the time because the animation is not being stopped.

NpcCreate()
{
    if (npc != NULL_KEY) osNpcRemove (npc); // remove any previous NPC
    llSay(0,"Please wait while I create your NPC");
    // get the appearance notecard name and break it into parts
    list Parts = llParseString2List( selectappearance, [" ","-"],[]);
    NPCfname = llList2String(Parts, 1);
    NPClname = llList2String(Parts, 2);
    NPCgender = llList2String(Parts, 3);
    if (NPCgender != ("f" || "m")) NPCgender =""; // force to generic
    ReadAnimationFromNotecard(); // Get common animations based on gender
    npc = osNpcCreate(NPCfname, NPClname+"-NPC", NPChome, selectappearance,OS_NPC_CREATOR_OWNED);
    curlocname = homelocationname; //set the name of where the NPC is now at
    llSleep(1);
    osNpcSay(npc, "I'm at your service. How may I help you? My gender = "+NPCgender);
    MENU(ToucherID);
    osAvatarPlayAnimation(npc, greetanim);
    llSleep(3);
    osAvatarStopAnimation(npc, greetanim);
    osAvatarPlayAnimation(npc,standanim);
}

The wiki says you can use either the UUID or the animation name. Before the UUID did not work but the animation name did.

I have checked using two versions of the OSgrid release of opensim.

I tested using two ways to stop an animation in both releases.

    osAvatarStopAnimation(npc, llGetInventoryKey(greetanim)); //use animation UUID
    osAvatarStopAnimation(npc, greetanim); // use animation name

osgrid.opensim-04232012.v0.7.4.fd27988.zip

This release works just fine with the "use animation name" statement. The UUID statement does not work in this release.

osgrid.opensim-06302012.v0.7.4.1926de5.zip

In this release, neither versions of the statement work. That means the UUID version which previously did not work still does not work and the statement using the name now does not work either making this function a no-op.

(0021744)
Talun (manager)
2012-07-04 07:58

I just tried this using the script from the bottom of http://opensimulator.org/wiki/OSSLNPC [^] (with minor changes - see below)

I put a copy of the tpose animation (in the library) in the prim with the script, the portion of the npc script I changed changed is below.

It worked fine for both stop lines.
            else if (msg == "animate" && npc != NULL_KEY)
            {
                string anim = "tpose";
                osAvatarPlayAnimation(npc, anim);
                llSleep(3);
                osAvatarStopAnimation(npc, llGetInventoryKey(anim));
// osAvatarStopAnimation(npc, anim);
            }
(0021745)
Talun (manager)
2012-07-04 10:03

I have been gazing at the code differences between play and stop.

Are your animation names in the form of a UUID?

Changing the name of the animation from tpose to a random UUID that was not the animations actual UUID osAvatarStopAnimation(npc, anim) ceased working however osAvatarStopAnimation(npc, llGetInventoryKey(anim)) was successful in stopping the animation, you said above that neither works.
(0021748)
slow putzo (reporter)
2012-07-05 14:53

No, they were always in the form of the actual animation name. I tried to use the UUID form to see if it would possible stop the animation without any success.

The animation I am using is called "dance" it is just sosme animation I pulled from some opject since I was not really concerned with the visual at this point in my script development.

They are a string variable of the animation name contained in the controller prim. Everything is contained in the single prim. The animations, script, notecards and appearances.

I adopted an appearance name convention which identifies the gender of the NPC. The configuration notecard has animation names for: generic, male, and female, NPC's.

It is possible something else has caused this behaviour. I made the assumption it was this patch.

I am going to test each of the OSgrid releases of the opensim code to pinpoint exactly when it stopped working. I realized that there were afew releases between the current release and the one I used for my first test.

I'll report back as soon as I test all the releases.

It is correct that my script will not stop the animation with either stop statement in the current release.

I have moved my testing off the grid and am using a standalone which I have much faster "version change time" to.

Here is the routine I use to get the names of the animations from a notecard.
string walkanim = ""; //Walk animation name
string danceanim = ""; //Dance animation name
string greetanim = ""; //Greet animation name
string standanim = ""; //Stand animation name

ReadAnimationFromNotecard()
{
    integer notelength;
    integer idx;
    integer lineidx;
    string noteline;
    string settingname;
    string settingvalue;
    notelength = osGetNumberOfNotecardLines(NPC_CONFIG);
    
    for (idx=1; idx<=notelength; idx++)
    {
        noteline = osGetNotecardLine(NPC_CONFIG, idx);
        if (llStringLength(noteline) >= 0)
        {
            if (llGetSubString(noteline,0,1) != "##")
            {
                lineidx = llSubStringIndex(noteline,"=");
                settingname = llGetSubString(noteline,0,lineidx-1);
                settingvalue = llGetSubString(noteline,lineidx+1, -1);
                if (settingname == NPCgender+"walk")
                {
                    walkanim = settingvalue;
                }
                else if (settingname == NPCgender+"dance")
                {
                    danceanim = settingvalue;
                }
                else if (settingname == NPCgender+"stand")
                {
                    standanim = settingvalue;
                }
                else if (settingname == NPCgender+"greet")
                {
                    greetanim = settingvalue;
                }
                else
                {
                    //Add functionality by creating a setting in the config file, and adding code as above.
                }
            }
        }
    }
}
(0021749)
slow putzo (reporter)
2012-07-05 16:44
edited on: 2012-07-05 17:15

I completed testing the following 6 releases:

osgrid.opensim-04232012.v0.7.4.fd27988.zip UUID - n NAME - y
osgrid.opensim-05012012.v0.7.4.40f3c24.zip UUID - n NAME - y
osgrid.opensim-05072012.v0.7.4.4186fa1.zip UUID - n NAME - y
osgrid.opensim-05202012.v0.7.4.0db60ee.zip UUID - n NAME - y
osgrid.opensim-06022012.v0.7.4.729d901.zip UUID - n NAME - n
osgrid.opensim-06302012.v0.7.4.1926de5.zip UUID - n NAME - n

The UUID form of stop statement fails in all 6 release versions.
The name form stopped working in the first June release.

To be sure I had good test results, I did a recompile using the "tools" menu for every test after commenting out the statement line I did not want to test.

I will include the entire script for my controller so if you have any questions about what variables are being used you have a reference.

I'll also attach the config notecard.

-------------------- script ----------------------
// NPC controller
// Version 0.13 by Slow Putzo (27 April 2012)
// add male/female animations with gender identification
// removed first and last name from configuration file
// Version 0.12 by Slow Putzo (26 April 2012)
// appearance name includes gender, or generic identifier
// Version 0.11 by Slow Putzo (22 April 2012)
// Add test to avoid returning to same location if possible
// Version 0.10 by Slow Putzo (17 March 2012)
// Do not bring up the menu when "auto" has been selected
// Prevent NPC from doing repetative sit or animation activities
// Version 0.9 by Slow Putzo (10 March 2012)
// ------------------------------ Configuration variables -----------------------------------
string NPC_CONFIG = "config"; //Name of the bot configuration notecard
float TimerInterval; // pause time after arriving at a location in auto mode
//
//======================================== Variables ========================================
key npc; //our NPC key
key ToucherID; //key of avatar who touched to get menu
key targetsit; //key of sit target
string curlocname; //name of NPC's present location
string lastlocname; //name of NPC's last location
string keynote;
string NPCfname; //First name of npc
string NPClname; //Last name of npc
string NPCgender = "g"; // NPC gender, m=male, f=female, g=generic
string selectNPC; //Name for the NPC
string selectappearance; //NPC appearance Notecard
string walkanim = ""; //Walk animation name
string danceanim = ""; //Dance animation name
string greetanim = ""; //Greet animation name
string standanim = ""; //Stand animation name
string curanim = ""; //animation the NPC is currently performing
string homelocationname = ""; // name of location where config card sends bot at creation
string locationsNoteCard; //Name of locations Notecard
vector NPChome; //vector of the initial home location
list Waypointlocations; //List for waypoint's and their activitie NC names
list CloneList;
list buttons;
list buttonindex;
list Waypointactivities; //list of activities for a specific location
//list tempactivity; //list of activities for this waypoint
integer numappearance;
integer HANDLE;
integer RunAuto = 0; // flag to indicate if controller is in autorun mode
integer channel; //menu listen channel
integer sitting; // flag to indicate if NPC is on a sit target
integer animate; // flag to indicate if NPC is doing animation
integer hassit; // flag to indicate if NPC has done a sit target
integer hasanimate; // flag to indicate if NPC has done a animation
integer tryroute; // flag to do route. 0=ok not same, 3=ok same

//======================================== functions ========================================

ReadConfigFromNotecard()
{
    integer notelength;
    integer idx;
    integer lineidx;
    string noteline;
    string settingname;
    string settingvalue;
    notelength = osGetNumberOfNotecardLines(NPC_CONFIG);
    
    for (idx=1; idx<=notelength; idx++)
    {
        noteline = osGetNotecardLine(NPC_CONFIG, idx);
        if (llStringLength(noteline) >= 0)
        {
            if (llGetSubString(noteline,0,1) != "##")
            {
                lineidx = llSubStringIndex(noteline,"=");
                settingname = llGetSubString(noteline,0,lineidx-1);
                settingvalue = llGetSubString(noteline,lineidx+1, -1);
                if (settingname == "home")
                {
                    NPChome = (vector)settingvalue;
                }
                else if (settingname == "locations")
                {
                    locationsNoteCard = settingvalue;
                }
                else if (settingname == "homelocationname")
                {
                    homelocationname = settingvalue;
                }
                else
                {
                    //Add functionality by creating a setting in the config file, and adding code as above.
                }
            }
        }
    }
}


ReadAnimationFromNotecard()
{
    integer notelength;
    integer idx;
    integer lineidx;
    string noteline;
    string settingname;
    string settingvalue;
    notelength = osGetNumberOfNotecardLines(NPC_CONFIG);
    
    for (idx=1; idx<=notelength; idx++)
    {
        noteline = osGetNotecardLine(NPC_CONFIG, idx);
        if (llStringLength(noteline) >= 0)
        {
            if (llGetSubString(noteline,0,1) != "##")
            {
                lineidx = llSubStringIndex(noteline,"=");
                settingname = llGetSubString(noteline,0,lineidx-1);
                settingvalue = llGetSubString(noteline,lineidx+1, -1);
                if (settingname == NPCgender+"walk")
                {
                    walkanim = settingvalue;
                }
                else if (settingname == NPCgender+"dance")
                {
                    danceanim = settingvalue;
                }
                else if (settingname == NPCgender+"stand")
                {
                    standanim = settingvalue;
                }
                else if (settingname == NPCgender+"greet")
                {
                    greetanim = settingvalue;
                }
                else
                {
                    //Add functionality by creating a setting in the config file, and adding code as above.
                }
            }
        }
    }
}

GetLocationList()
{
        string noteline;
        integer notelength;
        integer lineidx;
        integer idx;
        noteline="";
        notelength = osGetNumberOfNotecardLines(locationsNoteCard);
        for(idx=1; idx<notelength; idx++)
        {
            noteline = osGetNotecardLine(locationsNoteCard, idx);
            if (llStringLength(noteline) >= 0)
            {
                if (llGetSubString(noteline,0,1) != "##")
                {
                    Waypointlocations += noteline; //generate list of valid NPC actions
                }
                else
                {
                    //llOwnerSay("ERROR: locationsNoteCard '" + locationsNoteCard + "' is formatted incorrectly.");
                }
            }
        }
}

DoNextActivity()
{
    //location list notecard name
    string nextlocname;
    integer idx1;

    integer listlength = llGetListLength(Waypointactivities); //get number of activities for this location
    integer rnum = RandIntBetween(1, listlength-1); // get a random activity from the list
    string notecard = llList2String(Waypointactivities,rnum); //get the notecard name for this activity
    string typeact = osGetNotecardLine(notecard, 0); //activity type
    string timeact = osGetNotecardLine(notecard, 1); //This activity time duration in seconds
    TimerInterval = (timeact); //Set the timer interval to this activity time
    if (typeact == "route" && tryroute<=2 ) //is this a route to where we just left
    { //walk this route if not the going back to same place
        nextlocname = llToUpper(llGetSubString(notecard, llSubStringIndex(notecard, "To")+2, -1)); //set the name to the location we go to next

 // llSay (0,"\ncurrnet location = "+curlocname+"\nnext location = "+nextlocname+"\nlast location = "+lastlocname); // Debug


        if (nextlocname!=lastlocname)
        {
        TestFlags(); // make sure NPC is standing before we move
        lastlocname=curlocname; //set our current location as our last location before we move
        hassit=0;
        hasanimate=0;
        AvatarWalkPath(notecard);
        }
                else
        {
 // llSay (0,"last location and next location the same"); // Debug
            ++tryroute; // step the times we have tried to do a route
            llSetTimerEvent(.04); //trigger the timer in the shortest time possible
            return;
        }
    }
        
    else if (typeact == "route" && tryroute>=3 ) //do this route
    { //walk this route
        TestFlags(); // make sure NPC is standing before we move
        lastlocname=curlocname; //set our current location as our last location before we move
        hassit=0;
        hasanimate=0;
        AvatarWalkPath(notecard);
    }
    else if (typeact == "sit") //is this activity a sit on pose ball
    {
        TestFlags(); // make sure NPC is standing if were siting or animating
        if (hassit == 0)
        {
            targetsit = osGetNotecardLine(notecard, 2);
            osAvatarStopAnimation(npc,walkanim);
            osAvatarStopAnimation(npc,standanim);
            sitting = 1; // set sitting flag
            hassit=1;
            osNpcSit(npc,targetsit,OS_NPC_SIT_NOW);
            llSetTimerEvent( TimerInterval);
        }
        else
        {
            llSetTimerEvent(.04); //trigger the timer in the shortest time possible
            return;
        }
        
    }
    else if (typeact == "animate") //is this activity an animation to perform
    {
        TestFlags(); // make sure NPC is standing if were siting or animating
        if (hasanimate == 0)
        {
        curanim = osGetNotecardLine(notecard, 2);
        osAvatarStopAnimation(npc,walkanim);
        osAvatarStopAnimation(npc,standanim);
        animate = 1; // set animation flag
        hasanimate=1;
        osAvatarPlayAnimation(npc, curanim);
        llSetTimerEvent(TimerInterval);
        }
        else
        {
            llSetTimerEvent(.04); //trigger the timer in the shortest time possible
            return;
        }
    }
}

integer randInt(integer n)
{
     return (integer)llFrand(n + 1);
}

integer RandIntBetween(integer min, integer max)
{
    return min + randInt(max - min);
}

list AppearanceList()
{
    // Get a list of all the appearances in controller
    list result = [];
    string name;
    integer n = llGetInventoryNumber(INVENTORY_NOTECARD);
 
    while(n)
    {
        name = llGetInventoryName(INVENTORY_NOTECARD, --n);
        if (llGetSubString(name, 0, 9) == "appearance")
        result = name + result;
    }
    numappearance = llGetListLength(result);
    return result;
}

AvatarWalkPath(string notecard)
{
    //WALK PATH CODE
    string currentloc;
    vector curPos;
    vector vecTo_targ;
    vector nPos;
    list path;
    integer path_length;
    integer pad_Turn = 3; // Larger the number smoother the turn, but less accurate
                          // Smaller the number more accurate but sharper noticeable stop/turn
    integer i;
    tryroute=0; // clear the number of trys to do a route
    for(i=1; i<osGetNumberOfNotecardLines(notecard); i++)
    {
      path += osGetNotecardLine(notecard, i);
    } // Grab path vectors from notecard and pack into list
    path_length=llGetListLength(path);
    integer x;
    for (x = 3; x < path_length; x++)
    {
        vecTo_targ = llList2Vector(path,x);
        nPos = osNpcGetPos(npc);
        if (vecTo_targ.x > 1)
        {
            osAvatarStopAnimation(npc,standanim);
            osAvatarPlayAnimation(npc,walkanim);
            osNpcSetRot(npc, llRotBetween(<PI,PI,0>,llVecNorm(vecTo_targ - osNpcGetPos(npc))));
            osNpcMoveToTarget(npc, vecTo_targ, OS_NPC_NO_FLY);
            while (llFabs(llVecDist(vecTo_targ, nPos)) > pad_Turn)
            {
                    nPos = osNpcGetPos(npc);
                    llSleep(.4);
            } // Probably a lower lag way to do this with states or something
                // This also locks out the script until the loop is complete
        }
        currentloc = llGetSubString(notecard, llSubStringIndex(notecard, "To")+2, -1);
        curlocname = llToUpper(currentloc); //set the name to the location where we have stopped
    }
    osAvatarStopAnimation(npc,walkanim);
    if (TimerInterval == 0)
    {
        llSetTimerEvent(.04); //trigger the timer in the shortest time possible
    }
    else
    {
        llSleep(1);
        osAvatarPlayAnimation(npc,standanim);
        llSetTimerEvent( TimerInterval );
    }
}

TestFlags()
{
    if (sitting == 1) // if NPC is sitting on a target, be sure they are standing for new command
    {
        osNpcStand(npc);
        llSleep(3);
        sitting = 0; // remove sitting state
        osAvatarPlayAnimation(npc,standanim);
    }
    if (animate == 1) // if NPC is sitting on a target, be sure they are standing for new command
    {
        osAvatarStopAnimation(npc,curanim);
        llSleep(3);
        animate = 0; // remove animate state
        osAvatarPlayAnimation(npc,standanim);
    }
}

NpcCreate()
{
    if (npc != NULL_KEY) osNpcRemove (npc); // remove any previous NPC
    llSay(0,"Please wait while I create your NPC");
    // get the appearance notecard name and break it into parts
    list Parts = llParseString2List( selectappearance, [" ","-"],[]);
    NPCfname = llList2String(Parts, 1);
    NPClname = llList2String(Parts, 2);
    NPCgender = llList2String(Parts, 3);
    if (NPCgender != ("f" || "m")) NPCgender ="g"; // force to generic
    ReadAnimationFromNotecard(); // Get common animations based on gender
    npc = osNpcCreate(NPCfname, NPClname+"-NPC", NPChome, selectappearance,OS_NPC_CREATOR_OWNED);
    curlocname = homelocationname; //set the name of where the NPC is now at
    llSleep(1);
    osNpcSay(npc, "I'm at your service. How may I help you? My gender = "+NPCgender);
    MENU(ToucherID);
    osAvatarPlayAnimation(npc, greetanim);
    llSleep(3);
    osAvatarStopAnimation(npc, llGetInventoryKey(greetanim));
    //osAvatarStopAnimation(npc, greetanim);
    osAvatarPlayAnimation(npc,standanim);
}

AutoPilot()
{
    //AUTOPILOT CODE
    integer idx1;

    integer listlength=llGetListLength(Waypointlocations); //get the number of Waypoint entries in list
    // Get a list of the activities for the Waypoint we are at
    for (idx1=0; idx1<listlength; idx1++)
    {
        string listitem = llList2String(Waypointlocations,idx1); //get a entry from the Waypoint list
        string Waypointname = llToUpper(llGetSubString(listitem,0,llSubStringIndex(listitem,",")-1)); //get entry Waypoint name
        Waypointactivities = llCSV2List(listitem); //build a list of this Waypoint activities
        if (llToUpper(Waypointname) == llToUpper(curlocname)) //Do we have the entry for the Waypoint we are at?
        { //perform activity for this Waypoint
            idx1=listlength; //set index to end of list to end the for loop. activities for this Waypoint found
        }
    }
    DoNextActivity();
}

MENU(key id) // Menu
{
    string msg = "You must select a NPC before you can do any other commands\nSelected clone = ";
    buttons = ["Dance Ball","Ball Stop","Kill All","AUTO","Stop AUTO","Go","Select NPC","Remove"];
    llListenRemove(HANDLE); // Safety kill listener incase left over
    HANDLE = llListen(channel, "", ToucherID, ""); // listen for dialog answers
    //
    llDialog(id,msg+selectNPC,buttons,channel);
}

MENUNPC(key id) // Menu
{
    string msg = "Select a NPC for this controller\nSelected clone = ";
    buttons = ["MAIN MENU","Jonh","Reporter","Gem","April","Slow","Jenna","Molly","Noah","Redhead","Tess","Walter"];
    llListenRemove(HANDLE); // Safety kill listener incase left over
    HANDLE = llListen(channel, "", ToucherID, ""); // listen for dialog answers
    //
    llDialog(id,msg+selectNPC,buttons,channel);
}


// testing some code to build clone selection list
get_buttons() {
    integer ix;
    string name;
    for (ix = 0; ix < llGetListLength(buttons); ++ix) {
        name = llList2String(buttons, ix);
        if (((integer)llList2String(buttons, ix)) != 0) {
            
        }
    }
}

//======================================== code ========================================
default
{
    state_entry()
    {
        llSetText("Touch for Menu", <1,1,1>, 1.5);
        channel = ( -1 * (integer)("0x"+llGetSubString((string)llGetKey(),-5,-1)) ); //get a random unique channel number
        ReadConfigFromNotecard(); // Get the configuration information
        ReadAnimationFromNotecard(); // Get common animations
        GetLocationList(); // Populate the NPC locations
        RunAuto = 0;
    }

  touch_start(integer number)
    {
        ToucherID = llDetectedKey(0);
        MENU(ToucherID); // Display the menu
    }

    listen(integer channel, string name, key id, string msg)
    {
        llListenRemove(HANDLE); HANDLE = 0; // Kill listen reduce Lag
        if (msg != "")
        {
            if (sitting == 1) // if NPC is sitting on a target, be sure they are standing for new command
            {
            osNpcStand(npc);
            llSleep(3);
            sitting = 0;
            osAvatarPlayAnimation(npc,standanim);
            }
            // Remove this NPC from the region
            if (msg == "Remove" && npc != NULL_KEY)
            {
                osNpcSay(npc, "Goodbye!!");
                osNpcRemove (npc);
                llSetTimerEvent(0);
                RunAuto = 0;
                MENU(ToucherID);
            }
            // Remove all NPC's from this region
            else if (msg == "Kill All")
            {
                MENU(ToucherID);
                list avatars = llList2ListStrided(osGetAvatarList(), 0, -1, 3);
                integer i;
                llSay(0,"NPC Removal: No avatars will be harmed or removed in this process!");
                llSetTimerEvent(0);
                RunAuto = 0;
                for (i=0; i<llGetListLength(avatars); i++)
                {
                    string target = llList2String(avatars, i);
                    osNpcRemove(target);
                    llSay(0,"NPC Removal: Target "+target);
                }
            }
            else if (msg == "Go" && npc != NULL_KEY)
            {
                MENU(ToucherID);
                AutoPilot();
            }
            else if (msg == "AUTO" && npc != NULL_KEY)
            {
                llSay(0, "Auto NPC is taking control of "+selectNPC);
                RunAuto = 1;
                AutoPilot();
            }
            else if (msg == "Stop AUTO" && npc != NULL_KEY)
            {
                MENU(ToucherID);
                llSay(0, "Auto NPC is giving up control of "+selectNPC);
                RunAuto = 0;
            }
            else if (msg == "Dance" && npc != NULL_KEY)
            {
                MENU(ToucherID);
                osAvatarPlayAnimation(npc, danceanim);
            }
            else if (msg == "Dance Stop" && npc != NULL_KEY)
            {
                MENU(ToucherID);
                osAvatarStopAnimation(npc, danceanim);
            }
            else if (msg == "Dance Ball" && npc != NULL_KEY)
            {
                MENU(ToucherID);
                targetsit = "eaf047f5-9b60-4e1b-b679-38edde58e578";
                osAvatarStopAnimation(npc,walkanim);
                osAvatarStopAnimation(npc,standanim);
                sitting = 1; // set sitting flag
                hassit=1;
                osNpcSit(npc,targetsit,OS_NPC_SIT_NOW);
            }
            else if (msg == "Ball Stop" && npc != NULL_KEY)
            {
                MENU(ToucherID);
                TestFlags(); // make sure NPC is standing before we move
            }
            else if (msg == "Slow" && npc != NULL_KEY)
            {
                selectNPC = "Slow";
                selectappearance = "appearance-Slow Putzo-m-2011-11-17";
                NpcCreate();
            }
            else if (msg == "Gem" && npc != NULL_KEY)
            {
                selectNPC = "Gem";
                selectappearance = "appearance-gemini17 rising-f-2011-11-13";
                NpcCreate();
            }
            else if (msg == "April" && npc != NULL_KEY)
            {
                selectNPC = "April";
                selectappearance = "appearance-April King-f-2011-11-12";
                NpcCreate();
            }
            else if (msg == "Jenna" && npc != NULL_KEY)
            {
                selectNPC = "Jenna";
                selectappearance = "appearance-jenna yexil-f-2011-11-17";
                NpcCreate();
            }
            else if (msg == "Jonh" && npc != NULL_KEY)
            {
                selectNPC = "Jonh";
                selectappearance = "appearance-jonh Charlie-m-2012-01-11";
                NpcCreate();
            }
            else if (msg == "Molly" && npc != NULL_KEY)
            {
                selectNPC = "Molly";
                selectappearance = "appearance-Molly Malone-f-2011-12-06";
                NpcCreate();
            }
            else if (msg == "Noah" && npc != NULL_KEY)
            {
                selectNPC = "Noah";
                selectappearance = "appearance-Noah MacMoragh-m-2011-12-10";
                NpcCreate();
            }
            else if (msg == "Reporter" && npc != NULL_KEY)
            {
                selectNPC = "Reporter";
                selectappearance = "appearance-OSGazet Reporte-fr-2011-11-26";
                NpcCreate();
            }
            else if (msg == "Redhead" && npc != NULL_KEY)
            {
                selectNPC = "Redhead";
                selectappearance = "appearance-redhead tiptoe-f-2011-11-18";
                NpcCreate();
            }
            else if (msg == "Tess" && npc != NULL_KEY)
            {
                selectNPC = "Tess";
                selectappearance = "appearance-Tess Zahm-f-2011-12-09";
                NpcCreate();
            }
            else if (msg == "Walt" && npc != NULL_KEY)
            {
                selectNPC = "Walt";
                selectappearance = "appearance-Walt Walters-m-2011-11-26";
                NpcCreate();
            }
            else if (msg == "stop" && npc != NULL_KEY)
            {
                MENU(ToucherID);
                osNpcStopMoveToTarget(npc);
            }
            else if (msg == "MAIN MENU")
            {
                MENU(ToucherID);
            }
            else if (msg == "Select NPC")
            {
                MENUNPC(ToucherID);
            }
            else
            {
                MENU(ToucherID);
                llOwnerSay("I don't understand [" + msg + "]");
            }
        }
    }
    
    // Poll the region every x seconds (as configured by the TimerInterval variable). Rather than using
    // sensors, which are limited both in range and in the number of avatars they can detect, we'll use
    // the OpenSim-only function osGetAgents().
    //
    timer()
    {
        if (RunAuto == 1) {
          llSetTimerEvent(0); //disable timer events
          AutoPilot();
        }
    }
}


------------------------ config notecard ---------------------

## NPC Configuration File V.0.13
##
##This file contains basic configuration information for your NPC, such as home starting location, and the name of a notecard
##defining routes for paths and activities.
##
##Comments are delineated by a '##' at the beginning of the line. There should be no blank or empty lines.
##
## Each line contains one setting, in the format 'Property=Value'.
##
##
##home=<41, 81, 22> (The vector of the location on your sim where you NPC will be rezzed to)
home=<40, 83, 22>
##homelocationname=FRONTYARD (The location name of the above vector. Must be in upper case, and be a location in your activities card).
homelocationname=FRONTYARD
##locations=activities (The name of your activities note card. While you can change this it is recommended you do not).
locations=activities
## You must provide whatever animations you define here inside the controller.
## female gender animations
fdance=rock dance m
fwalk=walkAnim1
fstand=bdstand1
fgreet=dance
## male gender animations
mdance=rock dance m
mwalk=walk male 3
mstand=stand4
mgreet=dance
## generic animations if gender is missing
dance=rock dance m
walk=walk1
stand=stand4
greet=dance

(0021750)
slow putzo (reporter)
2012-07-05 16:57

None of the animations I use are in the library. Reading the LSL wiki there are some comments about using the UUID for animations and referencing animations that are in the library.

I wonder if that is why your test worked?

The LSL wiki also says that the UUID can not be used to start an animation, only the anamation name can be used and it must be in the prim. I guess that ensurs you own the anamation and have the right to use it.

This fails both on my standalone and on the grid.
(0021751)
Talun (manager)
2012-07-05 17:34

I will get a different animation to try, there are some free to use/distribute ones available. If it still works with that I will attache a copy of the bvh and my much simpler test script for you to try
(0021752)
slow putzo (reporter)
2012-07-05 17:42

Another thought. The dance animation is a looped animation. I suspect the T-pose is a static animation. I will try using the T-pose but I bet what has happened is that after the patch it is not stopping a looped animation.

It's just a guess on my part. I'll post what I see using the T-pose animation.
(0021753)
slow putzo (reporter)
2012-07-05 17:59

Talun, hold on. It is something to do with the specific animation.

I tried both different static and looped animations and they both work using both stop statments.

It is very odd though. The "dance" animation I randomly selected worked just fine in the version before the patch, but now will not stop.

It is a full perm animation would there be any way to send you that animation to see if it is something only with that animation or is it affecting a "type" on animation?

I would only need you ID inworld and I can send you the animation.
(0021754)
slow putzo (reporter)
2012-07-05 18:10

I have tested several looped animations now and they all work just fine.

What are the odds I could pick one bad animation out of a list of dozens that this change fails on. lol

Do you think it is the specific animation or does the change make some tighter restrictions on the animation used?
(0021755)
Talun (manager)
2012-07-05 19:34

yay problem solved then :)

The change was to check the animation name and if it was a UUID use that UUID to stop the animation otherwise check the prims inventory and use the UUID of the animation found. That is why it fails if the animations name is in the form of a UUID.
Before my change it only checked inventory

I will set this back to resolved and do a fresh one for the (unlikely) use of a UUID for an animation name

- Issue History
Date Modified Username Field Change
2012-05-22 20:05 slow putzo New Issue
2012-05-22 23:36 Talun Note Added: 0021483
2012-05-22 23:36 Talun File Added: 0002-Mantis-6028-osAvatarStopAnimation-not-stopping-anima.patch
2012-05-22 23:37 Talun Status new => patch included
2012-05-22 23:44 Talun Note Edited: 0021483 View Revisions
2012-05-26 00:14 justincc Note Added: 0021531
2012-05-26 00:14 justincc Status patch included => resolved
2012-05-26 00:14 justincc Resolution open => fixed
2012-05-26 00:14 justincc Assigned To => justincc
2012-07-03 20:35 slow putzo Note Added: 0021742
2012-07-03 20:35 slow putzo Status resolved => patch feedback
2012-07-03 20:38 slow putzo Note Edited: 0021742 View Revisions
2012-07-03 21:36 slow putzo Note Edited: 0021742 View Revisions
2012-07-03 21:40 slow putzo Note Edited: 0021742 View Revisions
2012-07-04 07:58 Talun Note Added: 0021744
2012-07-04 10:03 Talun Note Added: 0021745
2012-07-05 14:53 slow putzo Note Added: 0021748
2012-07-05 16:44 slow putzo Note Added: 0021749
2012-07-05 16:57 slow putzo Note Added: 0021750
2012-07-05 17:08 slow putzo Note Edited: 0021749 View Revisions
2012-07-05 17:11 slow putzo Note Edited: 0021749 View Revisions
2012-07-05 17:15 slow putzo Note Edited: 0021749 View Revisions
2012-07-05 17:34 Talun Note Added: 0021751
2012-07-05 17:42 slow putzo Note Added: 0021752
2012-07-05 17:59 slow putzo Note Added: 0021753
2012-07-05 18:10 slow putzo Note Added: 0021754
2012-07-05 19:34 Talun Note Added: 0021755
2012-07-05 19:35 Talun Status patch feedback => closed


Copyright © 2000 - 2012 MantisBT Group
Powered by Mantis Bugtracker