User:Kisamin Resident

From Second Life Wiki
Jump to navigation Jump to search

More Efficient AO

In April, Linden Labs released some new LSL functions specifically designed for AOs. While they fall short of the full functionality of a ZHAO or similar, they provide almost all of the things we need to do. If you do not need the following overrides, then you should be able to use this instead.

The omitted override functionality are:

  1. Typing
  2. Swimming

A fast test gave a factor of 20 for this AO over a ZHAO (i.e. a ZHAO used 20 times more computer resources than this code). It is designed to read ZHAO configuration cards. There is still a bunch of work to be done to clean this up and make it fully usable. Right now it has simple on/off abilities as well as placeholders for adding more functionality.

I wrote this "quick and dirty" to test it out, and am now using it as my main AO.

Note that this is a work in progress. Check back here for updates.

string  g_sConfigCardName;
integer g_iConfigCardLine;

string  g_sTypingAnimationSpecification = "Typing";

float   g_fChangeAnimsTime = 30.;

list    g_lStanding;
list    g_lWalking;
list    g_lSitting;
list    g_lSittingOnGround;
list    g_lCrouching;
list    g_lCrouchWalking;
list    g_lLanding;
list    g_lStandingUp;
list    g_lFalling;
list    g_lFlyingDown;
list    g_lFlyingUp;
list    g_lFlying;
list    g_lHovering;
list    g_lJumping;
list    g_lPreJumping;
list    g_lRunning;
list    g_lTurningRight;
list    g_lTurningLeft;
list    g_lFloating;
list    g_lSwimmingForward;
list    g_lSwimmingUp;
list    g_lSwimmingDown;
list    g_lTyping;

dump (string in_sLabel, list in_lAnims) {
    llSay (0, in_sLabel);
    if (in_lAnims == [])
        llSay (0, "<Empty>");
    else
        llSay (0, llDumpList2String (in_lAnims, "--"));
}

integer index (list in_lList) {
    integer i = llGetListLength (in_lList);
    if (i == 0)
        return -1;
    return (integer)llFrand (i);
}

