Jump to content

Need help - trying to make an object's menu useable by any avatar


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

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

Recommended Posts

Hello lsl geniuses! I have a bit of a quandary. I made a pretty ring with texture change menu by adapting a script posted in an ancient (2009?) thread at sluniverse. It works wonderfully for the owner of the object. Now that I've tested the item, I'd like to make a demo for my shop so potential buyers can test the texture change, but I can't work out how to configure the script to allow anyone to use the menu.

This is what I've tried - it will open the main menu, but when one of the options is clicked, the menu just closes. Please can someone help? For reference - I know just enough html and php to be dangerous - I'm less comfortable with lsl as I've not used it much.

//Adapted from a script by Rhonda Huntress

list lMetals = ["silver.g", "gold.g"];
list lDiamond = ["amethyst.d", "canary.d", "chocolate.d", "diamond.d", "emerald.d", "garnet.d", "ruby.d", "sapphire.d"];
list lAccents = ["amethyst.a", "canary.a", "chocolate.a", "diamond.a", "emerald.a", "garnet.a", "ruby.a", "sapphire.a"];
integer iNumMetals = 0;   
integer iNumDiamond = 0;
integer iNumAccents = 0;
integer iChannel = 473;
integer iHandle = 0;
integer iNumPrims;
integer idx;
key User;
    
default{

    state_entry() {
    }
    touch_start(integer total_number){
        User = llDetectedKey(0);
        //load texture list
        integer idx = 0;
        integer iNumTexs = llGetInventoryNumber(INVENTORY_TEXTURE);
        string sTexName;
        integer bIsMetal = FALSE;
        integer bIsDiamond = FALSE;
        integer bIsAccents = FALSE;

        lMetals = [];
        lDiamond = [];
        lAccents = [];
        iNumMetals = 0;   
        iNumDiamond = 0;
        iNumAccents = 0;

        for (idx=0; idx< iNumTexs; ++idx){
            sTexName = llGetInventoryName(INVENTORY_TEXTURE,idx);
            bIsMetal = FALSE;  bIsDiamond = FALSE; bIsAccents = FALSE;
            if (llSubStringIndex(sTexName, ".m")> 0) bIsMetal = TRUE;
            else if (llSubStringIndex(sTexName,".d") > 0) bIsDiamond = TRUE;
            else if (llSubStringIndex(sTexName,".a") > 0) bIsAccents = TRUE;

            if (bIsMetal){
                lMetals += sTexName;
                iNumMetals += 1;
            }

            if (bIsDiamond){
                lDiamond += sTexName;
                iNumDiamond += 1;
            }
            
             if (bIsAccents){
                lAccents += sTexName;
                iNumAccents += 1;
            }
        }

        //build menu
        list lMainMenu = ["Metal", "Diamond", "Accents"];
        llDialog (User, "\nPlease choose the component you wish to change", lMainMenu, iChannel);
        iHandle = llListen(iChannel, User, "", "");
        llSetTimerEvent(0.0);  //clear any timers;
        llSetTimerEvent(60.0);
        
    }
    listen(integer channel, string name, key id, string message){
        llListenRemove(iHandle);
        if (message == "Metal") state metal_menu;
        if (message == "Diamond") state diamond_menu;
        if (message == "Accents") state accents_menu;
    }

    timer(){
        llListenRemove(iHandle);
        llSetTimerEvent(0.0);  //clear any timers;
    }
}

state metal_menu{

    state_entry(){
        iHandle =  llListen(iChannel, "", User, "");
        llDialog(User, " ", lMetals, iChannel);
        llSetTimerEvent(0.0);  //clear any timers;
        llSetTimerEvent(60.0);
    }

    listen(integer channel, string name, key id, string message){
        llSetTimerEvent(0.0);
        llListenRemove(iHandle);
        iNumPrims = llGetNumberOfPrims();
        for (idx=2; idx <= iNumPrims; ++idx){
            if (llGetLinkName(idx) == "metal"){
                llSetLinkTexture(idx, message, ALL_SIDES);
            }
        }
        state default;
    }

    timer(){
        llListenRemove(iHandle);
        llSetTimerEvent(0.0);  //clear any timers;
        state default;        
    }
}

