Jump to content

Updating existing scripts/particles more easily?


MajorCooke
 Share

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

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

Recommended Posts

So here's the deal... Right now I have an object attached to a body part that's linked together and emits particles from its location, since you cannot offset the particle system via the code. At least, not via origin point.

The trouble is, I have to rez both limbs out, delete the particle systems via dragging a particle removing script and reapply the main particle script upon it, then link them all up once more and reapply them to the body. This can be quite the annoyance especially as the object in question is invisible, so selecting it is very difficult.

I would love to cut out that part so all I have to do is recompile the script, and those two objects have their particles changed without needing to take apart my character all over again.

How would I do this?

Link to comment
Share on other sites

You can change the particles of a prim by issuing one of the LSL commands (llParticleSystem or llLinkParticleSystem) with either an empty list - which will turn the particles off, or a new list - which will override any existing setting.

But, you shouldn't even need to unlink anything in the first place. If you need to target a child prim (for example, to access its inventory to get at a script), you can select the "Edit Linked" checkbox in the build tool to only select individual prims of a linkset instead of the root.

That said, if you have edit access to the primary scripts, you can make use of the various "linked" LSL functions that allow your script to target other prims in the linkset, no matter which prim the script is actually in. This makes things a lot easier to manage, as you don't need to use multiple scripts (and having less scripts is usually preferable for performance).

So for example, you may want to consider re-writing your main particle script to make use of llLinkParticleSystem, which take the standard list of parameters and a link number which will make it target that child prim.

Link to comment
Share on other sites

Unfortunately I'm unfamiliar with how to use LinkParticleSystem. Someone gave me the script and while I know how to modify it, I don't know how to properly change it because it gives me a compiler error about the first integer.

default {
    state_entry() {
        llParticleSystem([ 
            PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK|PSYS_PART_INTERP_COLOR_MASK|PSYS_PART_INTERP_SCALE_MASK,
            PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE,
            PSYS_SRC_BURST_RADIUS, 0.200000,
            PSYS_SRC_ANGLE_BEGIN, -2.5,
            PSYS_SRC_ANGLE_END, 2.5,
            PSYS_PART_START_COLOR, <1.00000, 0.70000, 0.00000>,
            PSYS_PART_END_COLOR, <1.00000, 0.50000, 0.00000>,
            PSYS_PART_START_ALPHA, 1.000000,
            PSYS_PART_END_ALPHA,0.000000, 
            PSYS_PART_START_SCALE, <0.20000, 0.20000, 0.00000>,
            PSYS_PART_END_SCALE, <0.01000, 0.01000, 0.00000>,
            PSYS_SRC_MAX_AGE, 0.000000,
            PSYS_PART_MAX_AGE, 1.000000,
            PSYS_SRC_TEXTURE, "e6c7b1f4-5428-04fd-4c4f-42a789f08625",
            PSYS_SRC_BURST_RATE, 0.000000,
            PSYS_SRC_BURST_PART_COUNT, 999,
            PSYS_SRC_ACCEL, <0.00000, 0.00000, 0.75000>,
            PSYS_SRC_BURST_SPEED_MIN, 0.500000,
            PSYS_SRC_BURST_SPEED_MAX, 0.500000
        ]); 
    } 
} 

How do I get the link ID? Please bear in mind I'm very new to this. So this is going to take some real explaining on how to work this out.

Edited by MajorCooke
Link to comment
Share on other sites

Maybe I should back up and get a little more context... Are you saying you have multiple different particle scripts, and you want to periodically switch them out on your attachment? Or is something breaking and you find you need to restart the particles for some reason? I'm a little unclear.

Regarding the other things mentioned, if you're still having trouble selecting a child prim in a link set, I think you can use the following keyboard shortcuts to iterate over each child prim:

Select the "next" link with Ctrl+.
Select the "previous" link with Ctrl+,

There's also a shortcut to highlight transparent objects with Ctrl+Alt+T

