Primset script

From Second Life Wiki
Revision as of 02:52, 14 December 2011 by Rufus Darkfold (talk | contribs)
Jump to navigation Jump to search

{ //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));
           }
       }
   }

} }