Delay/Non-responsive with Random Number/Textures
|
|
Aedroogo Hosoi
Registered User
Join date: 22 Aug 2006
Posts: 12
|
09-21-2006 08:08
Hello all, I'm working on a script for an object that, when touched, will generate a random integer and assign a texture acourding to the result. I've got it working, with one problem. Every few touches (maybe 1 out of every 3 or 4) results in nothing. If I wait a few seconds, it'll work again. They're fairly small textures - it doesn't seem like it's mere slowness in loading them. I've set it up to also say the number generated, and I don't get that either. Is there a way to get rid of that momentary response hangup, or am I seeing a symptom of somthing else going on? Here's the script: float rand() { float r; r = llFrand(16); r = (float)llCeil(r); if(r < 1)r = 1; return r; }
default { touch_start(integer total_number) { if ( llDetectedKey(0) != llGetOwner() ) return;
if(rand() == 1) { llSetTexture("bdra", 2); llSay(0, "1"); } else if(rand() == 2) { llSetTexture("bgua", 2); llSay(0, "2"); } else if(rand() == 3) { llSetTexture("bkng", 2); llSay(0, "3"); } else if(rand() == 4) { llSetTexture("bwiz", 2); llSay(0, "4"); } else if(rand() == 5) { llSetTexture("gdra", 2); llSay(0, "5"); } else if(rand() == 6) { llSetTexture("ggua", 2); llSay(0, "6"); } else if(rand() == 7) { llSetTexture("gkng", 2); llSay(0, "7"); } else if(rand() == 8) { llSetTexture("gwiz", 2); llSay(0, "8"); } else if(rand() == 9) { llSetTexture("rdra", 2); llSay(0, "9"); } else if(rand() == 10) { llSetTexture("rgua", 2); llSay(0, "10"); } else if(rand() == 11) { llSetTexture("rkng", 2); llSay(0, "11"); } else if(rand() == 12) { llSetTexture("rwiz", 2); llSay(0, "12"); } else if(rand() == 13) { llSetTexture("ydra", 2); llSay(0, "13"); } else if(rand() == 14) { llSetTexture("ygua", 2); llSay(0, "14"); } else if(rand() == 15) { llSetTexture("ykng", 2); llSay(0, "15"); } else if(rand() == 16) { llSetTexture("ywiz", 2); llSay(0, "16"); } rand(); //discarding the return value is also legal } }
Thanks in advance for any help!
|
|
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
|
09-21-2006 08:36
I think there are at least two things here.
Setting the textures will always have a delay, there's a 0.2s sleep associated with it, plus (probably) longer as the texture is rezzed.
Your code is also not quite right. You want something like integer test=(integer)rand(); if(test==1) etc.
You're calling the random function each time in each test. That means there's a (15/16)^16 chance (0.356 or so) that NONE of them will work, which is about what you're eyeballing.
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
09-21-2006 09:20
I'd also be inclined to put the textures in a list and then use llList2String
list lTextures = ["bdra","bgua","bkng","bwiz", "gdra","ggua","gkng","gwiz", "rdra","rgua","rkng","rwiz", "ydra","ygua","ykng","ywiz"];
default { touch_start(integer total_number) { if ( llDetectedKey(0) != llGetOwner() ) return;
integer selection = (integer)llFrand(16); string text = llList2String(lTextures,selection); llSetTexture(text, 2); llOwnerSay((string)selection); } }
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
09-21-2006 10:39
There's also the chance that rand() returned the same value as it did the last time, so you end up setting the same texture that's currently on, which makes it look like nothing happened.
|
|
Aedroogo Hosoi
Registered User
Join date: 22 Aug 2006
Posts: 12
|
09-21-2006 20:27
Thanks guys, that did the trick. Newgate, thanks for the list idea too. At the very least it makes things look cleaner. I'm going to go check the Wiki to find out, but Am I right in saying that it's reading the list in sequence, ie "bdra" is 0, "ywiz" is 15, etc? Is that how all lists work or is that something that llList2String is doing?
Thanks again. It's nice and quick now!
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
09-22-2006 00:46
From: Aedroogo Hosoi Thanks guys, that did the trick. Newgate, thanks for the list idea too. At the very least it makes things look cleaner. I'm going to go check the Wiki to find out, but Am I right in saying that it's reading the list in sequence, ie "bdra" is 0, "ywiz" is 15, etc? Is that how all lists work or is that something that llList2String is doing?
Thanks again. It's nice and quick now! Basically yes. Someone will no doubt correct me if I'm wrong, but my understanding of it is that a list is LSL's general purpose collection class. It can store any data type and because of this we use accessor functions (llList2String, llList2Vector etc.) to extract the data. At least thast how I've always used them. Revisiting the earlier code I'd actaully change it slightly, I was being lazy when I knocked it up. You dont need a hardcoded constant as you can find out how many textures you have dynamically from the list itself. I've also added a guard to ensure you dont select the same texture twice. list lTextures = ["bdra","bgua","bkng","bwiz", "gdra","ggua","gkng","gwiz", "rdra","rgua","rkng","rwiz", "ydra","ygua","ykng","ywiz"];
integer randval;
default { touch_start(integer total_number) { if ( llDetectedKey(0) != llGetOwner() ) return;
integer num = llGetListLegth(lTextures);
integer selection = randval;
while(randval == selection) selection = (integer)llFrand( num ); randval = selection;
string text = llList2String(lTextures,randval); llSetTexture(text, 2); llOwnerSay((string)randval); } }
|
|
Aedroogo Hosoi
Registered User
Join date: 22 Aug 2006
Posts: 12
|
09-22-2006 07:35
Hmm, even smoother. Now I can just plunk int texture names as I need them. Cool
I'm going to go test it myself when I get home from work, but do you think with using GetListLength for my llFrand range, that my return range will still start at 0 or will start at 1 now?
|
|
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
|
09-22-2006 10:00
Newgate's latest script will give you numbers in the range 0 -> length of list -1 as required.
|
|
Don Misfit
Registered User
Join date: 1 Jun 2006
Posts: 60
|
09-22-2006 15:05
Aedroogo... Do you really want to show a random texture on each click? By doing that, it's possible that some textures will rarely (or even never) be displayed. Another approach would be to shuffle the list, then display each texture in order. When you've shown them all, you can re-shuffle the list. list lTextures = ["bdra","bgua","bkng","bwiz", "gdra","ggua","gkng","gwiz", "rdra","rgua","rkng","rwiz", "ydra","ygua","ykng","ywiz"]; integer iCurrent ; integer iTotal ; default { state_entry() { lTextures = llListRandomize(lTextures, 1) ; iTotal = llGetListLength(lTextures) ; iCurrent = 0 ; } touch_start(integer total_number) { string sCurrent = llList2String ( lTextures, iCurrent ) ) ; llSetTexture ( sCurrent, 2 ) ; iCurrent++ ; if ( iCurrent > iTotal - 1 ) { // all textures shown once, so re-shuffle lTextures = llListRandomize(lTextures, 1) ; // if first item in re-shuffled list is the same as the last texture shown // strip it and then add it to the end if ( llList2String ( lTextures, 0 ) == sCurrent ) { lTextures = llDeleteSubList ( lTextures, 0, 0 ) ; lTextures += [sCurrent] ; } iCurrent = 0 ; } } }
|