Linksets in SecondLife (2)


Before approaching the script to make links securely while maintaining the original order, I will explain a trick to do it without scripts.

  1. Rez the object you want to add and link it to a newly created primitive.
  2. Link the target object (for example the car) to the newly created object.
  3. Unlink the root prim, that is, the primitive you just created.


And that's all. If you have experimented with the LinkSpy.lsl script on all primitives you will see that the order is correct.

Using the script that I created the instructions are a bit more complex, there are six steps instead of three.

  1. Put the JJReLink script in the inventory of object.
  2. Click the object.
  3. Object will ask for link permissions. click on Yes
  4. Link object you can add to linkset. (Ctrl + L)
  5. Click on object again.
  6. Remove JJReLink script and check that everything is working


Warning: This script to work temporarily breaks all links. Make sure your object is not physical before use, or all parts will fall to the ground.



Script: JJRelink.lsl


list g_lLinks = [];
list g_lPhysics = [];
integer g_iNumberOfPrims;
list g_lStopped = [];

default
{
    state_entry()
    {
       llOwnerSay("clickme to memorize links");
    }

    touch_end(integer total_number)
    {
        g_lLinks = [];
        g_lPhysics = [];
        g_lStopped = [];
        g_iNumberOfPrims = llGetNumberOfPrims();
        llOwnerSay("There are " + (string) g_iNumberOfPrims + " prims in linkset.");
        integer iNumLink;
        for (iNumLink = 2; iNumLink <= g_iNumberOfPrims; iNumLink++) 
        {
            key kKey = llGetLinkKey(iNumLink);
            g_lLinks = g_lLinks + [ kKey ];
            
            list lResult = llGetLinkPrimitiveParams(iNumLink, [ PRIM_PHYSICS_SHAPE_TYPE ]);
            integer iTipo = llList2Integer(lResult, 0);            
            g_lPhysics = g_lPhysics + [ iTipo ];
        }
        
        //llOwnerSay("DEBUG: " + llDumpList2String(g_lLinks, ", "));
        llRequestPermissions(llGetOwner(), PERMISSION_CHANGE_LINKS);
    }
    
    run_time_permissions(integer perm) 
    {
        if ((perm & PERMISSION_CHANGE_LINKS) == PERMISSION_CHANGE_LINKS)
        {
            state NextStep;
        }
    }
    
}


state NextStep
{
    state_entry()
    {
        llOwnerSay(" --> Stopping running scripts in root prim.");
        integer iNumScripts = llGetInventoryNumber(INVENTORY_SCRIPT);
        
        integer iNScript;
        for(iNScript = 0; iNScript < iNumScripts; iNScript++) 
        {
            string sScriptName = llGetInventoryName(INVENTORY_SCRIPT, iNScript);
            if (sScriptName != llGetScriptName())
            {
                integer iState = llGetScriptState(sScriptName);
                if (iState == TRUE) 
                {
                    llSetScriptState(sScriptName, FALSE);
                    g_lStopped = g_lStopped + [ sScriptName ];
                }
            }
        }
        
       llOwnerSay("Ok, link your prims and clickme");
    }
    
    state_exit()
    {
        llOwnerSay(" --> Restoring script states.");
        
        integer iCounter;
        integer iStopped = llGetListLength(g_lStopped);
        for (iCounter = 0; iCounter < iStopped; iCounter++) 
        {
            string sScriptName = llList2String(g_lStopped, iCounter);
            llSetScriptState(sScriptName, TRUE);
        }
        
        llOwnerSay("... done ... You can removeme or start the process again");
        
    }
    
    touch_end(integer total_number)
    {
        integer iNewNumber = llGetNumberOfPrims();
        
        if (iNewNumber == g_iNumberOfPrims)
        {
            llOwnerSay("Only add new prims supported");
            return;
        }
        
        
        llOwnerSay(" --> Detecting new links.");
        
        list lNewLinks = [];
        list lTipos = [];
        integer iNumLink;
        for (iNumLink = 2; iNumLink <= iNewNumber; iNumLink++) 
        {
            key kKey = llGetLinkKey(iNumLink);
            //llOwnerSay("DEBUG--> Link: " + (string) iNumLink + " UUID: " + (string)kKey);
            
            if (llListFindList(g_lLinks, [ kKey ]) < 0)
            {
                lNewLinks = lNewLinks + [ kKey ];
                
                list lResult = llGetLinkPrimitiveParams(iNumLink, [ PRIM_PHYSICS_SHAPE_TYPE ]);
                integer iTipo = llList2Integer(lResult, 0);            
                lTipos = lTipos + [ iTipo ];
            }
        }
        
        //llOwnerSay("DEBUG: " + llDumpList2String(lNewLinks, ", "));
        llOwnerSay(" --> Breaking linkset");
        llBreakAllLinks();
        
        llOwnerSay(" --> Adding new Links");
        
        integer iCounter;
        integer iMax = llGetListLength(lNewLinks);
        for (iCounter = 0; iCounter < iMax; iCounter++) 
        {
            key kKey = llList2Key(lNewLinks, iCounter);
            llOwnerSay("Adding ... " + (string) iCounter + " Max: " + (string) iMax + "  " + (string) kKey);
            llCreateLink(kKey, TRUE);
            integer iTipo = llList2Integer(lTipos, iCounter);
            llSetLinkPrimitiveParams(2, [ PRIM_PHYSICS_SHAPE_TYPE, iTipo]);
        }

        llOwnerSay(" --> Adding old Links");
        
        //integer iOffset = iMax + 1;
        iMax = llGetListLength(g_lLinks) - 1;
        for (iCounter = iMax; iCounter >= 0; iCounter --)
        {
            key kKey = llList2Key(g_lLinks, iCounter);
            llOwnerSay("Adding ... " + (string) iCounter + " Max: " + (string) iMax + "  " + (string) kKey);
            llCreateLink(kKey, TRUE);
            integer iTipo = llList2Integer(g_lPhysics, iCounter);
            llSetLinkPrimitiveParams(2, [ PRIM_PHYSICS_SHAPE_TYPE, iTipo]);
        } 
        
        state default;
        
    }
    
    
}

Comments

Popular posts from this blog

About the death and rebirth of my auto greeter

Linksets in SecondLife (1)