Difference between revisions of "Primset script"

From Second Life Wiki
Jump to navigation Jump to search
Line 1: Line 1:
{
    //primset+++ - Includes support for llGet/SetLinkPrimitiveParams, linkset resize, llLinkParticleSystem, and
    //llSetKeyframeMotion
    // Used by the primcontrol HUD.


//primset+++ - Includes support for llGet/SetLinkPrimitiveParams, linkset resize, llLinkParticleSystem, and
    //This function typecasts a list of strings, into the types they appear to be.  
//llSetKeyframeMotion
    //Extremely useful for feeding user data into llSetPrimitiveParams
// Used by the primcontrol HUD.
    //It takes a list as an input, and returns that list, with all elements correctly typecast, as output
 
    //Written by Fractured Crystal, 27 Jan 2010, Commissioned by WarKirby Magojiro, this function is Public Domain
//This function typecasts a list of strings, into the types they appear to be.  
    //Modified by Rufus Darkfold to keep strings like <foo> instead of discarding them entirely from the output
//Extremely useful for feeding user data into llSetPrimitiveParams
    list list_cast(list in)
//It takes a list as an input, and returns that list, with all elements correctly typecast, as output
//Written by Fractured Crystal, 27 Jan 2010, Commissioned by WarKirby Magojiro, this function is Public Domain
//Modified by Rufus Darkfold to keep strings like <foo> instead of discarding them entirely from the output
list list_cast(list in)
{
    list out;
    integer i;
    integer l= llGetListLength(in);
    for (i=0; i < l; i++)
     {
     {
        string d= llStringTrim(llList2String(in,i),STRING_TRIM);
list out;
        if (d == "") out += "";
integer i;
        else
integer l= llGetListLength(in);
        {
for (i=0; i < l; i++)
            if (llGetSubString(d,0,0) == "<")
{
            {
    string d= llStringTrim(llList2String(in,i),STRING_TRIM);
                if (llGetSubString(d,-1,-1) == ">")
    if (d == "") out += "";
                {
    else
                    list s = llParseString2List(d,[","],[]);
    {
                    integer sl= llGetListLength(s);
if (llGetSubString(d,0,0) == "<")
                    if (sl == 3) {
{
                        out += (vector)d;
    if (llGetSubString(d,-1,-1) == ">")
                    } else if(sl == 4) {
    {
                        out += (rotation)d;
list s = llParseString2List(d,[","],[]);
                    } else
integer sl= llGetListLength(s);
                        out += [d];
if (sl == 3) {
                } else
    out += (vector)d;
                    out += [d];
} else if(sl == 4) {
            } else if (~llSubStringIndex(d,".")) {
    out += (rotation)d;
                out += (float)d;
} else
            } else {
    out += [d];
                integer lold = (integer)d;
    } else
                if ((string)lold == d) out += lold;
out += [d];
                else
} else if (~llSubStringIndex(d,".")) {
                {
    out += (float)d;
                    key kold = (key)d;
} else {
                    if (kold) out += [kold];
    integer lold = (integer)d;
                    else out += [d];
    if ((string)lold == d) out += lold;
                }
    else
            }
    {
        }
key kold = (key)d;
    }
if (kold) out += [kold];
   
else out += [d];
    //for (i = 0; i< llGetListLength(out); i++){
    }
    //    llOwnerSay("Element " + (string)i + " type is " + (string)llGetListEntryType(out, i)
}
    //                + " value is «" + llList2String(out,i) + "»");
    }
    //}
}
    return out;
}


integer dimTest( vector vr )
//for (i = 0; i< llGetListLength(out); i++){
{
//    llOwnerSay("Element " + (string)i + " type is " + (string)llGetListEntryType(out, i)
    return !( vr.x<0.01 || vr.y<0.01 || vr.z<0.01 || vr.x>64.0 || vr.y>64.0 || vr.z>64.0 );
//                + " value is «" + llList2String(out,i) + "»");
}
//}


resize_linkset( vector scal )
return out;
{
    integer primindx;
    list primP;
    vector s = llGetScale();
    integer validDim = dimTest( <scal.x*s.x,scal.y*s.y,scal.z*s.z> );
    for ( primindx = 2; primindx <= llGetNumberOfPrims(); primindx++ )
    {
        primP = llGetLinkPrimitiveParams( primindx, [PRIM_SIZE]);
        s = llList2Vector( primP, 0 );
        validDim = validDim && dimTest( <scal.x*s.x,scal.y*s.y,scal.z*s.z> );
     }
     }


     if ( validDim )
     integer dimTest( vector vr )
     {
     {
        s = llGetScale();
return !( vr.x<0.01 || vr.y<0.01 || vr.z<0.01 || vr.x>64.0 || vr.y>64.0 || vr.z>64.0 );
        llSetScale( <scal.x*s.x,scal.y*s.y,scal.z*s.z> );
        for ( primindx = 2; primindx <= llGetNumberOfPrims(); primindx++ )
        {
            primP = llGetLinkPrimitiveParams( primindx, [PRIM_SIZE, PRIM_POSITION]);
            vector primScale = llList2Vector( primP, 0 );
            primScale = <primScale.x*scal.x, primScale.y*scal.y, primScale.z*scal.z>;
            vector primPos = llList2Vector( primP, 1 ) - llGetPos();
            primPos = <primPos.x*scal.x, primPos.y*scal.y, primPos.z*scal.z>;
            llSetLinkPrimitiveParamsFast( primindx, [PRIM_SIZE, primScale, PRIM_POSITION, primPos/llGetRootRotation()]);
        }
     }
     }
    else llOwnerSay("No resize! Out of limit sizes are not accepted");
}


debugout(string msg)
    resize_linkset( vector scal )
{
    {
  llOwnerSay(msg);
integer primindx;
}
list primP;
vector s = llGetScale();
integer validDim = dimTest( <scal.x*s.x,scal.y*s.y,scal.z*s.z> );
for ( primindx = 2; primindx <= llGetNumberOfPrims(); primindx++ )
{
    primP = llGetLinkPrimitiveParams( primindx, [PRIM_SIZE]);
    s = llList2Vector( primP, 0 );
    validDim = validDim && dimTest( <scal.x*s.x,scal.y*s.y,scal.z*s.z> );
}


integer outchan =0;
if ( validDim )
reply(string msg)
{
{
    s = llGetScale();
    llRegionSayTo(llGetOwner(), outchan, msg);
    llSetScale( <scal.x*s.x,scal.y*s.y,scal.z*s.z> );  
    if (outchan) {
    for ( primindx = 2; primindx <= llGetNumberOfPrims(); primindx++ )
        debugout(msg);
    {
primP = llGetLinkPrimitiveParams( primindx, [PRIM_SIZE, PRIM_POSITION]);
vector primScale = llList2Vector( primP, 0 );
primScale = <primScale.x*scal.x, primScale.y*scal.y, primScale.z*scal.z>;
vector primPos = llList2Vector( primP, 1 ) - llGetPos();
primPos = <primPos.x*scal.x, primPos.y*scal.y, primPos.z*scal.z>;
llSetLinkPrimitiveParamsFast( primindx, [PRIM_SIZE, primScale, PRIM_POSITION, primPos/llGetRootRotation()]);
    }
}
else llOwnerSay("No resize! Out of limit sizes are not accepted");
     }
     }
}


integer channel = 884;
     debugout(string msg)
 
list subset;
integer hlis;
float timeout = 300; // stop listening after 5 minutes of inactivity
vector lastpos;
rotation lastrot;
 
default
{
     timer()
     {
     {
        if (hlis){
      llOwnerSay(msg);
            llOwnerSay("Deslecting " + llGetObjectName());
            llListenRemove(hlis);
            hlis = 0;
        }
     }
     }
      
 
     touch_start(integer num)
     integer outchan =0;
     reply(string msg)
     {
     {
        llSetTimerEvent(timeout);
llRegionSayTo(llGetOwner(), outchan, msg);
        llResetTime();
if (outchan) {
        if (!hlis) {
    debugout(msg);
            hlis =  llListen(channel, "", "", "");
}
            llOwnerSay(llGetObjectName() + " selected. Listening on channel " + (string)channel);
            return;
        }
        while (num--) {
            integer child=llDetectedLinkNumber(num);
            integer j = llListFindList(subset,[child]);
            if (~j) {
                llOwnerSay("Deselecting #" + (string)child);
                subset = llDeleteSubList(subset, j, j);
            } else {
                llOwnerSay("Selecting #" + (string)child);
                subset += child;
            }
        }
     }
     }


     listen(integer ch, string name, key id, string msg)
     integer channel = 884;
 
    list subset;
    integer hlis;
    float timeout = 300; // stop listening after 5 minutes of inactivity
    vector lastpos;
    rotation lastrot;
 
    default
     {
     {
        //llOwnerSay(msg + " from " + (string)id + " owned by " + (string)llGetObjectDetails(id, [OBJECT_OWNER]));
timer()
        if (llGetOwner() != id) {
{
            if (llList2Key(llGetObjectDetails(id, [OBJECT_OWNER]),0) != llGetOwner())
    if (hlis){
                return;
llOwnerSay("Deslecting " + llGetObjectName());
        }
llListenRemove(hlis);
hlis = 0;
    }
}
 
touch_start(integer num)
{
    llSetTimerEvent(timeout);
    llResetTime();
    if (!hlis) {
hlis =  llListen(channel, "", "", "");
llOwnerSay(llGetObjectName() + " selected. Listening on channel " + (string)channel);
return;
    }
    while (num--) {
integer child=llDetectedLinkNumber(num);
integer j = llListFindList(subset,[child]);
if (~j) {
    llOwnerSay("Deselecting #" + (string)child);
    subset = llDeleteSubList(subset, j, j);
} else {
    llOwnerSay("Selecting #" + (string)child);
    subset += child;
}
    }
}
 
listen(integer ch, string name, key id, string msg)
{
    //llOwnerSay(msg + " from " + (string)id + " owned by " + (string)llGetObjectDetails(id, [OBJECT_OWNER]));
    if (llGetOwner() != id) {
if (llList2Key(llGetObjectDetails(id, [OBJECT_OWNER]),0) != llGetOwner())
    return;
    }
 
    outchan = 0;
 
    if (msg == "") {
subset = [];
llSetTimerEvent(0.1);  // empty message = disconnect right away;
return;
    }
    llSetTimerEvent(timeout);
 
    if (llGetSubString(msg, 0, 0) == "/") {  // specify response channel
integer endch = llSubStringIndex(msg, " ");
outchan = (integer)llGetSubString(msg, 1, endch);
msg = llGetSubString(msg, endch+1, -1);
    }
 
    if (llGetSubString(msg,0,0) == "[") {
integer e = llSubStringIndex(msg, "]");
if (e > 1)
    subset = list_cast(llCSV2List(llGetSubString(msg, 1, e-1)));
else
    subset = [];
msg = llStringTrim(llGetSubString(msg, e+1, -1), STRING_TRIM_HEAD);
if (llList2String(subset,0) == "*") {
    integer i;
    subset = [];
    for (i=1; i<=llGetNumberOfPrims(); i++) subset += i;
}
    }
    list sub;
    list cmds;
    if (llGetSubString(msg,0,0) == "?") {
cmds = list_cast(llCSV2List(llGetSubString(msg, 1, -1)));
integer i;
list curr;
if (subset == []) // If not specified use root (or only) prim
    sub = [ (llGetNumberOfPrims() > 1) ];
else
    sub = subset;
 
debugout(llList2CSV(cmds));
for (i = 0; i<llGetListLength(sub); i++) {
    if (llGetListEntryType(sub,i) == TYPE_INTEGER){
integer j = llList2Integer(sub,i);
curr = llGetLinkPrimitiveParams(j, cmds);
reply("[" + (string)j + "] " + llList2CSV(curr));
    }     
    else //if (llGetListEntryType(subset,i) == TYPE_STRING)
    {
integer k;
string x=llList2String(sub,i);
list exp;
for (k=1; k<=llGetNumberOfPrims(); k++) {
    if (~llListFindList(llGetLinkPrimitiveParams(k,[PRIM_NAME,PRIM_DESC]),
[x]))
    {
curr = llGetLinkPrimitiveParams(k, cmds);
exp += k;
reply("[" + (string)k + "] " + llList2CSV(curr));
  }
}
debugout(x + " is " + llList2CSV(exp));
    }
 
}
return;
    }
    if (llGetSubString(msg,0,0) == "$") {
msg = llDeleteSubString(msg,0,0);
vector v = (vector)msg;
if (v == ZERO_VECTOR) {
    float scal=(float)msg;
    v = <scal,scal,scal>;
}
resize_linkset(v);
return;
    } else if (llGetSubString(msg,0,0) == "%") {
msg = llDeleteSubString(msg,0,0);
cmds = list_cast(llCSV2List(msg));
if (subset == [])
    sub = [LINK_SET];
else
    sub  = subset;


        outchan = 0;
debugout("ParticleSystem On " + llList2CSV(subset) +":\nCmds: "+ llDumpList2String(cmds,"; "));
       
integer i;
        if (msg == "") {
for (i = 0; i<llGetListLength(sub); i++) {
            subset = [];
    if (llGetListEntryType(sub,i) == TYPE_INTEGER)
            llSetTimerEvent(0.1); // empty message = disconnect right away;
llLinkParticleSystem(llList2Integer(sub,i), cmds);
            return;
    else //if (llGetListEntryType(subset,i) == TYPE_STRING)
        }
    {
        llSetTimerEvent(timeout);
integer k;
       
string x=llList2String(sub,i);
        if (llGetSubString(msg, 0, 0) == "/") { // specify response channel
list exp;
            integer endch = llSubStringIndex(msg, " ");
for (k=llGetNumberOfPrims(); k; k--) {
            outchan = (integer)llGetSubString(msg, 1, endch);
    if (~llListFindList(llGetLinkPrimitiveParams(k,[PRIM_NAME,PRIM_DESC]),[x]))
            msg = llGetSubString(msg, endch+1, -1);
    {
        }
llLinkParticleSystem(k, cmds);
exp += k;
    }
}
debugout(x + " is " + llList2CSV(exp));
    }
}
return;
    } else if (llGetSubString(msg,0,0) == "@") {
if (subset != []) {
    if (!~llListFindList(subset,[llGetNumberOfPrims() > 1]) && !~llListFindList(subset,[llGetObjectName()])) {
return;
    }
}
integer direction = KFM_FORWARD;
msg = llDeleteSubString(msg,0,0);
string pfx2 = llGetSubString(msg,0,0);
if ( pfx2 == "%") {
    direction = KFM_PING_PONG;
    msg = llDeleteSubString(msg,0,0);
} else if (pfx2 == "^")  {
    direction = KFM_REVERSE;
    msg = llDeleteSubString(msg,0,0);
} else if (pfx2 == "@") {
    if (msg = "@@") {
llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_STOP]);
llSetPos(lastpos);
llSetRot(lastrot);
return;
    }       
    llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_PAUSE]);
    return;
} else if (pfx2 == "!") {
    lastpos = llGetPos();
    lastrot = llGetRot();
    llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_PLAY]);
    llSetTimerEvent(0.0);  // stop the timer while animation is running
    return;
} else if (msg == "") {
    llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_STOP]);
    return;
}
lastpos = llGetPos();
lastrot = llGetRot();
cmds = list_cast(llCSV2List(msg));
llSetKeyframedMotion(cmds, [KFM_MODE, direction]);
llSetTimerEvent(0.0);  // stop the timer while animation is running
return;
    }


        if (llGetSubString(msg,0,0) == "[") {
    cmds = list_cast(llCSV2List(msg));
            integer e = llSubStringIndex(msg, "]");
    if (subset == [])
            if (e > 1)
sub = [LINK_SET];
                subset = list_cast(llCSV2List(llGetSubString(msg, 1, e-1)));
    else
            else
sub = subset;
                subset = [];
            msg = llStringTrim(llGetSubString(msg, e+1, -1), STRING_TRIM_HEAD);
            if (llList2String(subset,0) == "*") {
                integer i;
                subset = [];
                for (i=1; i<=llGetNumberOfPrims(); i++) subset += i;
            }
        }
        list sub;
        list cmds;
        if (llGetSubString(msg,0,0) == "?") {
            cmds = list_cast(llCSV2List(llGetSubString(msg, 1, -1)));
            integer i;
            list curr;
            if (subset == []) // If not specified use root (or only) prim
                sub = [ (llGetNumberOfPrims() > 1) ];  
            else
                sub = subset;


            debugout(llList2CSV(cmds));
    debugout("On " + llList2CSV(subset) +":\nCmds: "+ llDumpList2String(cmds,"; "));
            for (i = 0; i<llGetListLength(sub); i++) {
    integer i;
                if (llGetListEntryType(sub,i) == TYPE_INTEGER){
    for (i = 0; i<llGetListLength(sub); i++) {
                    integer j = llList2Integer(sub,i);
if (llGetListEntryType(sub,i) == TYPE_INTEGER)
                    curr = llGetLinkPrimitiveParams(j, cmds);
    llSetLinkPrimitiveParamsFast(llList2Integer(sub,i), cmds);
                    reply("[" + (string)j + "] " + llList2CSV(curr));
else //if (llGetListEntryType(subset,i) == TYPE_STRING)
                }     
{
                else //if (llGetListEntryType(subset,i) == TYPE_STRING)
    integer k;
                {
    string x=llList2String(sub,i);
                    integer k;
    list exp;
                    string x=llList2String(sub,i);
    for (k=llGetNumberOfPrims(); k; k--) {
                    list exp;
if (~llListFindList(llGetLinkPrimitiveParams(k,[PRIM_NAME,PRIM_DESC]),[x]))
                    for (k=1; k<=llGetNumberOfPrims(); k++) {
{
                        if (~llListFindList(llGetLinkPrimitiveParams(k,[PRIM_NAME,PRIM_DESC]),
    llSetLinkPrimitiveParamsFast(k, cmds);
                                            [x]))
    exp += k;
                        {
}
                            curr = llGetLinkPrimitiveParams(k, cmds);
    }
                            exp += k;
    debugout(x + " is " + llList2CSV(exp));
                            reply("[" + (string)k + "] " + llList2CSV(curr));
}
                      }
    }
                    }
}
                    debugout(x + " is " + llList2CSV(exp));
                }
   
            }
            return;
        }
        if (llGetSubString(msg,0,0) == "$") {
            msg = llDeleteSubString(msg,0,0);
            vector v = (vector)msg;
            if (v == ZERO_VECTOR) {
                float scal=(float)msg;
                v = <scal,scal,scal>;
            }
            resize_linkset(v);
            return;
        } else if (llGetSubString(msg,0,0) == "%") {
            msg = llDeleteSubString(msg,0,0);
            cmds = list_cast(llCSV2List(msg));
            if (subset == [])
                sub = [LINK_SET];
            else
                sub  = subset;
               
            debugout("ParticleSystem On " + llList2CSV(subset) +":\nCmds: "+ llDumpList2String(cmds,"; "));
            integer i;
            for (i = 0; i<llGetListLength(sub); i++) {
                if (llGetListEntryType(sub,i) == TYPE_INTEGER)
                    llLinkParticleSystem(llList2Integer(sub,i), cmds);
                else //if (llGetListEntryType(subset,i) == TYPE_STRING)
                {
                    integer k;
                    string x=llList2String(sub,i);
                    list exp;
                    for (k=llGetNumberOfPrims(); k; k--) {
                        if (~llListFindList(llGetLinkPrimitiveParams(k,[PRIM_NAME,PRIM_DESC]),[x]))
                        {
                            llLinkParticleSystem(k, cmds);
                            exp += k;
                        }
                    }
                    debugout(x + " is " + llList2CSV(exp));
                }
            }
            return;
        } else if (llGetSubString(msg,0,0) == "@") {
            if (subset != []) {
                if (!~llListFindList(subset,[llGetNumberOfPrims() > 1]) && !~llListFindList(subset,[llGetObjectName()])) {
                    return;
                }
            }
            integer direction = KFM_FORWARD;
            msg = llDeleteSubString(msg,0,0);
            string pfx2 = llGetSubString(msg,0,0);
            if ( pfx2 == "%")  {
                direction = KFM_PING_PONG;
                msg = llDeleteSubString(msg,0,0);
            } else if (pfx2 == "^")  {
                direction = KFM_REVERSE;
                msg = llDeleteSubString(msg,0,0);
            } else if (pfx2 == "@")  {
                if (msg = "@@") {
                    llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_STOP]);
                    llSetPos(lastpos);
                    llSetRot(lastrot);
                    return;
                }       
                llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_PAUSE]);
                return;
            } else if (pfx2 == "!") {
                lastpos = llGetPos();
                lastrot = llGetRot();
                llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_PLAY]);
                llSetTimerEvent(0.0);  // stop the timer while animation is running
                return;
            } else if (msg == "") {
                llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_STOP]);
                return;
            }
            lastpos = llGetPos();
            lastrot = llGetRot();
            cmds = list_cast(llCSV2List(msg));
            llSetKeyframedMotion(cmds, [KFM_MODE, direction]);
            llSetTimerEvent(0.0);  // stop the timer while animation is running
            return;
        }
       
        cmds = list_cast(llCSV2List(msg));
        if (subset == [])
            sub = [LINK_SET];
        else
            sub  = subset;
           
        debugout("On " + llList2CSV(subset) +":\nCmds: "+ llDumpList2String(cmds,"; "));
        integer i;
        for (i = 0; i<llGetListLength(sub); i++) {
            if (llGetListEntryType(sub,i) == TYPE_INTEGER)
                llSetLinkPrimitiveParamsFast(llList2Integer(sub,i), cmds);
            else //if (llGetListEntryType(subset,i) == TYPE_STRING)
            {
                integer k;
                string x=llList2String(sub,i);
                list exp;
                for (k=llGetNumberOfPrims(); k; k--) {
                    if (~llListFindList(llGetLinkPrimitiveParams(k,[PRIM_NAME,PRIM_DESC]),[x]))
                    {
                        llSetLinkPrimitiveParamsFast(k, cmds);
                        exp += k;
                    }
                }
                debugout(x + " is " + llList2CSV(exp));
            }
        }
     }
     }
}
}

