Jump to content

How do I un-loop the looped sound and chat text from this modded script?


GadgetKit Vectoscope
 Share

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

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

Recommended Posts

First off, forgive me, because I'm a beginner who barely knows what I'm doing, as far is scripting is concerned. For all I know, the answer to this is probably very simple and is staring me right in the face...

I found an old, free script in my inventory, 'Multiple Sound Fragments Player", and tried to mod it into a hybrid with a "Sound & Text on Touch" script.

The goal was to have a prim attachment play 4 sound files (rather than the usual 2), in a certain order, when touched.

This version of the script does this, but unfortunately loops both the sound and the chat text indefinitely. I want to have it play all this stuff just once, whenever the prim is touched, with no automatic repeats.

The other drawback is that there is a considerable time delay (6+ seconds) prior to the first sound clip playing and between the subsequent the sound clips. I've tried setting the llSetTimerEvent to lower numbers than 10, but it didn't seem to make any difference.

 

Quote

 

string STATE = "off";
integer FRAGMENT_COUNT;
integer CURRENT_FRAGMENT = -1;

default
{
   state_entry()
   {
     FRAGMENT_COUNT = llGetInventoryNumber(INVENTORY_SOUND);
     llSetTimerEvent(10);
   }
     
     touch_start(integer total_number) {
      if (STATE=="off") {
          STATE = "on";
          
    }
    else {
        STATE = "off";
        llStopSound();
    }
  }
 
  timer() {
      if (STATE=="on") {   
            CURRENT_FRAGMENT=CURRENT_FRAGMENT+1;
            if(CURRENT_FRAGMENT==FRAGMENT_COUNT) {
                CURRENT_FRAGMENT=0;
            }
            llPlaySound(llGetInventoryName(INVENTORY_SOUND,CURRENT_FRAGMENT),1);
        }
        else {
            STATE = "off";
            llStopSound();
        }
      
      llInstantMessage( llGetOwner(), "►►  * Button *  ◄◄");
      llInstantMessage( llGetOwner(), "►► ACTIVATED! ◄◄");
      llInstantMessage( llGetOwner(), "   Go-Go Gadget:");
      llInstantMessage( llGetOwner(), " ♂ SEX-CHANGE! ♀");
      llInstantMessage( llGetOwner(), "*** WARNING ***");
      llInstantMessage( llGetOwner(), "* SYSTEM ERROR *");
      llInstantMessage( llGetOwner(), "►►  * Button *  ◄◄");
      llInstantMessage( llGetOwner(), "►► MALFUNCTION! ◄◄");
      llSleep(0.5);
      llSay(0, "* TG Button Failure! ");
      llSay(0, "*      GadgetKit      ");
      llSay(0, "*    is now stuck     ");
      llSay(0, "*  in Female Mode.  ");
     
     
      
    }
}

 

 

Link to comment
Share on other sites

If you use a function in a script - always read the caveats in the wiki 1st 😁
Every llInstantMessage has a delay of 2 seconds - you get the idea why your timing doesn't work now.

Use llOwnerSay instead

Be generally careful with delays and llSleeps and loops in timer events - if you exceed the trigger time your timing will be messed up.

Besides of that it's a bad script since the timer is always running - even if it's "OFF" but get it running 1st and then try to fix that.

Link to comment
Share on other sites

Thank you. That definitely got rid of the delays.

The main problem now is the running timer; it stays in a loop. I've tested putting llSetTimerEvent(0.0) in various spots in the script, but that either does nothing, or pre-empts the 'Multiple Sound Fragments' feature (which allows the prim play 4 sound clips in order, rather than the usual maximum of 2), depending on where I place it.

I think I'll just have to go back to square one and learn/re-learn lsl scripting basics. I seem to know just enough (usually by accident!) to sometimes tweak an existing script a little bit to my liking, but it's not as though I have a firm grasp of the concept of events, states, strings, constants, variables, integers, etc. I examine most scripts and my eyes glaze over and I get a bit lost.

Link to comment
Share on other sites

You stop the sound and the timer: (in touch_start and in timer)

