Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

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:

CODE

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.
_____________________
Eloise's MiniMall
Visit Eloise's Minimall
New, smaller footprint, same great materials.

Check out the new blog
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

CODE


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.

CODE

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.
_____________________
Eloise's MiniMall
Visit Eloise's Minimall
New, smaller footprint, same great materials.

Check out the new blog
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.

CODE
 
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 ;
}
}
}