As for the syntax, the only difference in between llParticleSystem and the linked version is that the linked version takes an extra parameter before the list:

llLinkParticleSystem( x, [rules-list]);

Where x is the link number of the target child prim. Check out the wiki pages linked earlier for all the details.

As for discovering the link ID (aka link number), that is based on the order in which you linked all the prims together, with the last one being the root (and thus having a link number of 1). You can use the example code shown on the wiki page for llDetectedLinkNumber to report the link number of the child prim when clicked. But be aware that if you unlink everything and then re-link, the link numbers will very likely change - unless you meticulously link everything in exactly the same order.

There are other ways to discover the desired link number of a child prim, but I want to get a clearer picture of this scenario before we go down that path..

Edited by Fenix Eldritch
Link to comment
Share on other sites

6 minutes ago, Fenix Eldritch said:

But be aware that if you unlink everything and then re-link, the link numbers will very likely change - unless you meticulously link everything in exactly the same order.

That's why it is almost always advisable to give each link a unique name and use it to identify the link when you need to, instead of using the link number.  Then, you can either capture the links in your state_entry event with something like this:
 

integer i;
while ( i < llGetNumberOfPrims() )
{
    string name = llGetLinkName(i);
    if ( name == "Right side" )
    {
        iRight = i;
    }
    else if ( name -==- "Left side" )
    {
        iLeft = i;
    }
    // And so on
    ++i;
}

where iRight, iLeft, and all the  other saved link numbers are global integer variables, or for one-off purposes (as in a touch_start event) you can write
 

if ( llGetLinkName( llDetectedLinkNumber(0) ) == "Right side" )
{
    //Do something
}

 

  • Like 1
Link to comment
Share on other sites

Ah, that should be handy. Thanks for that trick! Anyway, to clarify what I'm trying to accomplish:

57f45414ac.png

Okay... SO what I have here on each hoof is an object called "Flaming Hoof Ring", which is the little attachment in blue highlighting (ignore the actual glowing hoof shoe itself - that's not a prim, it's a part of the mesh)

