Jump to content

Timers, sounds and sensors?


Queenship3001
 Share

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

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

Recommended Posts

Okay, so in my store I have a phantom prim along the length/width of the floor, and when people walk on it, a small invisible prim follows them leaving a trail of sparkley particles. It's just a little effect for my store and the prim deletes as soon as they step off them phantom prim. Now, I thought it would be cool to add some little sound effects to make it cute to go with the particles when people move. However, this has not been easy....

 

The prim that gets rezzed controls the particle engine, and I also want it to trigger the sound, but it also has to move. A and C work but B (sound) doesn't.

 

Here is the script I'm using:

 

integer gCount;
list particle_parameters=[];
list parse_parameters = [];
vector pos;
key avatar_key;
vector water_min;
vector water_max;
integer lh;

ripple()
{
    particle_parameters = [
       PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0), 
       PSYS_PART_START_SCALE, <0.1, .1, FALSE>, PSYS_PART_END_SCALE, <.2,.2, FALSE>, 
       PSYS_PART_START_COLOR, <1,1,1>,    PSYS_PART_END_COLOR, <.5,.6,1>, 
       PSYS_PART_START_ALPHA,  (float)0.5,            PSYS_PART_END_ALPHA, (float)0.1,   
       PSYS_SRC_BURST_PART_COUNT, (integer)30, 
       PSYS_SRC_BURST_RATE, (float) 0.6,  
       PSYS_PART_MAX_AGE, (float)3.0, 
       PSYS_SRC_MAX_AGE,(float) 0.0,  
       PSYS_SRC_PATTERN, (integer)4,
       PSYS_SRC_BURST_SPEED_MIN, (float).5,   PSYS_SRC_BURST_SPEED_MAX, (float).5, 
       PSYS_SRC_ANGLE_BEGIN, (float) 0.9*PI,    PSYS_SRC_ANGLE_END, (float)0*PI,  
       PSYS_SRC_ACCEL, <0.0,0.0, 0.0 >,      
       PSYS_PART_FLAGS, (integer)( 0  
                            | PSYS_PART_INTERP_COLOR_MASK   
                            | PSYS_PART_INTERP_SCALE_MASK   
                            | PSYS_PART_EMISSIVE_MASK   
                            | PSYS_PART_FOLLOW_VELOCITY_MASK 
                        ) 
                     
    ];    
}
wave()
{
    particle_parameters = [
       PSYS_SRC_TEXTURE, "*****************"
       PSYS_PART_START_SCALE, <0.3,0.3,0.3>, PSYS_PART_END_SCALE, <0.1,0.1,0.1>, 
       PSYS_PART_START_COLOR, <1,1,1>,    PSYS_PART_END_COLOR, <1,1,1>, 
       PSYS_PART_START_ALPHA,  (float)1,            PSYS_PART_END_ALPHA, (float)0.1,   
     
       PSYS_SRC_BURST_PART_COUNT, (integer)8, 
       PSYS_SRC_BURST_RATE, (float) 0.1,  
       PSYS_PART_MAX_AGE, (float)5, 
       PSYS_SRC_MAX_AGE,(float) 0.0,  
    
       PSYS_SRC_PATTERN, (integer)4,
       PSYS_SRC_BURST_SPEED_MIN, (float)0.05,   PSYS_SRC_BURST_SPEED_MAX, (float)0.1, 
    PSYS_SRC_BURST_RADIUS, 0.0,
       PSYS_SRC_ANGLE_BEGIN, (float) 0,    PSYS_SRC_ANGLE_END, (float)0,  
       PSYS_SRC_OMEGA, <0,0,1>, 
       PSYS_SRC_ACCEL, <0,0,0>,  
      
          
       PSYS_PART_FLAGS, (integer)( 0     
                            | PSYS_PART_INTERP_COLOR_MASK   
                            | PSYS_PART_INTERP_SCALE_MASK   
                            | PSYS_PART_EMISSIVE_MASK   
                            | PSYS_PART_FOLLOW_VELOCITY_MASK
 
                        )                    
    ];    
}
default {
    state_entry()
    {
        ripple();
        llSetScale(<0.010, 0.010, 0.010>);
        llSetColor(<1.0, 1.0, 1.0>, ALL_SIDES);
        llSetAlpha(0, ALL_SIDES);
        llParticleSystem([]);
    }
    on_rez(integer rez_param)
    {
        
        if (rez_param != 0)
        {
            
            lh = llListen(rez_param, "", NULL_KEY, "");
            llParticleSystem( particle_parameters );
            llSetTimerEvent(1.8);
        }
        else
        {
            llSetScale(<1.0, 1.0, 1.0>);
            llSetColor(<1.0, 1.0, 1.0>, ALL_SIDES);
            llSetAlpha(1, ALL_SIDES);            
        }
    }
    listen (integer ch, string name, key id, string msg)
    {        
        llListenRemove(lh);
        parse_parameters = llParseString2List(msg, ["##"], [""]);
        avatar_key = (key)llList2String(parse_parameters, 0);
        water_min = (vector)llList2String(parse_parameters, 1);
        water_max = (vector)llList2String(parse_parameters, 2);
        llSensorRepeat("", avatar_key, AGENT, 10.0, PI, 0.1);
        wave();
    }
    sensor(integer num_detected) 
    {
        pos = llDetectedPos(0);
        if (llVecDist(<pos.x, pos.y, water_max.z>, llGetPos()) > 0.1)
        {
            if (pos.x > water_min.x &&
                pos.y > water_min.y &&
                pos.x < water_max.x &&
                pos.y < water_max.y &&
                pos.z > (water_min.z - 0.5) &&
                pos.z < (water_max.z + 0.5))
            {
                    llSetLinkPrimitiveParamsFast(0, [PRIM_POSITION, <pos.x, pos.y, water_max.z>]);
                    llParticleSystem( particle_parameters );
                    llSetTimerEvent(0.8);
            }
            else 
                llDie();
        }
    }  
    no_sensor()
    {
        llDie();
    }
    timer()
    {
        llSetTimerEvent(0.0);
        llParticleSystem([]);
        if (gCount%3 == 0)
        {
            llPlaySound(llGetInventoryName(INVENTORY_SOUND,0), 1.0);
        }

        else if (gCount%3 == 1)
        {
            llPlaySound(llGetInventoryName(INVENTORY_SOUND,1), 1.0);
        }

        else if (gCount%3 == 2)
        {
            llPlaySound(llGetInventoryName(INVENTORY_SOUND,2), 1.0);
        }
    }        
}

 Now I've tried a few things.