state diamond_menu{
    
    state_entry(){
        iHandle = llListen(iChannel, "", User, "");
        llDialog(User, " ", lDiamond, iChannel);
        llSetTimerEvent(0.0);  //clear any timers;
        llSetTimerEvent(60.0);
    }

    listen(integer channel, string name, key id, string message){
        llSetTimerEvent(0.0);
        llListenRemove(iHandle);
        iNumPrims = llGetNumberOfPrims();
        for (idx=2; idx <= iNumPrims; ++idx){
            if (llGetLinkName(idx) == "diamond"){
                llSetLinkTexture(idx, message, ALL_SIDES);
            }
        }

        state default;
    }

    timer(){
        llListenRemove(iHandle);
        llSetTimerEvent(0.0);  //clear any timers;
        state default;        
    }
}
      
state accents_menu{
    
    state_entry(){
        iHandle = llListen(iChannel, "", User, "");
        llDialog(User, " ", lAccents, iChannel);
        llSetTimerEvent(0.0);  //clear any timers;
        llSetTimerEvent(60.0);
    }

    listen(integer channel, string name, key id, string message){
        llSetTimerEvent(0.0);
        llListenRemove(iHandle);
        iNumPrims = llGetNumberOfPrims();
        for (idx=2; idx <= iNumPrims; ++idx){
            if (llGetLinkName(idx) == "accent"){
                llSetLinkTexture(idx, message, ALL_SIDES);
            }
        }

        state default;
    }

    timer(){
        llListenRemove(iHandle);
        llSetTimerEvent(0.0);  //clear any timers;
        state default;        
    }
}

Thanks!

Link to comment
Share on other sites

I can't see why the script is restricted to owner only.  There's nothing in this code that would do that.  And the only thing I can see that might make the script close after tne first menu would be running it with no textures in the object's inventory.  The code block in the touch_start event of state default that says

        lMetals = [];        lDiamond = [];        lAccents = [];        iNumMetals = 0;           iNumDiamond = 0;        iNumAccents = 0;

clears the default list at the top of the script, so unless you have textures in your object's inventory to rebuild those lists, there won't be anything to build the lMetals, lDiamond, and lAccents dialogs with.

Link to comment
Share on other sites

Thanks for the reply!

I do have all textures in the object and have double checked that permissions are set to "copy" and "transfer" on each. The scipt I posted is where I attempted to change all references to llGetOwner to User to make it open for any avatar. While that lets the initial menu open, clicking on the options closes the menu.

I added "key User" at the top, and added the "User = llDetectKey" coding under the start command hoping that would make it work, so far - no luck.

Link to comment
Share on other sites

Check the order of arguments in the first call to llListen() -- the one in default state -- you have the User key in the place where a name string would be, and the LSL compiler won't fuss about that sort of type mismatch.

(It's not a big deal, but also I'd recommend calling the llListen() before the corresponding llDialog(). It will never lag enough to matter, but it's sorta more consistent.)

Link to comment
Share on other sites


Qie Niangao wrote:

...

(It's not a big deal, but also I'd recommend calling the llListen() before the corresponding llDialog(). It will never lag enough to matter, but it's sorta more consistent.)

It is mandantory to call the llListen before llDialog.

You may get away doing it the other way but I had one repeatable case where it didn't work in the wrong order. So just don't try it and don't waste time hunting bugs for this construct.

Edit:

just thinking about that - makes no sense so just ignore me :D

Can't find the script but must have been something specific there, never invested time to investigate.

Link to comment
Share on other sites

Thanks Qie! I've fixed the llListen entry so it's before the llDialog. Please could you expand on the name string? Should I be using a name string as an indicator of "user" instead of the detectkey?

I can only assume I'm trying to set the user to be any avatar incorrectly, and that's causing the menu to close on selection of "Metal", "Diamond", or "Accent".  M'husband is a software developer, but unfamiliar with lsl, and we were trying to set the user in the opening, but couldn't get it to work as it would if we were writing a php script! It's like lsl is similar to php at a glance, but seems to have its own quirks and nuances that I've yet to get a handle on!

Link to comment
Share on other sites

It's nothing clever or deep. Just that in the default state, you have:

        iHandle = llListen(iChannel, User, "", "");

but elsewhere else you (correctly) have :

        iHandle = llListen(iChannel, "", User, "");

You're correct to be using the llDetectedKey() here, not llDetectedName(), it's just that the first llListen() call needs to be like the others and put User in the argument for the key, not in the one for the name.

  • Like 1
Link to comment
Share on other sites

Qie, you ROCK!!! That fixed it!  Just had one of those, "Oh, well DUH!" moments :D  M'husband and I have just been through and cleaned up a lot of redundancies and unneccesary bits to streamline it as well - and it's working a charm!

My thanks to Qie and everyone who replied!

Link to comment
Share on other sites

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