Jump to content

SLPPF selectively by child prim name?


Peebee McMillan
 Share

You are about to reply to a thread that has been inactive for 3429 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hellos out there!

I've had no luck finding a solution in the depths of LSL Wiki and  pretty much any other LSL source I know, so I thought I'd give it a shot here. I'm trying to find out how to do this: 

llSetLinkPrimitiveParamsFast( ... on all child prims named "dumpling" in this linkset ... 

I assume there would have to be some indexing of the linknumbers and linknames beforehand (in state_entry? Maybe in a list?!), but I can't piece together how that would work. The above pseudo-code line is just figurative to indicate what I want to do, I know it wont be that simple. :smileyvery-happy:

Any thoughts are muchly appreciated!

Greetz, PeeBee

Link to comment
Share on other sites

Yes, you either need to build a list earlier or you have to loop through the links every time you want to apply SLPPF, to find out which ones are named "dumpling".  My general rule is that if you will be using the set of links more than a couple of times, it's probably smart to build the list early.  The state_entry event is a good place.

integer i;while (i <= llGetNumberOfPrims()){    if (llGetLinkName(i) == "dumpling")    {        gDumplingLinks += [i];    }    ++i;}

 Otherwise,

integer i;while (i <= llGetNumberOfPrims() ){    if (llGetLinkName(i) == "dumpling")    {        llSetLinkPrimitiveParamsFast(i,[Do something here]);    }    ++i;}

If you use the first option, then your SLPPF loop can be just

integer i;while (i < llGetListLength(gDumplingLinks) ){   llSetLinkPrimitiveParamsFast(llList2Integer(gDumplingLinks,i),[Do something Here]);    ++i;}

 

 

 

 

 

Link to comment
Share on other sites

Thanks a lot Rolig, that gives me an indication what I'd have to do.

Now I may need to expand, just to make sure I'll be able to use it like that. I will actually need to generate more than one child name list and then later use those lists in SLPPFs in a listen event.

Lets say some of the children are "dumplings" some are "pasta". Can I generate lists for each and use them later like this (again figuaratively):

----------------------------------------------------------------------------

listen(integer ch, string obj, key id, string msg)
{
     if (msg == "reddumpling")
     {
          llSetLinkPrimitiveParamsFast(...gDumplingLinks...,[Do stuff]);
     }
     else if (msg == "greenpasta")
     {
          llSetLinkPrimitiveParamsFast(...gPastaLinks...,[Do other stuff];
     }
}

----------------------------------------------------------------------------

Sorry for the code in plain text, I have no clue how to get those code fields you're using. :smileyindifferent:

Thanks again for thoughts!

Link to comment
Share on other sites

Sure.  You can get as complicated as you wish.  After a while you may tear your hair out, but you can create a glorious set of lists:

integer i;while (i <= llGetNumberOfPrims()){    list temp = llCSV2List(llGetLinkName(i));  // Assuming that your linknames are strings in the form "A, B, C"    if (temp,0) == "dumpling")    {        gDumplingLinks += [i];    }    if (temp,1) == "chicken")    {        gChicken += [i];    }    if (temp,2) == "spicy")    {        gSpicy += [i];    }    ++i;}

 Then you'll have tthree potential menu lists that you can use in dialogs later, either nested or independently.  There's nothing magical about the logic that you use for building the lists.  It's handy if you can step through all the links one time and create a passel of lists, but you could create them separately too.  Once you have the lists, they are a set of indices that you can use anywhere in the script.

 ETA:  BTW, you can format your code in these forums by using the little coding widget that is triggered with the icon that looks like the letter C in a box, right above the edit panel.

 EDIT (again)  Ooops.  I forgot to turn the loop off.  Fixed now.  :smileyembarrassed:

  • Like 1
Link to comment
Share on other sites

Perfect solution, thanks for this, Rolig!

Using your last example in the state_entry will let me use those lists anywhere further in the script to manipulate only those specific prims. That's exactly what I needed. I don't need dialogs for this project, but good to know that would work too.  

And I don't need any more than 3 of those lists, so my hair is hopefully safe. :D

But I figured this method beats setting SLPPFs on 50+ selected link numbers with PRIM_LINK_TARGET ... And god forbid, I'd have to unlink something afterwards and the link order changes. That would definately be more dangerous hair wise. :D

Even though I'm sure there's also a solution for that, but honestly I'm much of a novice with LSL.

Anyway, thanks again for your effort, you've helped me a lot. And I will use the code formatting next time, I didn't see that sneaky little icon.

Best greetz!

Link to comment
Share on other sites

Hehe.. It should have occurred to me that you could make my last example more flexible by looking for ANY of your key words ANYWHERE in the prim name instead of looking for them in the specific order A, B, C:

integer i;while (i <= llGetNumberOfPrims() ){    list temp = llCSV2List(llGetLinkName(i) );    if (~llListFindList(temp,["Dumpling"]) )    {        gDumplings += [i];    }    if (~llListFindList(temp,["Chicken"]) )    {        gChicken +_= [i];    }    if (~llListFindList(temp,["Spicy"]) )    {        gSpicy += [i];    }
++i;}

 

 

Link to comment
Share on other sites

This is the perfect example of where doing something multiple times in code might be better handled as a function, rather than inline code.

 

To wit:

 

list GetPrimsByName(string name){	integer i;	list result;	while (i <= llGetNumberOfPrims())	{		string prim = llGetLinkName(i);		if (~llSubStringIndex(prim,name))		{			result += [i];		}		i++;	}	return result;}DoSomethingToPrimList(list prims){	integer i;	while (i <= llGetListLength(prims))	{		// Do something here to the the prim where the prim number is element i of the list prims		// Example:  llSetLinkColor(llList2Integer(prims,i), <1.0,1.0,1.0>, ALL_SIDES);		// where this---------------^^^^^^^^^^^^^^^^^^^^^^^ is the value of the i-th element of the prim list.
// you could also have another parameter passed in with something to change to....
i++;
}
}

 

This creates 2 functions we can use anywhere in the code.  One to get a list of prims by name-fragment (it tests to see if the string passed in is present anywhere in the prims name.)  And one that does something to all prims in a list, and has an example of setting the color to white.

 

To use these, just put them outside of any states (i.e., they are global functions) and then call them within other code, like:

integer isRed;list red_prims;default{	state_entry()	{		isRed=FALSE;		red_prims = GetPrimsByName("RedFace");  // this assumes these prims are named like "RedFace1", "RedFace2", "BackRedFace", etc.	}		touch_start(integer numDetected)	{		isRed = !isRed;		if(isRed) DoSomethingToPrimList(red_prims);	}}

 

Now, obviously, if you are only doing this a couple of times in the code, or you only load the list once, it makes more sense to just inline the code instead of using a function.  But for things you may do many times in many places, functions can save a lot of code space.

 

They also make it much easier to debug the code, since things are broken down into sections.  And once you know the code works right, the function calls can be replaced with inline versions of the function and the function removed.....if it's only used in a few places.

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 3429 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...