Initially I was using llTriggerSound under the "sensor" section, so it would play the sound when the prim and avatar moved. The initial sound was too long and was spammed pretty bad, so I figured I'd need a timer and shorter sounds to play at intervals, so I found: http://community.secondlife.com/t5/Scripting/One-after-the-play-from-several-sound/td-p/499736

But, I needed it to be under the sensor area still, and so far as I know, I can't make a timer event in nother event (despite how much I want it to >.>). So I made the counter and put all the stuff I needed to in a new argument within the argument containing "llSetLinkPrimitiveParamsFast".

 

That ALMOST worked, but the counter wasn't so once again, the 3 short audio files I had were being smashed together and played as one. (several retries by editing the counter and even adding "float gap = 0.2" also failed)

So as a final effort that I knew would fail but decided to do anyway, was to put everything under that last part in the timer event (it was already there to end the script). And, like I thought it would, the sound only played when the prim stopped moving.

 

SO! How do I get my sound(s) to play properly under the "Sensor" event where I need them to? Any ideas?

Link to comment
Share on other sites

Probably you already realize that the problem is that every time your sensor repeats, it resets the timer, so the timer never gets a chance to expire and play a sound. You might get closer to what you want just by using a global variable that you set when you set the timer, and first test to make sure it hasn't been set.

At first glance, it appears there's at least one other problem, in that gCount never increments, so it will only ever play the 0th sound.

