Jump to content

Nwbie trying to script a lamp with a colored emits light (now working but learning tweaks)


TheNick10
 Share

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

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

Recommended Posts

Hi im very new to scripting but making progress (ive managed a few simple things) now im trying to make a on/off script for a crystal lamp ive made, its 3 diff meshes linked, stand is the root and the two others are the floating crystals and the main crystal. the script ive managed turns the linked prims glow and full bright on or off on touch, thats all working, i also wanted it to turn on/off a emits light on the main crystal but i wanted it to change the color of that to correspond with whatever the main top crystal is tinted too without having to change this in a script, so read the tint that the crystal is and then set the emits light color to the same, ive run into alot of hurdles but cannot seem to overcome this part on my own, please offer help and also any advice to making this better, 

integer switch;
default
{
    state_entry()
    {
        list primcolor = llGetLinkPrimitiveParams (2, [PRIM_COLOR, 1]);
        vector colorpick = llList2Vector (primcolor, 0);
    }

    touch_start(integer total_number)
    {
        if (switch==0)
        {
            switch=1;
            llOwnerSay ("lamp on");
            llSetLinkPrimitiveParams (LINK_ALL_OTHERS, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE]);
            llSetLinkPrimitiveParams (2, [PRIM_GLOW, ALL_SIDES, 0.10]);
            llSetLinkPrimitiveParams (3, [PRIM_GLOW, ALL_SIDES, 0.05]);
            llSetLinkPrimitiveParams (2, [PRIM_POINT_LIGHT, TRUE, colorpick, 1.0, 3.0, 0.0]);              // this is where its saying error name not within scope with the colorpick part
        }
        else if (switch==1)
        {
            switch=0;
            llOwnerSay ("lamp off");
            llGetLinkPrimitiveParams (1, [PRIM_COLOR, ALL_SIDES]);
            llSetLinkPrimitiveParams (LINK_ALL_OTHERS, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE]);
            llSetLinkPrimitiveParams (LINK_ALL_OTHERS, [PRIM_GLOW, ALL_SIDES, 0.0]);
            llSetLinkPrimitiveParams (2, [PRIM_POINT_LIGHT, FALSE, ZERO_VECTOR, 1.0, 3.0, 0.0]); 
        }
    }
}
https://prnt.sc/20mva0v

Edited by TheNick10
Link to comment
Share on other sites

33 minutes ago, TheNick10 said:

Hi im very new to scripting but making progress (ive managed a few simple things) now im trying to make a on/off script for a crystal lamp ive made, its 3 diff meshes linked, stand is the root and the two others are the floating crystals and the main crystal. the script ive managed turns the linked prims glow and full bright on or off on touch, thats all working, i also wanted it to turn on/off a emits light on the main crystal but i wanted it to change the color of that to correspond with whatever the main top crystal is tinted too without having to change this in a script, so read the tint that the crystal is and then set the emits light color to the same, ive run into alot of hurdles but cannot seem to overcome this part on my own, please offer help and also any advice to making this better, 

integer switch;
default
{
    state_entry()
    {
        list primcolor = llGetLinkPrimitiveParams (2, [PRIM_COLOR, 1]);
        vector colorpick = llList2Vector (primcolor, 0);
    }

    touch_start(integer total_number)
    {
        if (switch==0)
        {
            switch=1;
            llOwnerSay ("lamp on");
            llSetLinkPrimitiveParams (LINK_ALL_OTHERS, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE]);
            llSetLinkPrimitiveParams (2, [PRIM_GLOW, ALL_SIDES, 0.10]);
            llSetLinkPrimitiveParams (3, [PRIM_GLOW, ALL_SIDES, 0.05]);
            llSetLinkPrimitiveParams (2, [PRIM_POINT_LIGHT, TRUE, colorpick, 1.0, 3.0, 0.0]);              // this is where its saying error name not within scope with the colorpick part
        }
        else if (switch==1)
        {
            switch=0;
            llOwnerSay ("lamp off");
            llGetLinkPrimitiveParams (1, [PRIM_COLOR, ALL_SIDES]);
            llSetLinkPrimitiveParams (LINK_ALL_OTHERS, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE]);
            llSetLinkPrimitiveParams (LINK_ALL_OTHERS, [PRIM_GLOW, ALL_SIDES, 0.0]);
            llSetLinkPrimitiveParams (2, [PRIM_POINT_LIGHT, FALSE, ZERO_VECTOR, 1.0, 3.0, 0.0]); 
        }
    }
}
https://prnt.sc/20mva0v

