Primset script
Revision as of 06:34, 21 June 2013 by Toady Nakamura (talk | contribs) (added wiki links to the other parts of this system, tidied header only for appearance, not content)
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>