Right now I have four of these (two per each pair of legs) that have different sizes. I will undoubtedly have to make a second script for the bigger variant, until I learn how to get the scale of a prim (it's just a half circlet).

I would like to make is so each time I recompile the script (if possible), it automatically applies the new particle system to those parts, i.e. compiling directly from inventory and effectively refreshes it.

@Rolig Loon Yeah, well, these two are the exact same for the sake of simplicity for this edition so I was thinking they could both be applied one, using that code indeed. Now I'm curious as to how this automatically starts up every time? Or at least how to do so.

Edited by MajorCooke
Link to comment
Share on other sites

14 minutes ago, MajorCooke said:

Now I'm curious as to how this automatically starts up every time? Or at least how to do so.

Each time what?   Each time you wear it?  Put the code in an attached event and trigger it if (id).  For good measure, leave it in the state_entry event as well, and wrap it in a condition that says
 

if ( llGetAttached() )
{
    // Do all the particle stuff
}

so that it's triggered if you restart the script too.

Link to comment
Share on other sites

Each time I log in and the body loads, or yes, attaches. 

So, I should put that on the emitting object then?

My main concern is that it won't auto-update from the script in the inventory, that the script itself will not be up to date each time its called. Is there some sort of function to call upon a specific script from inventory?

Link to comment
Share on other sites

You've lost me. I don't know what you mean by "auto-update."  What are you updating?  And what "inventory"? 

You have a very basic particle script.  Fenix has told you how to use llLinkParticleSystem so that you don't need to put a separate script in each emitting prim. Just drop it in the root prim of your linkset. If you take my last suggestion and trigger the particles in an attached event and ( if (llGetAttached() )  ) in the state_entry event, the script will automatically start the particles in the links that you target in the llLinkParticleSystem command.  Do you want it to do something else?

Link to comment
Share on other sites

Forgive me if I've misunderstood, but if this is all just to keep the particles constantly running when someone wears the attachment, then none of this is necessary. Because particles are a permanent prim property. That basically means once you start the particles on a prim, they will stay running forever** until you explicitly stop them by re-issuing the particle function with an empty list - which is exactly what your particle-remover script does). You can take the object into inventory, rez it, wear it, even delete the script that started the particles, and they will continue to be emitted until you overwrite them with a new particle parameter list (or an empty one).

**unless the PYS_SRC_MAX_AGE parameter is something other than zero, but that's not the case in your example.

I'm also confused why you mean by auto-updating. Are you intending to allow the user to turn the particles on an off? Or change the particles to another set? If so, then that is a different matter. That's certainly possible to do, but we need to fully understand your intent before we can offer advice.

Enclosed is a little test script for you to experiment with. It uses the same particle list you provided earlier, but shows how you can toggle them on and off from a single script. Create an object that comprises of at least three prims. Link them together and then drop this script into it and click the object to see what happens.

//create an object of 3 linked prims. Place this script in the root and click any prim to toggle the particles on and off.

integer toggle = FALSE;     //used to keep track of the on/off switch
list  particleList;         //used to hold the particle parameters

default
{
    state_entry()   //this state is run whenever you restart (or recompile) the script)
    {
        // define the particle parameters list at the start. We'll reuse it later.
        particleList = [ 
            PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK|PSYS_PART_INTERP_COLOR_MASK|PSYS_PART_INTERP_SCALE_MASK,
            PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE,
            PSYS_SRC_BURST_RADIUS, 0.200000,
            PSYS_SRC_ANGLE_BEGIN, -2.5,
            PSYS_SRC_ANGLE_END, 2.5,
            PSYS_PART_START_COLOR, <1.00000, 0.70000, 0.00000>,
            PSYS_PART_END_COLOR, <1.00000, 0.50000, 0.00000>,
            PSYS_PART_START_ALPHA, 1.000000,
            PSYS_PART_END_ALPHA,0.000000, 
            PSYS_PART_START_SCALE, <0.20000, 0.20000, 0.00000>,
            PSYS_PART_END_SCALE, <0.01000, 0.01000, 0.00000>,
            PSYS_SRC_MAX_AGE, 0.000000,
            PSYS_PART_MAX_AGE, 1.000000,
            PSYS_SRC_TEXTURE, "e6c7b1f4-5428-04fd-4c4f-42a789f08625",
            PSYS_SRC_BURST_RATE, 0.000000,
            PSYS_SRC_BURST_PART_COUNT, 999,
            PSYS_SRC_ACCEL, <0.00000, 0.00000, 0.75000>,
            PSYS_SRC_BURST_SPEED_MIN, 0.500000,
            PSYS_SRC_BURST_SPEED_MAX, 0.500000
        ]; 
        
        llLinkParticleSystem(LINK_SET, []); //scrub particles from all prims in entire link set. 
    }

    touch_start(integer total_number)   //this state is run whenever you click on any of the prims in the linkset
    {
        if(toggle == TRUE)
        {
            llOwnerSay("turning off particles");
            llLinkParticleSystem( 2, []);       //target child prim #2
            llLinkParticleSystem( 3, []);       //target child prim #3
            toggle = FALSE;
        }
        else
        {
            llOwnerSay("turning on particles");
            llLinkParticleSystem( 2, particleList);     //target child prim #2
            llLinkParticleSystem( 3, particleList);     //target child prim #3
            toggle = TRUE;
        }
    }
}

 

Edited by Fenix Eldritch
Link to comment
Share on other sites

Okay, let me back up a bit to (try to) clarify. Is there a way to call another script? Because if I could use that 'on attach' method, then I could simply refresh the particles by having it call the particle remover script, and then initialize the particles once again.

59326bd462.png

In order for me to update the particles currently, I have to go through and apply the particle remover onto the parts, along with deleting the currently running Burning Particles scripts that's on them. Then, I have to drag a copy onto their Content tab.

So I'm wondering, is it possible by any chance where I could just hook up a simple script which calls the Burning Particles script upon the mesh itself? 

I'm not seeking a toggle ability but I will keep that in mind.

Link to comment
Share on other sites

I'm still trying to figure out why you are removing particles from anything and "refreshing" them.  I can't imagine any reason for doing that, so I am clearly missing something important in what you are trying to explain.  I'm sure that it has something to do with what you are calling "updating," but as Fenix says, there's no need to do that.  Particles are a prim property.  Once they start, they keep on going unless you tell them specifically to stop.  They don't need to be "refreshed/updated".

Link to comment
Share on other sites

I had the opportunity to meet up with MajorCooke in-world and after some discussion and demos, I think we eventually realized the source of our confusion. It seems MajorCooke was under the impression that changes made to objects in-world would retroactively be applied to the objects in her avatar's inventory that the in-world instances were rezzed from. She didn't realize that they were all separate instances that could not influence each other.

This did lead to a discussion about using a another master object (like a HUD) to communicate with and update any already rezzed/worn instances. I believe that path is where she'd like to explore. To that end, the wiki would be a good place to start:

http://wiki.secondlife.com/wiki/Category:LSL_Communications

http://wiki.secondlife.com/wiki/Dialog_Menus

https://community.secondlife.com/knowledgebase/english/heads-up-displays-huds-r34/

  • Thanks 2
Link to comment
Share on other sites

Okay. What I'd like to try and do is edit the main script itself, save it, then type in a command like... /refreshparticles so it could replace the current instance of the script with a new copy from the main inventory.

I did have an idea on how to do that, thanks to the particle removing script

Is it possible to fetch the main script from my inventory after listening to that chat command using llGetInventoryName or similar?

The way I'm imagining this is if there's a listening script on the parts and they pick up the chat message, they will remove the previous version of "$Burning Particles" that's within the content, grab a copy from the main inventory and immediately execute it.

Or will I have to do this another way?

Link to comment
Share on other sites

Aww dang, sorry I misunderstood you again. I'm 0 for 3 on this one :/

I believe you can inject a script into a target object using something like llRemoteLoadScriptPin... but if your ultimate goal is to just update the particle parameters for specific prims in several worn attachments, I honestly believe something like a more basic communication protocol might be a better (or at least less complex) approach.

Consider this:

Suppose you have an object like a HUD that will act as the controller. This HUD will have a script that contains the particle parameters list in memory. You can make whatever edits you want to the list there and then save. The HUD script would also have code to broadcast the list to your other attachments when prompted (such as when you type a chat command, or even automatically when the script starts after being compiled). Meanwhile, your separate leg attachments will each have a script which listens for the broadcast message from the HUD. When they hear the message, they convert the incoming string to a list and then use that list for the particle command.

That way, you don't need to juggle scripts and only need to make the update in one place.

 

Link to comment
Share on other sites

10 minutes ago, Fenix Eldritch said:

Suppose you have an object like a HUD that will act as the controller. This HUD will have a script that contains the particle parameters list in memory. You can make whatever edits you want to the list there and then save. The HUD script would also have code to broadcast the list to your other attachments when prompted (such as when you type a chat command, or even automatically when the script starts after being compiled). Meanwhile, your separate leg attachments will each have a script which listens for the broadcast message from the HUD. When they hear the message, they convert the incoming string to a list and then use that list for the particle command.

That way, you don't need to juggle scripts and only need to make the update in one place.

That's actually what I would like. If I cannot have a /refresh command of some sort then I'll be happy to do a HUD. Anything to reduce the amount of updating to just 1 place. So, do I still follow the HUD links you posted?

Simply put I thought it might be easier if it could snatch up the copy of the script from the inventory that way instead of needing to read in the details.

Edited by MajorCooke
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1846 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...