You're declaring colorpick inside a state, when it needs to be a global.

Variables declared inside a state cannot be referenced by other states.

In your script, you have switch as a global - declare colorpick as a global as well, and your script should work!

As a note: llSetLinkPrimitiveParams forces the script to sleep for 0.2 seconds, so it's generally preferred to use llSetLinkPrimitiveParamsFast instead. (The command syntax is the same)

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Another option might be to make colorpick local to touch_start—simply moving everything that's currently in state_entry into touch_start instead. This means it'll execute every time somebody clicks on the object, but that's not all that expensive and has the advantage of picking up any color change applied in the Build Tool without needing to reset the script to get state_entry to execute again.

Looking ahead, besides llSetLinkPrimitiveParamsFast(), it may be instructive to consider PRIM_LINK_TARGET as a way to combine all the llSet…Param function calls into one that operates on a single long parameter list. That's not crucial here, certainly, but it's a way all the changes are likely to execute in a single simulation frame with only a single update-object message to the viewer.

Edited by Qie Niangao
["Build Tool" more precise than "editor"]
  • Like 2
Link to comment
Share on other sites

aha thankyou! ok ive made a couple changes adding vector colorpick; to the top made it work/accept it, (i had a extra getprimparam in the lampoff part ive removed that, i think that was the right thing to do) and it saved and is turning the emits light on and off but it's setting it to black (the main crystal is tinted blue) could you advise as to whats going wrong here? 

i moved the list and vector colorpick lines into the lamp on part also as i like the idea of it updating when re clicked instead of resetting 

 

integer switch;
vector colorpick;
default
{
    state_entry()
    {

    }

    touch_start(integer total_number)
    {
        if (switch==0)
        {
            switch=1;
         list primcolor = llGetLinkPrimitiveParams (2, [PRIM_COLOR, 1]);
        vector colorpick = llList2Vector (primcolor, 0);
            llOwnerSay ("lamp on");
            llSetLinkPrimitiveParamsFast (LINK_ALL_OTHERS, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE]);
            llSetLinkPrimitiveParamsFast (2, [PRIM_GLOW, ALL_SIDES, 0.10]);
            llSetLinkPrimitiveParamsFast (3, [PRIM_GLOW, ALL_SIDES, 0.05]);
            llSetLinkPrimitiveParamsFast (2, [PRIM_POINT_LIGHT, TRUE, colorpick, 1.0, 3.0, 0.0]);
        }
        else if (switch==1)
        {
            switch=0;
            llOwnerSay ("lamp off");
            llSetLinkPrimitiveParamsFast (LINK_ALL_OTHERS, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE]);
            llSetLinkPrimitiveParamsFast (LINK_ALL_OTHERS, [PRIM_GLOW, ALL_SIDES, 0.0]);
            llSetLinkPrimitiveParamsFast (2, [PRIM_POINT_LIGHT, FALSE, ZERO_VECTOR, 1.0, 3.0, 0.0]); 
        }
    }
}

Edited by TheNick10
Link to comment
Share on other sites

To figure out what's going on, it may help to add a line of debug code, something like
  llOwnerSay("color for light = "+(string)colorpick);
perhaps right after assigning the value of colorpick.

Currently, llGetLinkPrimitiveParams is getting the color of side #1 of link #2. If I had to guess, maybe link #2 only has one side (which would be side #0), or somehow whatever is side #1 really is black. (In passing, ALL_SIDES would give a value blending all the sides' colors.)*

Incidentally, that version doesn't actually use the global declaration for colorpick at the top, only the local one declared inside touch_start. That's because the assignment "colorpick = …" follows a new "vector" type declaration, meaning it's defining a whole new local variable that shadows the global one.

_________________________
 [EDIT: Sorry, that's wrong. It's how llGetColor() works, but llG.L.P.P. returns a list of colors and alphas of all the sides.]

Edited by Qie Niangao
  • Like 2
Link to comment
Share on other sites

YES! THANKYOU Qie Niangao! its working fully as intended! a massive thankyou to both you and Jenna Huntsman ive learnt 4 new things with your help its really appreciated!