llStopSound();
llSetTimerEvent(0);

You start the timer when you switch it on: (in touch_start)

STATE = "on";
llSetTimerEvent(10);

The llTimerEvent in the state_entry event is only called when the script is reset so you can remove that.

There is one problem though: if you touch it will take 10 seconds until the sound starts so to fix that we need some changes:
Not tested

string STATE = "off";
integer FRAGMENT_COUNT;
integer CURRENT_FRAGMENT = -1;

default
{
   state_entry()
   {
     FRAGMENT_COUNT = llGetInventoryNumber(INVENTORY_SOUND);
   }
     
     touch_start(integer total_number) {
      if (STATE=="off") {
          STATE = "on";
		  llSetTimerEvent(0.02);
          
    }
    else {
        STATE = "off";
        llStopSound();
		llSetTimerEvent(0);
    }
  }
 
  timer() {
      if (STATE=="on") {   
			llSetTimerEvent(10);
            CURRENT_FRAGMENT=CURRENT_FRAGMENT+1;
            if(CURRENT_FRAGMENT==FRAGMENT_COUNT) {
                CURRENT_FRAGMENT=0;
            }
            llPlaySound(llGetInventoryName(INVENTORY_SOUND,CURRENT_FRAGMENT),1);
        }
        else {
            STATE = "off";
            llStopSound();
			llSetTimerEvent(0);
        }
      
      llInstantMessage( llGetOwner(), "►►  * Button *  ◄◄");
      llInstantMessage( llGetOwner(), "►► ACTIVATED! ◄◄");
      llInstantMessage( llGetOwner(), "   Go-Go Gadget:");
      llInstantMessage( llGetOwner(), " ♂ SEX-CHANGE! ♀");
      llInstantMessage( llGetOwner(), "*** WARNING ***");
      llInstantMessage( llGetOwner(), "* SYSTEM ERROR *");
      llInstantMessage( llGetOwner(), "►►  * Button *  ◄◄");
      llInstantMessage( llGetOwner(), "►► MALFUNCTION! ◄◄");
      llSleep(0.5);
      llSay(0, "* TG Button Failure! ");
      llSay(0, "*      GadgetKit      ");
      llSay(0, "*    is now stuck     ");
      llSay(0, "*  in Female Mode.  ");
     
     
      
    }
} 

 

 

Link to comment
Share on other sites

You may also want to use another function:

llPreloadSound

This will eliminate the delay in playing sounds as this will make nearby viewers download and cache the sound before it is needed.

You can also make use of

llSetSoundQueueing

This will mean you can queue sounds to play sequentially, thus meaning you can have a slower timer loop. Note that you can only queue 2 sounds at a time, so the timer would have to trigger at approx 15 seconds (assuming the 2 previous sounds were 10 seconds each) to use llPreloadSound and add the next item to the queue.

For efficiency's sake, you may want to add this line under your state_entry

llSetMemoryLimit(llGetFreeMemory() + 512);

This will limit your script's memory usage to only use what it actually needs, with a little headroom.

Link to comment
Share on other sites

13 minutes ago, Jenna Huntsman said:

This will limit your script's memory usage to only use what it actually needs, with a little headroom.

Nope, the memory usage of the script will not change by this.
Fact - I will not discuss anything about that - there are already too many posts about that.

Link to comment
Share on other sites

3 minutes ago, Nova Convair said:

Nope, the memory usage of the script will not change by this.
Fact - I will not discuss anything about that - there are already too many posts about that.

I already know that 'active' usage won't change - but Mono's memory reporting always reports the max usable, hence why limiting the memory to only what's needed can be beneficial if a script performs a fixed function, as someone using one of those dreaded 'performance monitors' might see a simple item eating 64k of script memory and accuse that of the source of lag for the region.

Stupid as it sounds, I've seen it happen many times.

Link to comment
Share on other sites

The downside of using llSetMemoryLimit() is that simply calling the function uses some amount of memory and processing time, both minuscule but non-imaginary, for absolutely no benefit other than to placate the fantasies of those wielding the dreaded performance monitors.