selectAnims() {
    integer i;
    i = index(g_lStanding);

    if (i == -1)
        llResetAnimationOverride ("Standing");
    else
        llSetAnimationOverride( "Standing", llList2String (g_lStanding, i));
        
    i = index(g_lWalking);
    if (i == -1)
        llResetAnimationOverride ("Walking");
    else
        llSetAnimationOverride( "Walking", llList2String (g_lWalking, i));

    i = index(g_lSitting);
    if (i == -1)
        llResetAnimationOverride ("Sitting");
    else
        llSetAnimationOverride( "Sitting", llList2String (g_lSitting, i));

    i = index(g_lSittingOnGround);
    if (i == -1)
        llResetAnimationOverride ("Sitting on Ground");
    else
        llSetAnimationOverride( "Sitting on Ground", llList2String (g_lSittingOnGround, i));

    i = index(g_lCrouching);
    if (i == -1)
        llResetAnimationOverride ("Crouching");
    else
        llSetAnimationOverride( "Crouching", llList2String (g_lCrouching, i));

    i = index(g_lCrouchWalking);
    if (i == -1)
        llResetAnimationOverride ("CrouchWalking");
    else
        llSetAnimationOverride( "Crouch Walking", llList2String (g_lCrouchWalking, i));

    i = index(g_lLanding);
    if (i == -1)
        llResetAnimationOverride ("Landing");
    else
        llSetAnimationOverride( "Landing", llList2String (g_lLanding, i));

    i = index(g_lStandingUp);
    if (i == -1)
        llResetAnimationOverride ("Standing Up");
    else
        llSetAnimationOverride( "Standing Up", llList2String (g_lStandingUp, i));

    i = index(g_lFalling);
    if (i == -1)
        llResetAnimationOverride ("Falling Down");
    else
        llSetAnimationOverride( "Falling Down", llList2String (g_lFalling, i));

    i = index(g_lFlyingDown);
    if (i == -1)
        llResetAnimationOverride ("Hovering Down");
    else
        llSetAnimationOverride( "Hovering Down", llList2String (g_lFlyingDown, i));

    i = index(g_lFlyingUp);
    if (i == -1)
        llResetAnimationOverride ("Hovering Up");
    else
        llSetAnimationOverride( "Hovering Up", llList2String (g_lFlyingUp, i));

    i = index(g_lFlying);
    if (i == -1)
        llResetAnimationOverride ("Flying");
    else
        llSetAnimationOverride( "Flying", llList2String (g_lFlying, i));

    i = index(g_lHovering);
    if (i == -1)
        llResetAnimationOverride ("Hovering");
    else
        llSetAnimationOverride( "Hovering", llList2String (g_lHovering, i));

    i = index(g_lJumping);
    if (i == -1)
        llResetAnimationOverride ("Jumping");
    else
        llSetAnimationOverride( "Jumping", llList2String (g_lJumping, i));

    i = index(g_lPreJumping);
    if (i == -1)
        llResetAnimationOverride ("PreJumping");
    else
        llSetAnimationOverride( "PreJumping", llList2String (g_lPreJumping, i));

    i = index(g_lRunning);
    if (i == -1)
        llResetAnimationOverride ("Running");
    else
        llSetAnimationOverride( "Running", llList2String (g_lRunning, i));

    i = index(g_lTurningRight);
    if (i == -1)
        llResetAnimationOverride ("Turning Right");
    else
        llSetAnimationOverride( "Turning Right", llList2String (g_lTurningRight, i));

    i = index(g_lTurningLeft);
    if (i == -1)
        llResetAnimationOverride ("Turning Left");
    else
        llSetAnimationOverride( "Turning Left", llList2String (g_lTurningLeft, i));

    /* THe following aren't currently used.
    i = index(g_lFloating);
    if (i == -1)
        llResetAnimationOverride ("Standing");
    else
        llSetAnimationOverride( "Standing", llList2String (g_lStanding, i);

    i = index(g_lSwimmingForward);
    if (i == -1)
        llResetAnimationOverride ("Standing");
    else
        llSetAnimationOverride( "Standing", llList2String (g_lStanding, i);

    i = index(g_lSwimmingUp);
    if (i == -1)
        llResetAnimationOverride ("Standing");
    else
        llSetAnimationOverride( "Standing", llList2String (g_lStanding, i);

    i = index(g_lSwimmingDown);
    if (i == -1)
        llResetAnimationOverride ("Standing");
    else
        llSetAnimationOverride( "Standing", llList2String (g_lStanding, i);

    i = index(g_lTyping);
    if (i == -1)
        llResetAnimationOverride ("Typing");
    else
        llSetAnimationOverride( "Typing", llList2String (g_lTyping, i));
*/
}