integer switch;
default
{
    state_entry()
    {

    }

    touch_start(integer total_number)
    {
        if (switch==0)
        {
            switch=1;
         list primcolor = llGetLinkPrimitiveParams (2, [PRIM_COLOR, 0]);                  // this fixed it 
         vector colorpick = llList2Vector(primcolor, 0);                                                   //with this also
       
            llOwnerSay ("lamp on");
            llSetLinkPrimitiveParamsFast (LINK_ALL_OTHERS, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE]);
            llSetLinkPrimitiveParamsFast (2, [PRIM_GLOW, ALL_SIDES, 0.10]);
            llSetLinkPrimitiveParamsFast (3, [PRIM_GLOW, ALL_SIDES, 0.05]);
            llSetLinkPrimitiveParamsFast (2, [PRIM_POINT_LIGHT, TRUE, colorpick, 1.0, 3.0, 0.0]);
        }
        else if (switch==1)
        {
            switch=0;
            llOwnerSay ("lamp off");
            llSetLinkPrimitiveParamsFast (LINK_ALL_OTHERS, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE]);
            llSetLinkPrimitiveParamsFast (LINK_ALL_OTHERS, [PRIM_GLOW, ALL_SIDES, 0.0]);
            llSetLinkPrimitiveParamsFast (2, [PRIM_POINT_LIGHT, FALSE, ZERO_VECTOR, 1.0, 3.0, 0.0]); 
        }
    }
}

Edited by TheNick10
Link to comment
Share on other sites

One more thing that might be useful is the PRIM_LINK_TARGET flag for llSetLinkPrimitiveParamsFast.

            llSetLinkPrimitiveParamsFast (LINK_ALL_OTHERS,
            [
                PRIM_FULLBRIGHT, ALL_SIDES, TRUE,
                PRIM_LINK_TARGET, 2,
                PRIM_GLOW, ALL_SIDES, 0.10,
                PRIM_POINT_LIGHT, TRUE, colorpick, 1.0, 3.0, 0.0, 
                PRIM_LINK_TARGET, 3,
                PRIM_GLOW, ALL_SIDES, 0.05
            ]);

 

Edited by KT Kingsley
  • Like 1
  • Thanks 2
Link to comment
Share on other sites

Thankyou KT Kingsley, i dont really understand the PRIM_LINK_TARGET quite yet and will need to open tab number 30 of the wiki XD (im still on day 1 of any scripting ever) does that create a less impactful 'event' and what i can tell is combining all my 4 calls into 1?

Edited by TheNick10
Link to comment
Share on other sites

2 hours ago, TheNick10 said:

         vector colorpick = llList2Vector(primcolor, 0);                                                   //with this also

This line should be changed to:

colorpick = llList2Vector(primcolor, 0); 

As you're attempting to create a local variable with the same name as a global variable. (Qie has an explanation above)

Another note:

llList2Vector can behave... weirdly at times. It's usually more reliable to use (vector)llList2String

Edited by Jenna Huntsman
spelling lol
  • Like 2
Link to comment
Share on other sites

  • TheNick10 changed the title to Nwbie trying to script a lamp with a colored emits light (now working but learning tweaks)
1 hour ago, TheNick10 said:

Thankyou KT Kingsley, i dont really understand the PRIM_LINK_TARGET quite yet and will need to open tab number 30 of the wiki XD (im still on day 1 of any scripting ever) does that create a less impactful 'event' and what i can tell is combining all my 4 calls into 1?

Yeah, that's the idea. Below is a way to use it in your script, with a couple other optional "tweaks" that may be of interest: a switch toggle cliche, and using that boolean switch value to alter the parameter values directly (so only the one llSet…Params call is needed).

integer switch;

default
{
    touch_start(integer total_number)
    {
        vector colorpick = llList2Vector( llGetLinkPrimitiveParams( 2, [PRIM_COLOR, 0] ), 0 );
        switch = !switch;   // toggles the value between TRUE (1) and FALSE (0)
        if (switch) {
            llOwnerSay("lamp on");
        }
        else {
            llOwnerSay("lamp off");
        }
        // Can use value of switch to modify the parameter values:
        llSetLinkPrimitiveParamsFast( LINK_ALL_OTHERS, 
            [ PRIM_FULLBRIGHT, ALL_SIDES, switch,
              PRIM_LINK_TARGET, 2,   // params for link 2 will follow:
              PRIM_GLOW, ALL_SIDES, 0.10 * switch,
              PRIM_POINT_LIGHT, switch, colorpick, 1.0, 3.0, 0.0,
              PRIM_LINK_TARGET, 3,  // and now params for link 3 will follow:
              PRIM_GLOW, ALL_SIDES, 0.05 * switch ]);
    }
}

