Menu driven Texture Changer

by Jessica Margetts

// Here is a menu based texture changing script, that has no limits on the number of pages textures it can support.

// PLEASE remember that textures MUST HAVE full permissions in order to be used with it.

integer         INVENTORY_TYPE  = INVENTORY_TEXTURE;
integer         PAGES;
integer         PAGE            = 1;
integer         COM_CHAN        = -278976;
integer         LISTENER;
integer         NEEDED_PERMS;

list            THIS_PAGE;
list            LIST_NAV_X      = ;
list            LIST_NAV_A      = ;
list            LIST_NAV_B      = ;
list            LIST_NAV_C      = ;

string          PAGE_NAV_NULL   = "    ";
string          PAGE_NAV_NEXT   = "NEXT";
string          PAGE_NAV_BACK   = "BACK";
string          PAGE_NAV_HOME   = "HOME";

integer ptTestPerms(string item, integer needed)
{
    integer perm = llGetInventoryPermMask(item, MASK_OWNER);
    if ((perm & needed) == needed) { return(TRUE); }
    return(FALSE);
}

ptDisplayPage(key theUser) {
    integer     TEXTURES    = llGetInventoryNumber(INVENTORY_TYPE);
    integer     I;
    integer     START;
    integer     STOP;
    string      INTRO       = "Page " + (string) PAGE + " of " + (string) PAGES;
    string      NEW_LINE;
    string      ITEM_NAME;
    string      T;
    list        MENU;
    
    
    if (TEXTURES >= 1) {
        PAGES       = 1 + (llFloor((float) TEXTURES / 9.0));
        INTRO       = "Page " + (string) PAGE + " of " + (string) PAGES;
        if (TEXTURES <= 9) {
            MENU = [] + LIST_NAV_X;
            for (I = 0; I < TEXTURES; ++I)
            {
                T           = (string) (I + 1);
                ITEM_NAME   = llGetInventoryName(INVENTORY_TYPE, I);
                if (ptTestPerms(ITEM_NAME, NEEDED_PERMS)) {                
                    NEW_LINE    = "\n" + T + "- " + ITEM_NAME;
                    INTRO       = "" + INTRO + NEW_LINE;
                    MENU        = [] + MENU + ;
                } else {
                    NEW_LINE    = "\n" + T + "- ~BLOCKED ~";
                    INTRO       = "" + INTRO + NEW_LINE;
                    MENU        = [] + MENU + ;
                }
            }
        } else {
            if ((PAGE == 1) || (PAGE > PAGES)) {
                PAGE = 1;
                MENU = [] + LIST_NAV_A;
            } else if ((PAGE == PAGES) || (PAGE <1)) {
                MENU = [] + LIST_NAV_C;
            } else {
                MENU = [] + LIST_NAV_B;
            }
            START       = ((PAGE - 1) * 9);
            STOP        = (PAGE * 9);
            if (STOP > TEXTURES) { STOP = TEXTURES - 1; }
            INTRO       = "Page " + (string) PAGE + " of " + (string) PAGES;
            
            for (I = START; I 

 

Texture Change Menu

//Drop this script into an object with up to 22 textures inside.

//When anyone Touches they will get a menu with all the textures available. Button names in menu will be first 10 characters from that item's name. 

//NOTE: Texture Names may not exceed 24 characters or script error and menu fails.


integer side = ALL_SIDES; //ALL_SIDES or any face number 0 through 5

list texture_list;
list texture_list2;
key user = NULL_KEY;

composelist()
{
    integer currenttexture = 0;
    integer totaltextures = llGetInventoryNumber(INVENTORY_TEXTURE);
    
    if(totaltextures > 0 & totaltextures <= 12)
    {
        texture_list = [];
        do
        {
            texture_list = texture_list + llGetInventoryName(INVENTORY_TEXTURE, currenttexture);
            currenttexture++;
        }
        while (currenttexture > 0 & currenttexture  12 & totaltextures <= 22)
    {
        texture_list = ["Next Page"];
        do
        {
            texture_list = texture_list + llGetInventoryName(INVENTORY_TEXTURE, currenttexture);
            currenttexture++;
        }
        while (currenttexture > 0 & currenttexture <11);
        
        texture_list2 = ["Last Page"];
        do
        {
            texture_list2 = texture_list2 + llGetInventoryName(INVENTORY_TEXTURE, currenttexture);
            currenttexture++;
        }
        while (currenttexture >= 11 & currenttexture  22)
    {
        llWhisper(0, "You may only have a maximimum of 22 Textures. Please remove any extra ones.");
    }
    if(totaltextures == 0)
    {
        llWhisper(0, "Please add up to 22 Textures inside this object.");
    }
}


//The Menu
integer menu_handler;
integer menu_channel;
menu(key user,string title,list texture_list)
{
    menu_channel = (integer)(llFrand(99999.0) * -1); //random channel
    menu_handler = llListen(menu_channel,"","","");
    llDialog(user,title,texture_list,menu_channel);
    llSetTimerEvent(30.0); //menu channel open for 30 seconds
}

default
{
    state_entry()
    {
        composelist(); //make list from inventory textures
    }

    touch_start(integer total_number)
    {
        user = llDetectedKey(0);
        menu(user,"nnPlease select one below.",texture_list);
    }
    
    listen(integer channel,string name,key id,string message)
    {
        if (channel == menu_channel)
        {
            llSetTimerEvent(0.0);
            llListenRemove(menu_handler);
            if(message == "Next Page")
            {
                menu(user,"nnPlease select one below.",texture_list2);
            }
            else if(message == "Last Page")
            {
                menu(user,"nnPlease select one below.",texture_list);
            }
            else
            {
                llSetTexture(message, side);
            }
        }
    }
    
    timer() //Close the Menu Listen or we'll get laggy
    {
        llSetTimerEvent(0.0); 
        llListenRemove(menu_handler);
    }
    
    changed(integer change) 
    {
        if (change & CHANGED_INVENTORY) //inventory has changed
        {
            llSleep(0.5);
            composelist(); //rebuild the list
        }
    }
}

 

Single Prim Texture Changer

// Texture changer.  Will cycle through all textures
// in the prims inventory.
//
// Kimm Paulino
// Written for Bebelou Naidoo, April 2010
 
float TIMER_PERIOD = 5.0; // in seconds.
integer RANDOM = 1;     // 0 = sequential, 1 = random
 
// globals
integer gNumTextures;
integer gLastTexture;
 
default
{
    on_rez (integer n)
    {
        llResetScript();
    }
 
    state_entry()
    {
        gLastTexture = 0;
        gNumTextures = llGetInventoryNumber(INVENTORY_TEXTURE);
        llSetTimerEvent(TIMER_PERIOD);
    }
 
    timer()
    {
        integer nextTexture;
        if (RANDOM)
        {
            // Randomly choose one
            nextTexture = (integer)llFrand (gNumTextures);
        }
        else
        {
            // Move on from the last one
            gLastTexture ++;
            if (gLastTexture > gNumTextures)
            {
                gLastTexture = 0;
            }
            nextTexture = gLastTexture;
        }
        string texture = llGetInventoryName(INVENTORY_TEXTURE, nextTexture);
        if (texture != "")
        {
            llSetTexture(texture, ALL_SIDES);
        }
    }
 
    changed (integer change)
    {
        if (change & CHANGED_INVENTORY)
        {
            llResetScript();
        }
    }
}

 

Dialog Texture Changer

// Script to present a dialog populated with a list of textures
// either from the prims inventory or specified by UUID in a notecard.
//
// Notecard lines have the form:
//    Texture Name=UUID
//
// Note that only the first 24 characters of the texture names
// are actually used - as only 24 chars can be placed in a dialog
// button.  This means that if two textures have the first 24 chars
// the same, the second will be ignored ...
//
// Note however that usually, buttons don't display more than, say,
// around 10 or so characters anyway!!
//
// There are two methods of setting textures - one (gSetTexture = TRUE)
// allows you to use UUIDs, etc, but the other (gSetTexture = FALSE)
// will allow you to specify the rotation and offset values.
//
// There is also an option to just use the values from the texture already
// on the face (but this won't work for ALL_SIDES).
//
// Both allow you to set the face.
//
// Kimm Paulino
// Feb 2012
 
// Controls how the script operates:
integer gReshow = FALSE;
integer gSetTexture = FALSE;               // Use SetTexture method (needed for textures not in the prim inventory)
integer gNotecards = TRUE;               // Get textures to use from a notecard not inventory
integer gPreserveTextures = FALSE;      // Read offset/rotation values from existing texture
 
// configures how textures appear
integer gFace = 1;
vector  gRepeats = <1 .0, 1.0, 1.0>;
vector  gOffsets = <1 .0, 1.0, 1.0>;
float     gRotationInDegrees = 0.0;
 
// Do not change anything below this line (unless you know what you are doing)
integer gDebug = FALSE;
integer gMenuPage;
integer gNumTextures;
list gTextures;
list gTextureUUIDs;
 
string gNotecardName;
integer gNotecardLine = 0;
key gQueryID;
 
integer gListenChannel;
integer gListenHandle;
float     gListenTimer;
float     LISTEN_TIMEOUT=300.0;
 
string MENU_NEXT="Next>";
string MENU_TOP="Top";
string MENU_BACK="= num_pages)
    {
        // gMenuPage is an index starting at 0...
        // max is a 1...
        gMenuPage = num_pages-1;
    }
 
    // Max buttons on a dialog is 12, so if more than that, then need to 
    // include special next/back button handling
    integer first_texture = 0;
    integer last_texture = gNumTextures-1;
    if (gNumTextures > 12)
    {
        // Note: This yields notecards counting as follows:
        // 0 to 8 = first page,
        // 9 to 17 = next page, etc
        first_texture = gMenuPage * 9;
        last_texture = first_texture + 9 - 1;
        if (last_texture >= gNumTextures)
        {
            // recall last_texture indexed from 0, but
            // gNumTextures is indexed from 1
            last_texture = gNumTextures-1;
        }
 
        if (gMenuPage > 0)
        {
            buttons += [MENU_BACK];
        }
        else
        {
            buttons += [MENU_SPACE];
        }
 
        if (gMenuPage == 0)
        {
            buttons += [MENU_SPACE];
        }    
        else
        {
            buttons += [MENU_TOP];
        }
 
        // If not on the last page, and there are more pages to come ...
        if (gNumTextures > 9 && gMenuPage <(num_pages-1))
        {
            buttons += [MENU_NEXT];
        }
        else
        {
            buttons += [MENU_SPACE];
        }
    }
 
    integer i;
    for (i=first_texture; (i <= last_texture) && (i < gNumTextures); i++)
    {
        buttons += [llList2String (gTextures, i)];
    }
 
    do_dialog (id, "\n\n(click \"Ignore\" when done)", buttons);
}
 
do_dialog (key id, string msg, list buttons)
{
    llListenRemove (gListenHandle);
    gListenChannel = getRandomChannel();
    gListenHandle = llListen (gListenChannel, "", id, "");
    llSetTimerEvent (LISTEN_TIMEOUT);
    llDialog (id, msg, buttons, gListenChannel);
}
 
default
{
    on_rez (integer start_param)
    {
        llResetScript();
    }
 
    state_entry()
    {
        if (read_textures_from_inventory())
        {
            // We have textures in the inventory and have read them
            gNotecards = FALSE;
        }
        else if (read_textures_from_notecards())
        {
            // We have textures read in from a notecard by UUID
            // (or will have pretty soon)
            gNotecards = TRUE;
        }
        else
        {
            llOwnerSay ("Note: There are no textures or notecards in this prim ...");
        }
        gMenuPage = 0;
    }
 
    touch_start(integer total_number)
    {
        // Start menu system again. Note that I don't do anything special
        // with several people trying to touch it at the same time - it will
        // always overlap the processing of gMenuPage, but all that will
        // happen is that peoples next/back might be a bit quirky for a while.
        // Eventually, they will sort themselves out!
        gMenuPage = 0;
        show_dialog (llDetectedKey(0));
    }
 
    listen (integer channel, string name, key id, string msg)
    {
        if (channel == gListenChannel)
        {
            if (msg == MENU_BACK)
            {
                gMenuPage--;
                show_dialog (id);
            }
            else if (msg == MENU_TOP)
            {
                gMenuPage = 0;
                show_dialog (id);
            }
            else if (msg == MENU_NEXT)
            {
                gMenuPage++;
                show_dialog (id);
            }            
            else
            {
                // should be something in the inventory to give out
                apply_texture (msg);
 
                // reshow the dialog
                if (gReshow)
                {
                    show_dialog(id);
                }
            }
        }
    }
 
    timer ()
    {
        // First see if we are timing out on a listen event
        if (gListenHandle != 0)
        {
            // Remove the old listen
            llListenRemove (gListenHandle);
            gListenHandle = 0;
            gListenChannel = 0;
        }
    }
 
    dataserver(key query_id, string line)
    {
        if (query_id == gQueryID)
        {
            if (line != EOF)
            {
                if (llSubStringIndex (line, "=") != 0)
                {
                    list vals = llParseString2List (line, ["="], []);
 
                    // Only store the first 24 characters of the name as this is all we can
                    // show in a dialog anyway
                    string texture = llList2String (vals, 0);
                    string uuid = llList2Key (vals, 1);
                    gTextures += [llGetSubString (texture, 0, 23)];
                    gTextureUUIDs += uuid;
                    doDebug ("Adding: " + texture + " ("+uuid+")");
                }
 
                // Now get the next line
                gNotecardLine++;
                gQueryID = llGetNotecardLine(gNotecardName, gNotecardLine);
            }
            else
            {
                gNumTextures = llGetListLength (gTextures);
                doDebug ("Found " + (string)gNumTextures + " textures.");
            }
        }
    }
 
    changed (integer change)
    {
        if (change & CHANGED_INVENTORY)
        {
            llResetScript();
        }
    }
}

 

Menu Driven Texture Selector

Foun in the Second Life Scripting Library Forum:

integer HANDLE;
integer CHANNEL = -44567;
float INTENSITY = 10.0;
float RADIUS = 6.0;
float FALLOFF = .25;
integer FACE = 5;

list COLOR_LIST = ["white", "red", "green",
                   "blue", "yellow", "orange",
                   "purple", "pink", "cyan", "off", "random"];
list COLOR_VALUE = [<1 , 1, 1>, <1 , .0, .0>, <0, 1, 0>,
                    <0, 0, 1>, <1 , 1, 0>, <1 , .05, .0>,
                    <1 , 0, 1>, <1 , .02, .02>, <0, 1, 1>]; 

pColor(vector color)
{
   llSetPrimitiveParams([PRIM_POINT_LIGHT, TRUE, color, INTENSITY, RADIUS, FALLOFF,
                         PRIM_COLOR, FACE, color, llGetAlpha(FACE),
                         PRIM_GLOW, FACE, 1.0]);
}

default
{
    touch_start(integer total_number)
    {
        HANDLE = llListen(CHANNEL, "", NULL_KEY, "");
        llDialog(llDetectedKey(0), "Color?", COLOR_LIST, CHANNEL);
    }

    listen(integer channel, string name, key id, string message)
    {
       llListenRemove(HANDLE);

       if(message == "off")
       {
           llSetTimerEvent(0.0);
           llSetPrimitiveParams([PRIM_POINT_LIGHT, FALSE, <0, 0, 0>, 0, 0, 0,
                                 PRIM_COLOR, FACE, <.95, .95, .95>, llGetAlpha(FACE),
                                 PRIM_GLOW, FACE, 0.0]);
           llWhisper(0,"Lights out");
       }
       else if(message == "random") llSetTimerEvent(1.0);
       else
       {
           llSetTimerEvent(0.0);
           integer i = llListFindList(COLOR_LIST, [message]);
           vector color = llList2Vector(COLOR_VALUE, i);
           pColor(color);
       }
    }

    timer()
    {
        vector color = llList2Vector(COLOR_VALUE, (integer)(llFrand(llGetListLength(COLOR_VALUE))));
        pColor(color);
    }
}