(The only time I've found the function actually useful is as a way to force garbage collection. That's gotta be a big performance hit, but it's likely buried so deep in Mono's innards that I bet the sim doesn't even count it as script time.)

  • Thanks 1
Link to comment
Share on other sites

First, thanks everyone for your help and patience so far, I really appreciate it.

I re-tooled the script in such a way that it does precisely what I want it to do, with the major exception that I still can't get it to stop repeating the 4 sound clips in an infinite loop. Ditto the chat text (when included in the script; currently it isn't).

A couple of variations I've tried either restricts it to the normal 2-sound-file limit (which doesn't loop), or which plays the 4 sound clips, in order, with no loop, but each sound file requires its own separate click of the prim to play (they aren't strung together).

Just to clarify, this is what I want the scripted prim, which is a button that is worn by the avatar, to do:

1.) it can by selected/clicked by any nearby user, myself included.

2.) the click activates the string of sound files, of which there are 4, which play in order.

3.) this isn't crucial... but ideally, a text message plays, once, in local chat.

4.) after the 4th sound file plays, the sequence stops automatically, both sound and text, without the need to click the prim button a second time to stop it. To repeat it would require another click of the button.

Seems like this would be very simple to achieve.

Here's my simplified new version of the script, which is minus any chat text function (which, in its current looped form, spams local chat terribly):

Quote

string STATE = "off";
integer FRAGMENT_COUNT;
integer CURRENT_FRAGMENT = -1;

default
{
    state_entry()
    {
       FRAGMENT_COUNT = llGetInventoryNumber(INVENTORY_SOUND);
        
    }
    touch_start(integer total_number)
        {
         llSetTimerEvent(1);
        }
        
        timer(){
            llSetTimerEvent(8.5);
            CURRENT_FRAGMENT=CURRENT_FRAGMENT+1;
            if(CURRENT_FRAGMENT==FRAGMENT_COUNT) {
                CURRENT_FRAGMENT=0;
            }
            llPlaySound(llGetInventoryName(INVENTORY_SOUND,CURRENT_FRAGMENT),1);
        
           
            
           }
    }

 

Again, this does exactly what I want it to do, except for the automatic, endless repeating.

Link to comment
Share on other sites

15 minutes ago, Quistess Alpha said:
if(CURRENT_FRAGMENT==FRAGMENT_COUNT) {
     CURRENT_FRAGMENT=0;
}

I believe you want to change to

if(CURRENT_FRAGMENT==FRAGMENT_COUNT) {
     llSetTimerEvent(0);
}

which would stop the timer after you get to the last fragment instead of repeating.

I just gave that a try. It worked on the first click, which seemed promising, but then a Script Warning/Error/Debug box popped up, telling me it could not find sound, so it was disabled for any further clicks/activation.

Link to comment
Share on other sites

1 minute ago, GadgetKit Vectoscope said:

I just gave that a try. It worked on the first click, which seemed promising, but then a Script Warning/Error/Debug box popped up, telling me it could not find sound, so it was disabled for any further clicks/activation.

Oh, combine the two then:

if(CURRENT_FRAGMENT==FRAGMENT_COUNT) {
   llSetTimerEvent(0);
   CURRENT_FRAGMENT=0;
}

 

Link to comment
Share on other sites

14 minutes ago, Quistess Alpha said:

Oh, combine the two then:

if(CURRENT_FRAGMENT==FRAGMENT_COUNT) {
   llSetTimerEvent(0);
   CURRENT_FRAGMENT=0;
}

 

Hmmmm... this worked nicely (thanks!), but with one odd wrinkle; it plays all 4 sound files, in order, but then immediately repeats Sound File #1 a second time, before ending. Otherwise, it's perfect. No error box, no constant looping.

Link to comment
Share on other sites

35 minutes ago, GadgetKit Vectoscope said:

then immediately repeats Sound File #1

add another line with a

return;

in the same if-block.

(or better yet, add a -1 afer FRAGMENT_COUNT in the if-statement, and move the llPlaySound(... ); to the top of the timer() event.)

Edited by Quistess Alpha
Link to comment
Share on other sites

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