// 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><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();
}
}
}
>1>