GadgetKit Vectoscope Posted August 31, 2021 Share Posted August 31, 2021 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 More sharing options...
Nova Convair Posted August 31, 2021 Share Posted August 31, 2021 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 More sharing options...
GadgetKit Vectoscope Posted September 2, 2021 Author Share Posted September 2, 2021 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 More sharing options...
Nova Convair Posted September 3, 2021 Share Posted September 3, 2021 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 More sharing options...
Jenna Huntsman Posted September 3, 2021 Share Posted September 3, 2021 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 More sharing options...
Nova Convair Posted September 3, 2021 Share Posted September 3, 2021 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 More sharing options...
Jenna Huntsman Posted September 3, 2021 Share Posted September 3, 2021 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 More sharing options...
Qie Niangao Posted September 3, 2021 Share Posted September 3, 2021 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.) 1 Link to comment Share on other sites More sharing options...
GadgetKit Vectoscope Posted September 3, 2021 Author Share Posted September 3, 2021 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 More sharing options...
Quistess Alpha Posted September 4, 2021 Share Posted September 4, 2021 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. Link to comment Share on other sites More sharing options...
GadgetKit Vectoscope Posted September 4, 2021 Author Share Posted September 4, 2021 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 More sharing options...
Quistess Alpha Posted September 4, 2021 Share Posted September 4, 2021 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 More sharing options...
GadgetKit Vectoscope Posted September 4, 2021 Author Share Posted September 4, 2021 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 More sharing options...
Quistess Alpha Posted September 4, 2021 Share Posted September 4, 2021 (edited) 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 September 4, 2021 by Quistess Alpha Link to comment Share on other sites More sharing options...
GadgetKit Vectoscope Posted September 4, 2021 Author Share Posted September 4, 2021 Ah, just moving the llPlaySound to the top of the timer() event, alone, fixed it! Perfect! Conversely, adding a -1 after FRAGMENT_COUNT resulted in the Script Warning/Error/Debug box. But that doesn't matter, because the script works! A great big THANK YOU, again, for all of your help! 🙂👍💯 Link to comment Share on other sites More sharing options...
Recommended Posts
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