Revision as of 02:54, 14 December 2011

   //primset+++ - Includes support for llGet/SetLinkPrimitiveParams, linkset resize, llLinkParticleSystem, and
   //llSetKeyframeMotion
   // Used by the primcontrol HUD.
   //This function typecasts a list of strings, into the types they appear to be. 
   //Extremely useful for feeding user data into llSetPrimitiveParams
   //It takes a list as an input, and returns that list, with all elements correctly typecast, as output
   //Written by Fractured Crystal, 27 Jan 2010, Commissioned by WarKirby Magojiro, this function is Public Domain
   //Modified by Rufus Darkfold to keep strings like <foo> instead of discarding them entirely from the output
   list list_cast(list in)
   {

list out; integer i; integer l= llGetListLength(in); for (i=0; i < l; i++) { string d= llStringTrim(llList2String(in,i),STRING_TRIM); if (d == "") out += ""; else { if (llGetSubString(d,0,0) == "<") { if (llGetSubString(d,-1,-1) == ">") { list s = llParseString2List(d,[","],[]); integer sl= llGetListLength(s); if (sl == 3) { out += (vector)d; } else if(sl == 4) { out += (rotation)d; } else out += [d]; } else out += [d]; } else if (~llSubStringIndex(d,".")) { out += (float)d; } else { integer lold = (integer)d; if ((string)lold == d) out += lold; else { key kold = (key)d; if (kold) out += [kold]; else out += [d]; } } } }

//for (i = 0; i< llGetListLength(out); i++){ // llOwnerSay("Element " + (string)i + " type is " + (string)llGetListEntryType(out, i) // + " value is «" + llList2String(out,i) + "»"); //}

return out;

   }
   integer dimTest( vector vr )
   {

return !( vr.x<0.01 || vr.y<0.01 || vr.z<0.01 || vr.x>64.0 || vr.y>64.0 || vr.z>64.0 );

   }
   resize_linkset( vector scal )
   {

integer primindx; list primP; vector s = llGetScale(); integer validDim = dimTest( <scal.x*s.x,scal.y*s.y,scal.z*s.z> ); for ( primindx = 2; primindx <= llGetNumberOfPrims(); primindx++ ) { primP = llGetLinkPrimitiveParams( primindx, [PRIM_SIZE]); s = llList2Vector( primP, 0 ); validDim = validDim && dimTest( <scal.x*s.x,scal.y*s.y,scal.z*s.z> ); }

if ( validDim ) { s = llGetScale(); llSetScale( <scal.x*s.x,scal.y*s.y,scal.z*s.z> ); for ( primindx = 2; primindx <= llGetNumberOfPrims(); primindx++ ) { primP = llGetLinkPrimitiveParams( primindx, [PRIM_SIZE, PRIM_POSITION]); vector primScale = llList2Vector( primP, 0 ); primScale = <primScale.x*scal.x, primScale.y*scal.y, primScale.z*scal.z>; vector primPos = llList2Vector( primP, 1 ) - llGetPos(); primPos = <primPos.x*scal.x, primPos.y*scal.y, primPos.z*scal.z>; llSetLinkPrimitiveParamsFast( primindx, [PRIM_SIZE, primScale, PRIM_POSITION, primPos/llGetRootRotation()]); } } else llOwnerSay("No resize! Out of limit sizes are not accepted");

   }
   debugout(string msg)
   {
     llOwnerSay(msg);
   }
   integer outchan =0;
   reply(string msg)
   {

llRegionSayTo(llGetOwner(), outchan, msg); if (outchan) { debugout(msg); }

   }
   integer channel = 884;
   list subset;
   integer hlis;
   float timeout = 300; // stop listening after 5 minutes of inactivity
   vector lastpos;
   rotation lastrot;
   default
   {

timer() { if (hlis){ llOwnerSay("Deslecting " + llGetObjectName()); llListenRemove(hlis); hlis = 0; } }

touch_start(integer num) { llSetTimerEvent(timeout); llResetTime(); if (!hlis) { hlis = llListen(channel, "", "", ""); llOwnerSay(llGetObjectName() + " selected. Listening on channel " + (string)channel); return; } while (num--) { integer child=llDetectedLinkNumber(num); integer j = llListFindList(subset,[child]); if (~j) { llOwnerSay("Deselecting #" + (string)child); subset = llDeleteSubList(subset, j, j); } else { llOwnerSay("Selecting #" + (string)child); subset += child; } } }

listen(integer ch, string name, key id, string msg) { //llOwnerSay(msg + " from " + (string)id + " owned by " + (string)llGetObjectDetails(id, [OBJECT_OWNER])); if (llGetOwner() != id) { if (llList2Key(llGetObjectDetails(id, [OBJECT_OWNER]),0) != llGetOwner()) return; }

outchan = 0;

if (msg == "") { subset = []; llSetTimerEvent(0.1); // empty message = disconnect right away; return; } llSetTimerEvent(timeout);

if (llGetSubString(msg, 0, 0) == "/") { // specify response channel integer endch = llSubStringIndex(msg, " "); outchan = (integer)llGetSubString(msg, 1, endch); msg = llGetSubString(msg, endch+1, -1); }

if (llGetSubString(msg,0,0) == "[") { integer e = llSubStringIndex(msg, "]"); if (e > 1) subset = list_cast(llCSV2List(llGetSubString(msg, 1, e-1))); else subset = []; msg = llStringTrim(llGetSubString(msg, e+1, -1), STRING_TRIM_HEAD); if (llList2String(subset,0) == "*") { integer i; subset = []; for (i=1; i<=llGetNumberOfPrims(); i++) subset += i; } } list sub; list cmds; if (llGetSubString(msg,0,0) == "?") { cmds = list_cast(llCSV2List(llGetSubString(msg, 1, -1))); integer i; list curr; if (subset == []) // If not specified use root (or only) prim sub = [ (llGetNumberOfPrims() > 1) ]; else sub = subset;

debugout(llList2CSV(cmds)); for (i = 0; i<llGetListLength(sub); i++) { if (llGetListEntryType(sub,i) == TYPE_INTEGER){ integer j = llList2Integer(sub,i); curr = llGetLinkPrimitiveParams(j, cmds); reply("[" + (string)j + "] " + llList2CSV(curr)); } else //if (llGetListEntryType(subset,i) == TYPE_STRING) { integer k; string x=llList2String(sub,i); list exp; for (k=1; k<=llGetNumberOfPrims(); k++) { if (~llListFindList(llGetLinkPrimitiveParams(k,[PRIM_NAME,PRIM_DESC]), [x])) { curr = llGetLinkPrimitiveParams(k, cmds); exp += k; reply("[" + (string)k + "] " + llList2CSV(curr)); } } debugout(x + " is " + llList2CSV(exp)); }

} return; } if (llGetSubString(msg,0,0) == "$") { msg = llDeleteSubString(msg,0,0); vector v = (vector)msg; if (v == ZERO_VECTOR) { float scal=(float)msg; v = <scal,scal,scal>; } resize_linkset(v); return; } else if (llGetSubString(msg,0,0) == "%") { msg = llDeleteSubString(msg,0,0); cmds = list_cast(llCSV2List(msg)); if (subset == []) sub = [LINK_SET]; else sub = subset;

debugout("ParticleSystem On " + llList2CSV(subset) +":\nCmds: "+ llDumpList2String(cmds,"; ")); integer i; for (i = 0; i<llGetListLength(sub); i++) { if (llGetListEntryType(sub,i) == TYPE_INTEGER) llLinkParticleSystem(llList2Integer(sub,i), cmds); else //if (llGetListEntryType(subset,i) == TYPE_STRING) { integer k; string x=llList2String(sub,i); list exp; for (k=llGetNumberOfPrims(); k; k--) { if (~llListFindList(llGetLinkPrimitiveParams(k,[PRIM_NAME,PRIM_DESC]),[x])) { llLinkParticleSystem(k, cmds); exp += k; } } debugout(x + " is " + llList2CSV(exp)); } } return; } else if (llGetSubString(msg,0,0) == "@") { if (subset != []) { if (!~llListFindList(subset,[llGetNumberOfPrims() > 1]) && !~llListFindList(subset,[llGetObjectName()])) { return; } } integer direction = KFM_FORWARD; msg = llDeleteSubString(msg,0,0); string pfx2 = llGetSubString(msg,0,0); if ( pfx2 == "%") { direction = KFM_PING_PONG; msg = llDeleteSubString(msg,0,0); } else if (pfx2 == "^") { direction = KFM_REVERSE; msg = llDeleteSubString(msg,0,0); } else if (pfx2 == "@") { if (msg = "@@") { llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_STOP]); llSetPos(lastpos); llSetRot(lastrot); return; } llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_PAUSE]); return; } else if (pfx2 == "!") { lastpos = llGetPos(); lastrot = llGetRot(); llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_PLAY]); llSetTimerEvent(0.0); // stop the timer while animation is running return; } else if (msg == "") { llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_STOP]); return; } lastpos = llGetPos(); lastrot = llGetRot(); cmds = list_cast(llCSV2List(msg)); llSetKeyframedMotion(cmds, [KFM_MODE, direction]); llSetTimerEvent(0.0); // stop the timer while animation is running return; }

cmds = list_cast(llCSV2List(msg)); if (subset == []) sub = [LINK_SET]; else sub = subset;

debugout("On " + llList2CSV(subset) +":\nCmds: "+ llDumpList2String(cmds,"; ")); integer i; for (i = 0; i<llGetListLength(sub); i++) { if (llGetListEntryType(sub,i) == TYPE_INTEGER) llSetLinkPrimitiveParamsFast(llList2Integer(sub,i), cmds); else //if (llGetListEntryType(subset,i) == TYPE_STRING) { integer k; string x=llList2String(sub,i); list exp; for (k=llGetNumberOfPrims(); k; k--) { if (~llListFindList(llGetLinkPrimitiveParams(k,[PRIM_NAME,PRIM_DESC]),[x])) { llSetLinkPrimitiveParamsFast(k, cmds); exp += k; } } debugout(x + " is " + llList2CSV(exp)); } } }

   }