Primset script: Difference between revisions
Jump to navigation
Jump to search
Created page with "//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, …" |
m added wiki links to the other parts of this system, tidied header only for appearance, not content |
||
| (9 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
//This function typecasts a list of strings | See [[Primset]] and [[PrimControl HUD]] for explanation and the other parts of this system. | ||
// | |||
// | <lsl> | ||
//Written by Fractured Crystal, 27 Jan 2010, Commissioned by WarKirby Magojiro, this function is Public Domain | //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. | |||
// Useful for feeding user data into llSetPrimitiveParams | |||
// Takes list 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 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, | if (llGetSubString(d,0,0) == "<") | ||
{ | { | ||
list s = llParseString2List(d,[","],[]); | 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 | } else | ||
out += [d]; | 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 ) | |||
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 ) | |||
{ | { | ||
s = llGetScale(); | 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++ ) | for ( primindx = 2; primindx <= llGetNumberOfPrims(); primindx++ ) | ||
{ | { | ||
primP = llGetLinkPrimitiveParams( primindx, [PRIM_SIZE | 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) | |||
{ | |||
debugout(string msg) | llOwnerSay(msg); | ||
{ | |||
} | } | ||
integer outchan =0; | |||
reply(string msg) | |||
integer | |||
{ | { | ||
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; | |||
if ( | |||
llOwnerSay(" | |||
} | } | ||
} | } | ||
touch_start(integer num) | |||
{ | |||
llSetTimerEvent(timeout); | |||
llResetTime(); | |||
if (!hlis) { | |||
hlis = llListen(channel, "", "", ""); | |||
llOwnerSay(llGetObjectName() + " selected. Listening on channel " + (string)channel); | |||
return; | 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 = []; | subset = []; | ||
msg = llStringTrim(llGetSubString(msg, e+1, -1), STRING_TRIM_HEAD); | 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; | integer i; | ||
subset = []; | list curr; | ||
for (i=1; | 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)); | cmds = list_cast(llCSV2List(msg)); | ||
if (subset == []) | if (subset == []) | ||
| Line 232: | Line 312: | ||
else | else | ||
sub = subset; | sub = subset; | ||
debugout(" | debugout("On " + llList2CSV(subset) +":\nCmds: "+ llDumpList2String(cmds,"; ")); | ||
integer i; | integer i; | ||
for (i = 0; i<llGetListLength(sub); i++) { | for (i = 0; i<llGetListLength(sub); i++) { | ||
if (llGetListEntryType(sub,i) == TYPE_INTEGER) | if (llGetListEntryType(sub,i) == TYPE_INTEGER) | ||
llSetLinkPrimitiveParamsFast(llList2Integer(sub,i), cmds); | |||
else //if (llGetListEntryType(subset,i) == TYPE_STRING) | else //if (llGetListEntryType(subset,i) == TYPE_STRING) | ||
{ | { | ||
| Line 246: | Line 326: | ||
if (~llListFindList(llGetLinkPrimitiveParams(k,[PRIM_NAME,PRIM_DESC]),[x])) | if (~llListFindList(llGetLinkPrimitiveParams(k,[PRIM_NAME,PRIM_DESC]),[x])) | ||
{ | { | ||
llSetLinkPrimitiveParamsFast(k, cmds); | |||
exp += k; | exp += k; | ||
} | } | ||
| Line 252: | Line 332: | ||
debugout(x + " is " + llList2CSV(exp)); | debugout(x + " is " + llList2CSV(exp)); | ||
} | } | ||
} | } | ||
} | } | ||
} | } | ||
</lsl> | |||
Latest revision as of 07:34, 21 June 2013
See Primset and PrimControl HUD for explanation and the other parts of this system.
<lsl> //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. // Useful for feeding user data into llSetPrimitiveParams // Takes list 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 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));
}
}
}
}
</lsl>