[EDIT: Oh, and you don't want to stop the timer in the timer event itself, assuming you want the sound to repeat and change. But you also said something about wanting to move all this to the sensor() event, which would be fine, but you'd need to do some arithmetic on timings so you play the sounds just when you want them played. That's probably easier to manage in the separate timer() event... although I must say that the current sensor repeat timing seems unnecessarily tight -- like, by a lot. -- so that may want some attention anyway.]

  • Like 1
Link to comment
Share on other sites

Yes, the sounds have to be in the sensor event because the sensor event takes place when the prim moves. If I place the sounds in the Timer event, then the sounds only play when the prim has stopped moving.

 

Is there a way to change it up and have it play a sound during the sensor event without having it repeat 57832784657 times in less than a second (compliemtns of llTriggerSound), and then have the sound stop midway when the prim stops moving?

Link to comment
Share on other sites

Well, if that's the issue, then I think I would set a flag (call it gSoundON) that is normally Set to FALSE. The first time that your sensor fires, flip it to TRUE and play the sound. Then don't trigger the sound on successive cycles through the sensor event.  Finally, when the timer event kicks in, set gSoundON FALSE again.

sensor(integer num_detected)     {        if (!gSoundON)        {            gSoundON = TRUE;            llPlaySound("My-3_SoundFiles_combined",1.0);        }        pos = llDetectedPos(0);        if (llVecDist(<pos.x, pos.y, water_max.z>, llGetPos()) > 0.1)        {            if (pos.x > water_min.x &&                pos.y > water_min.y &&                pos.x < water_max.x &&                pos.y < water_max.y &&                pos.z > (water_min.z - 0.5) &&                pos.z < (water_max.z + 0.5))            {                    llSetLinkPrimitiveParamsFast(0, [PRIM_POSITION, <pos.x, pos.y, water_max.z>]);                    llParticleSystem( particle_parameters );                    llSetTimerEvent(0.8);            }            else                 llDie();        }    }  

 

 

Link to comment
Share on other sites

Well, that gave me two outcomes. Saving the script with "gSoundON" switched to FALSE cause the sound to play nonestop, looped, regardless if the prim was movig or not. Saving the script with "gSoundON" switched to TRUE made the sound play just a single time when the prim initially rezzes and then it never plays again until I walk away and come back, making the system rez a new prim....

I was supposed to use "Integer gSoundON;" when adding it to the top of the script though, right?

Link to comment
Share on other sites

Yes, of course.  gSound has to be a global integer if you're going to use it as a flag each time you step into the sensor event.  Otherwise, it can't remember its previous value.  Taking the sensor event exactly as I wrote it and assuming that gSound = FALSE initially, the first time the sensor is triggered, the test

if (!gSound) will evaluate to TRUE (that is, it is TRUE that gSound has the value !gSound)

Therefore, the llPlaySound will be executed and the value of gSound will be set to TRUE.  If the sensor event is triggered again, the value of if(!gSound) will be FALSE, and your sound file will NOT play.  Also, the value of gSound will remain TRUE.

Therefore, unless something else happens, gSound will be TRUE until the end of time and the sound will never play again.  "Something else" could indeed be falling victim to the llDie command and being forced to rez again.  As I said, though, you could also reset the value of gSound to FALSE in a timer event. I didn't bother messing with that before, but just left it there for you.  One way to handle it, though would be to write something like

    sensor(integer num_detected)     {        if (!gSound)        {            gSound = TRUE;            llPlaySound("My_3_SoundFiles_Together",1.0);            llSetTimerEvent(2.0); //Purely arbitrary, just an example        }        pos = llDetectedPos(0);        if (llVecDist(<pos.x, pos.y, water_max.z>, llGetPos()) > 0.1)        {            if (pos.x > water_min.x &&                pos.y > water_min.y &&                pos.x < water_max.x &&                pos.y < water_max.y &&                pos.z > (water_min.z - 0.5) &&                pos.z < (water_max.z + 0.5))            {                    llSetLinkPrimitiveParamsFast(0, [PRIM_POSITION, <pos.x, pos.y, water_max.z>]);                    llParticleSystem( particle_parameters );            }            else                 llDie();  // Out of range; die        }    }      no_sensor()    {        llDie();   // REALLY out of range; die    }    timer()    {        llSetTimerEvent(0.0);  // Turn off the timer        gSound = FALSE;  // Tell the sensor that it's OK to play the sound next time    }

If you do it this way, the sounds will be triggered every 2 seconds until the object finally dies.  Since your combined sounds are only about 0.6 seconds long, that means you'll have 1.4 seconds of peace between sounds.  You can reduce the spam load by just making the timer wait more than 2.0 seconds.

 Incidentally, the particle generator will keep on spewing particles until you tell it to stop, so there's no reason to keep telling it to fire over and over and over each time the sensor fires.  It doesn't hurt anything.  Just sayin' .....

 

Link to comment
Share on other sites

Well it's looking good so far then, but the thing it I need it to pause now. The prim won't use any of the llDie functions until the avatar leaves the phantom prim floor (via walking off, teleporting out or crashing) The prim will simply follow the avatar around, making particles as it moves, but as soon as the avatar stands still, so will the prim, and the particles stop. When the avatar starts to move again, so will the prim and that means more particles. The sound however, doesn't do this. It's just looping constantly (although the demo script you set up there is still a major help!).

Link to comment
Share on other sites

<sigh>  There's always another challenge. As my friend(?) Maddy says, I am a sucker for a fun puzzle. :smileytongue:

OK, let's see if I understand this.  The follower, once triggered, is supposed to stay in range, spewing particles and making sounds ONLY when the person is moving, and then POOF when the person leaves, right?  In that case, I don't see why you have the llDie() inside the movement part of the sensor event. What you want to do there is stop particles and sounds, not kill the follower.

Like this?

    sensor(integer num_detected)     {        pos = llDetectedPos(0);        if (llVecDist(<pos.x, pos.y, water_max.z>, llGetPos()) > 0.1)        {            if (pos.x > water_min.x &&                pos.y > water_min.y &&                pos.x < water_max.x &&                pos.y < water_max.y &&                pos.z > (water_min.z - 0.5) &&                pos.z < (water_max.z + 0.5))            {                    llSetLinkPrimitiveParamsFast(0, [PRIM_POSITION, <pos.x, pos.y, water_max.z>]);                    llParticleSystem( particle_parameters );                if (!gSound)                {                    gSound = TRUE;                    llPlaySound("My_3_SoundFiles_Together",1.0);                    llSetTimerEvent(2.0); //Purely arbitrary, just an example                }            }            else // Follower is close, so quit showing off             {                llParticleSystem([]);                llSetTimerEvent(0.0);                gSound = FALSE;            }        }    }      no_sensor()    {        llDie();   // REALLY out of range; die    }    timer()    {        llSetTimerEvent(0.0);  // Turn off the timer        gSound = FALSE;  // Tell the sensor that it's OK to play the sound next time    }

 

Link to comment
Share on other sites

Are you going to hate me if I tell you right now I just figured exactly what you just showed me right before I refreshed the page...? xD

 

    sensor(integer num_detected)     {        if (!gSound)        {            gSound = TRUE;            llPlaySound("sparkles4, 1.0);        }                pos = llDetectedPos(0);        if (llVecDist(<pos.x, pos.y, water_max.z>, llGetPos()) > 0.1)        {            if (pos.x > water_min.x &&                pos.y > water_min.y &&                pos.x < water_max.x &&                pos.y < water_max.y &&                pos.z > (water_min.z - 0.5) &&                pos.z < (water_max.z + 0.5))            {                    llSetLinkPrimitiveParamsFast(0, [PRIM_POSITION, <pos.x, pos.y, water_max.z>]);                    llParticleSystem( particle_parameters );                    llSetTimerEvent(0.8);            }            else llDie();        }        else        {            gSound = FALSE;            llSetTimerEvent(0.0);            llParticleSystem([]);        }    }      no_sensor()    {        llDie();    }    timer()    {        llSetTimerEvent(0.0);        llParticleSystem([]);        gSound = FALSE;    }        }

 

Link to comment
Share on other sites

As thanks, I'll give out both scripts I'm using for others who want to do the same thing!

 

Invisible phantom floor script:

integer i;vector splash_pos;vector my_size;vector my_pos;integer splash_rez_listen;default{    state_entry()    {        //llSetTextureAnim(ANIM_ON | SMOOTH |    LOOP, ALL_SIDES,1,1,1,1,0.025);          llSetTextureAnim(ANIM_ON | SMOOTH |SCALE | PING_PONG | LOOP, 0,1,1,1,1.0,0.03);        llVolumeDetect(TRUE);    }    collision_start(integer num_detected)    {        my_pos = llGetPos();        my_size = llGetScale();        for(i=0;i<num_detected;i++)        {            splash_pos = llDetectedPos(i);            llRezObject(                            "sparkle",                                                           // object name in inventory                            <splash_pos.x, splash_pos.y, (my_pos.z + (my_size.z/2.0))>,         // rez at positioon                            ZERO_VECTOR,                                                        // rez velocity                            <0.00000, -0.70711, 0.00000, 0.70711>,                              // rez rotation                            (splash_rez_listen = (integer)llFrand(999999) * -1)                 // rez parameter                        );            llSleep(0.1);            llShout(splash_rez_listen,                                                          // listen key                    (string)llDetectedKey(i) + "##" + (string)(my_pos - (my_size / 2.0)) + "##" + (string)(my_pos + (my_size / 2.0)) // parameters                    );        }    }    collision(integer nd)    {        llOwnerSay("moving");    }}

 

Particle and sound prim follow script:

integer gSound;list particle_parameters=[];list parse_parameters = [];vector pos;key avatar_key;vector water_min;vector water_max;integer lh;ripple(){    particle_parameters = [  // start of particle settings       // Texture Parameters:       PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0),       PSYS_PART_START_SCALE, <0.1, .1, FALSE>, PSYS_PART_END_SCALE, <.2,.2, FALSE>,       PSYS_PART_START_COLOR, <1,0,1>,    PSYS_PART_END_COLOR, <0,1,1>,       PSYS_PART_START_ALPHA,  (float)1,            PSYS_PART_END_ALPHA, (float)1,              PSYS_SRC_BURST_PART_COUNT, (integer)50,       PSYS_SRC_BURST_RATE, (float) 0.01,         PSYS_PART_MAX_AGE, (float)4.0,       PSYS_SRC_MAX_AGE,(float) 0.0,            PSYS_SRC_PATTERN, (integer)8, // 1=DROP, 2=EXPLODE, 4=ANGLE, 8=ANGLE_CONE,             PSYS_SRC_BURST_SPEED_MIN, (float)0,   PSYS_SRC_BURST_SPEED_MAX, (float)0,    PSYS_SRC_BURST_RADIUS, 0.2,          PSYS_SRC_ANGLE_BEGIN, (float) PI,    PSYS_SRC_ANGLE_END, (float)0,       PSYS_SRC_OMEGA, <5,5,5>,          PSYS_SRC_ACCEL, <0.0,0.0, 0.0 >,      // PSYS_SRC_TARGET_KEY,      llGetLinkKey(llGetLinkNum() + 1),                        PSYS_PART_FLAGS, (integer)( 0                             | PSYS_PART_INTERP_COLOR_MASK                               | PSYS_PART_INTERP_SCALE_MASK                               | PSYS_PART_EMISSIVE_MASK                               | PSYS_PART_FOLLOW_VELOCITY_MASK                         // | PSYS_PART_WIND_MASK                                     // | PSYS_PART_BOUNCE_MASK                                   // | PSYS_PART_FOLLOW_SRC_MASK                              // | PSYS_PART_TARGET_POS_MASK                              // | PSYS_PART_TARGET_LINEAR_MASK                           )                  ];    }wave(){    particle_parameters = [       PSYS_SRC_TEXTURE, "your-UUID-goes-right-here",       PSYS_PART_START_SCALE, <0.3,0.3,0.3>, PSYS_PART_END_SCALE, <0.1,0.1,0.1>,       PSYS_PART_START_COLOR, <1,1,1>,    PSYS_PART_END_COLOR, <1,1,1>,       PSYS_PART_START_ALPHA,  (float)1,            PSYS_PART_END_ALPHA, (float)0.1,              PSYS_SRC_BURST_PART_COUNT, (integer)8,       PSYS_SRC_BURST_RATE, (float) 0.1,         PSYS_PART_MAX_AGE, (float)5,       PSYS_SRC_MAX_AGE,(float) 0.0,            PSYS_SRC_PATTERN, (integer)4, // 1=DROP, 2=EXPLODE, 4=ANGLE, 8=ANGLE_CONE,             PSYS_SRC_BURST_SPEED_MIN, (float)0.05,   PSYS_SRC_BURST_SPEED_MAX, (float)0.1,    PSYS_SRC_BURST_RADIUS, 0.0,          PSYS_SRC_ANGLE_BEGIN, (float) 0,    PSYS_SRC_ANGLE_END, (float)0,         PSYS_SRC_OMEGA, <0,0,1>,          PSYS_SRC_ACCEL, <0,0,0>,      // PSYS_SRC_TARGET_KEY,      llGetLinkKey(llGetLinkNum() + 1),                        PSYS_PART_FLAGS, (integer)( 0         // Texture Options:                                 | PSYS_PART_INTERP_COLOR_MASK                               | PSYS_PART_INTERP_SCALE_MASK                               | PSYS_PART_EMISSIVE_MASK                               | PSYS_PART_FOLLOW_VELOCITY_MASK                         // | PSYS_PART_WIND_MASK                                     // | PSYS_PART_BOUNCE_MASK                                   // | PSYS_PART_FOLLOW_SRC_MASK                              // | PSYS_PART_TARGET_POS_MASK                              // | PSYS_PART_TARGET_LINEAR_MASK                           )                     ];    }default {    state_entry()    {        ripple();        llSetScale(<0.010, 0.010, 0.010>);        llSetColor(<1.0, 1.0, 1.0>, ALL_SIDES);        llSetAlpha(0, ALL_SIDES);        llParticleSystem([]);    }    on_rez(integer rez_param)    {                if (rez_param != 0)        {            lh = llListen(rez_param, "", NULL_KEY, "");            llParticleSystem( particle_parameters );            llSetTimerEvent(1.8);        }        else        {            llSetScale(<1.0, 1.0, 1.0>);            llSetColor(<1.0, 1.0, 1.0>, ALL_SIDES);            llSetAlpha(1, ALL_SIDES);                    }    }    listen (integer ch, string name, key id, string msg)    {                llListenRemove(lh);        parse_parameters = llParseString2List(msg, ["##"], [""]);        avatar_key = (key)llList2String(parse_parameters, 0);        water_min = (vector)llList2String(parse_parameters, 1);        water_max = (vector)llList2String(parse_parameters, 2);        llSensorRepeat("", avatar_key, AGENT, 10.0, PI, 0.1);        wave();    }    sensor(integer num_detected)    {        if (!gSound)        {            gSound = TRUE;            llPlaySound("YOUR_SOUND_HERE", 1.0);        }                pos = llDetectedPos(0);        if (llVecDist(<pos.x, pos.y, water_max.z>, llGetPos()) > 0.1)        {            if (pos.x > water_min.x &&                pos.y > water_min.y &&                pos.x < water_max.x &&                pos.y < water_max.y &&                pos.z > (water_min.z - 0.5) &&                pos.z < (water_max.z + 0.5))            {                    llSetLinkPrimitiveParamsFast(0, [PRIM_POSITION, <pos.x, pos.y, water_max.z>]);                    llParticleSystem( particle_parameters );                    llSetTimerEvent(0.8);            }            else llDie();        }        else        {            gSound = FALSE;            llSetTimerEvent(0.0);            llParticleSystem([]);        }    }      no_sensor()    {        llDie();    }    timer()    {        llSetTimerEvent(0.0);        llParticleSystem([]);        gSound = FALSE;    }        }

 The above script goes into a prim, then the pri goes into the alpha floor with the first script. ^.^

Link to comment
Share on other sites

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