default {
    state_entry() {
        integer i;
        
        if (llGetInventoryType (".Default") == INVENTORY_NOTECARD)
            g_sConfigCardName = ".Default";
        else {
            list l_lNames;
            for (i=0; i<llGetInventoryNumber (INVENTORY_NOTECARD); i++) {
                string l_sName = llGetInventoryName (INVENTORY_NOTECARD, i);
                if (llGetSubString (l_sName, 0, 0) == ".")
                    l_lNames += l_sName;
            }
        
            if (llGetListLength (l_lNames) > 1) {
                llDialog (llGetOwner(), "Pick animation set.", l_lNames, 1);
                llListen (1, "", llGetOwner(), "");
                return;
            } else
                g_sConfigCardName = llList2String (l_lNames, 0);
        }
        if (llGetInventoryType (g_sConfigCardName) != INVENTORY_NOTECARD) {
            llOwnerSay ("Configuration notecard " + g_sConfigCardName + " is not present.");
            return;
        }
        llOwnerSay ("Reading configuration card " + g_sConfigCardName);
        g_iConfigCardLine = 0;
        llGetNotecardLine (g_sConfigCardName, g_iConfigCardLine);
        llRequestPermissions (llGetOwner(), PERMISSION_OVERRIDE_ANIMATIONS);
    }
    
    run_time_permissions (integer in_iPermissions) {
        if (!(in_iPermissions & PERMISSION_OVERRIDE_ANIMATIONS)) {
            llOwnerSay ("Please allow me to override your animations in order to operate.");
            llRequestPermissions (llGetOwner(), PERMISSION_OVERRIDE_ANIMATIONS);
        }
    }
    
    dataserver (key in_kReadRequest, string in_sData) {
        if (in_sData == EOF) state run;
        list l_lParts = llParseString2List (in_sData, ["#"], []);
        in_sData = llStringTrim (llList2String (l_lParts, 0), STRING_TRIM);
        l_lParts = llParseString2List (in_sData, ["[", "]"], []);
        string l_sSection = llToUpper (llStringTrim (llList2String (l_lParts, 0), STRING_TRIM));
        
        if (l_sSection == "STANDING")
            g_lStanding += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "WALKING")
            g_lWalking += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "SITTING")
            g_lSitting += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "SITTING ON GROUND")
            g_lSittingOnGround += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "CROUCHING")
            g_lCrouching += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "CROUCH WALKING")
            g_lCrouchWalking += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "LANDING")
            g_lLanding += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "STANDING UP")
            g_lStandingUp += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "FALLING")
            g_lFalling += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "FLYING DOWN")
            g_lFlyingDown += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "FLYING UP")
            g_lFlyingUp += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "FLYING")
            g_lFlying += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "HOVERING")
            g_lHovering += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "JUMPING")
            g_lJumping += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "PRE JUMPING")
            g_lPreJumping += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "RUNNING")
            g_lRunning += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "TURNING RIGHT")
            g_lTurningRight += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "TURNING LEFT")
            g_lTurningLeft += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "FLOATING")
            g_lFloating += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "SWIMMING FORWARD")
            g_lSwimmingForward += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "SWIMMING UP")
            g_lSwimmingUp += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "SWIMMING DOWN")
            g_lSwimmingDown += llParseString2List (llList2String (l_lParts, 1), ["|"], []);
        else if (l_sSection == "TYPING")
            g_lTyping += llParseString2List (llList2String (l_lParts, 1), ["|"], []);

        llSetText ((string)g_iConfigCardLine, <1., 1., 1.>, 1.);
        llGetNotecardLine (g_sConfigCardName, ++g_iConfigCardLine);
    }

    touch_start(integer total_number) {
        llSay(0, "Touched.");
    }
    
    state_exit() {
        llSetText ("", <0., 0., 0.>, 0.);
    }
    
    attach (key in_kID) {
        llResetScript ();
    }
    
    changed (integer in_iChange) {
        if (in_iChange & (CHANGED_INVENTORY | CHANGED_OWNER))
            llResetScript ();
    }
}

state run {
    state_entry () {
        llSetColor (<0., 1., 0.>, ALL_SIDES);
        llSetTimerEvent (g_fChangeAnimsTime);
        selectAnims();
    }
    
    timer () {
        selectAnims();
    }
    
    touch_start (integer in_iNumTouchers) {
        if (llGetColor (0) == <0., 1., 0.>) {
            // Turn it off
            llResetAnimationOverride ("ALL");
            llSetColor (<1., 0., 0.>, ALL_SIDES);
            llSetTimerEvent (0.);
        } else {
            llSetColor (<0., 1., 0.>, ALL_SIDES);
            llSetTimerEvent (g_fChangeAnimsTime);
            selectAnims();
        }
    }
    
    changed (integer in_iChange) {
        if (in_iChange & (CHANGED_INVENTORY | CHANGED_OWNER))
            llResetScript ();
    }
    
    attach (key in_kWearer) {
        llRequestPermissions (in_kWearer, PERMISSION_OVERRIDE_ANIMATIONS);
    }
    
    run_time_permissions (integer in_iPerms) {
        if (!(in_iPerms & PERMISSION_OVERRIDE_ANIMATIONS)) {
            llOwnerSay ("I must have the permissions in order to operate.");
            llRequestPermissions (llGetOwner(), PERMISSION_OVERRIDE_ANIMATIONS);
        }
    }
}