I hope that's not confusing because none of it is important, just of possible interest.

  • Like 2
Link to comment
Share on other sites

2 hours ago, Jenna Huntsman said:

llList2Vector can behave... weirdly at times. It's usually more reliable to use (vector)llList2String

When the thing in the list is definitely a vector (as it is with llGetLink...) then llList2Vector is the way to go, the weird annoying stuff happens when your list has strings in it that look like vectors (A common cause of that is llListen()ing for a list said with llSay or similar).

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

is this becoming a multi person project XD do i need to give credits lmao, so what does that do Mollymews? ive managed to work out what Qie Niangao has done and why, but thats something i dont understand unless... it changes what its telling me based on the switch state?

 

Link to comment
Share on other sites

16 minutes ago, TheNick10 said:

is this becoming a multi person project XD do i need to give credits lmao, so what does that do Mollymews? ive managed to work out what Qie Niangao has done and why, but thats something i dont understand unless... it changes what its telling me based on the switch state?

 

was just a play off what Qie wrote. Is a way to inline the lamp on off string. While the technique can be useful in some circumstances, it is way over kill for your script. I was just being a bit cheeky when I wrote it, so don't do this

the main thing to take out of this thread is what KT mentioned, using PRIM_LINK_TARGET to wrap everything you want the lamp to do in a single function call. Qie then expanded on this, using the value of switch to set parameter values

is good that you have worked out what KT and Qie have shown.  It will stand you in good stead going forward on your scripting journey

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

And, in fact, you can improve slightly on Qie's great example by compressing several lines of code into one:

integer switch;

default
{
    touch_start(integer total_number)
    {
        vector colorpick = llList2Vector( llGetLinkPrimitiveParams( 2, [PRIM_COLOR, 0] ), 0 );
        llOwnerSay( "Switch " + llList2String(["off","on"],(switch = !switch)) ); // Toggle the "switch" variable here
        llSetLinkPrimitiveParamsFast( LINK_ALL_OTHERS, 
            [ PRIM_FULLBRIGHT, ALL_SIDES, switch,
              PRIM_LINK_TARGET, 2,   // params for link 2 will follow:
              PRIM_GLOW, ALL_SIDES, 0.10 * switch,
              PRIM_POINT_LIGHT, switch, colorpick, 1.0, 3.0, 0.0,
              PRIM_LINK_TARGET, 3,  // and now params for link 3 will follow:
              PRIM_GLOW, ALL_SIDES, 0.05 * switch ]);
    }
}

There are different arguments for in-lining toggles (and other operations).  My personal favorite is that is shortens a script and can make it more readable. Others may argue that it saves a smidgen of time. It's a matter of personal choice, and it's largely irrelevant for a small script like this. As you get into longer scripts, though, habits that save time/space and improve readability can make a difference. 

While we're at it (not to reopen a recent debate, but ... ) I personally get tired of typing some long system constants out over and over again, so I replace selected ones with their integer equivalents.  PRIM_LINK_TARGET is one that I always replace with 34, so I would rewrite Qie's SLPPF statement as

llSetLinkPrimitiveParamsFast( LINK_ALL_OTHERS, 
            [ PRIM_FULLBRIGHT, ALL_SIDES, switch,
              34, 2, PRIM_GLOW, ALL_SIDES, 0.10 * switch, PRIM_POINT_LIGHT, switch, colorpick, 1.0, 3.0, 0.0,
              34, 3, PRIM_GLOW, ALL_SIDES, 0.05 * switch ]);

Again, that's a matter of personal taste but it saves me a bit of typing -- I am notorious for my typos -- and I believe it makes the script look less busy and therefore more readable. You can find the integer equivalents for all system constants on the appropriate pages in the LSL wiki.

  • Like 2
Link to comment
Share on other sites

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